0

我正在尝试使用 WSS4J 将密码摘要 WS-Security 位添加到来自我的客户端的 Web 服务调用。我使用 Axis 的 WSDL4J 从 WSDL 生成客户端类,并按照说明使用 WSS4J 将 WS-Security 的“Password Digest”标头添加到 SOAP 消息,但返回错误消息“处理标头时发现错误”。添加调试消息,看起来我的 CallbackHandler 并没有受到打击。我做错了什么吗?或者我是否遗漏了一些在 WSS4J 文档中无法解释的设置?

class CSProvider {
    public CS get(CSService csService, URL url, String username)
            throws ServiceException {
        CS csPort = csService.getCSPort(url);

        ((Stub) csPort)._setProperty(WSHandlerConstants.ACTION, WSHandlerConstants.USERNAME_TOKEN);
        ((Stub) csPort)._setProperty(WSHandlerConstants.USER, username);
        ((Stub) csPort)._setProperty(UsernameToken.PASSWORD_TYPE, WSConstants.PW_DIGEST);
        ((Stub) csPort)._setProperty(WSHandlerConstants.PW_CALLBACK_CLASS, "com.example.namespace.to.PasswordCallbackHandler");

        return csPort;   
    }
}

public class PasswordCallbackHandler implements CallbackHandler {

    @Override
    public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
        for (Callback callback : callbacks) {
            if (callback instanceof WSPasswordCallback) {
                ((WSPasswordCallback) callback).setPassword(PasswordStore.getPassword());
            } else {
                throw new UnsupportedCallbackException(callback);
            }
        }
    }
}
4

1 回答 1

1

经过一番摸索,我发现了问题所在。正如我所料,Web 服务请求在没有通过的情况下PasswordCallbackHandler发出,因此它们从远程服务器返回给定的错误消息,该服务器需要有效的身份验证凭据。我花了一段时间才确定我需要csService像这样构建服务定位器(在本例中为 ):

CSService csService = new CSServiceLocator(new FileProvider("client_deploy.wsdd"));

使用 client_deploy.wsdd 文件,如下所示:

<deployment xmlns="http://xml.apache.org/axis/wsdd/" xmlns:java="http://xml.apache.org/axis/wsdd/providers/java">
    <transport name="http" pivot="java:org.apache.axis.transport.http.HTTPSender"/>
    <globalConfiguration>
        <requestFlow>
            <handler name="csHandler" type="java:org.apache.ws.axis.security.WSDoAllSender"/>
        </requestFlow>
    </globalConfiguration>
</deployment>

然后设置属性从CSProvider.get()工作得很好。

我避免使用 wsdd 文件,因为我看到的所有其他示例都使用它来设置用户名和密码类——这两件事我要到运行时才知道。明智的说法:当文档说您可以使用_setProperty()方法而不是wsdd 文件时,这仅意味着出于设置这些属性的目的,而不是完全替换文件。

于 2012-04-19T20:31:44.947 回答