【问题标题】:Problem authenticating SOAP usernameToken with Apache CXF使用 Apache CXF 对 SOAP usernameToken 进行身份验证时出现问题
【发布时间】:2019-02-21 07:52:12
【问题描述】:

我正在尝试在Apache CXF 3.0.4 下开发一个 SOAP Web 服务,但我无法使用 WS-SecurityPolicy 对包含在每个 SOAP 消息头中的UsernameToken 进行身份验证。 根据documentation,如果cxf-rt-ws-policycxf-rt-ws-security 模块在classpath 上可用,则会自动启用WS-SecurityPolicy。经过适当的处理后,它会做必要的工作来处理安全性 配置。 我通过端点属性注释进行配置,在 方式如下:

@WebService(targetNamespace = "http://tempuri.org/", name = "MyService")

@EndpointProperties(value = {
        @EndpointProperty(key = "ws-security.callback-handler", value = "org.tempuri.ServerPasswordCallback")
        //@EndpointProperty(key = "ws-security.validate.token", value = "false")
    }
)


public interface MyService {
...
}

ServerPasswordCallback 是:

public class ServerPasswordCallback implements CallbackHandler {

    public ServerPasswordCallback() {
        System.out.println("Instantiating ServerPasswordCallback");
    }

    public void handle(Callback[] callbacks) throws IOException,
            UnsupportedCallbackException {

        System.out.println("Validating on ServerPasswordCallback");

        WSPasswordCallback pc = (WSPasswordCallback) callbacks[0];

        if (pc.getIdentifier().equals("joe")) {
            // set the password on the callback. This will be compared to the
            // password which was sent from the client.
            pc.setPassword("password");
        }
    }

}

问题是我得到以下异常:

Caused by: org.apache.wss4j.common.ext.WSSecurityException: The security token could not be authenticated or authorized
        at org.apache.wss4j.dom.validate.UsernameTokenValidator.verifyDigestPassword(UsernameTokenValidator.java:176)
        at org.apache.wss4j.dom.validate.UsernameTokenValidator.verifyPlaintextPassword(UsernameTokenValidator.java:136)
        at org.apache.wss4j.dom.validate.UsernameTokenValidator.validate(UsernameTokenValidator.java:94)

发送的消息头是:

<?xml version="1.0"?>
<soapenv:Header>
  <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
    <wsse:UsernameToken wsu:Id="UsernameToken-3B91E43693FA4F34C61536922750459149">
      <wsse:Username>joe</wsse:Username>
      <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">password</wsse:Password>
      <wsse:Nonce EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">ey+3J+OKoHlhfqREn7Q8jw==</wsse:Nonce>
      <wsu:Created>2018-09-14T10:59:10.459Z</wsu:Created>
    </wsse:UsernameToken>
    <wsu:Timestamp wsu:Id="TS-3B91E43693FA4F34C61536922750459148">
      <wsu:Created>2018-09-14T10:59:10.459Z</wsu:Created>
      <wsu:Expires>2018-09-14T10:59:15.459Z</wsu:Expires>
    </wsu:Timestamp>
  </wsse:Security>
</soapenv:Header>

奇怪的是,ServerPasswordCallback 似乎从未实例化,handle() 从未被调用。 如果在端点属性注释中我将ws-security.validate.token 设置为false,则会抛出前一个异常,即使这个 属性应该阻止令牌验证。 这一事实让我认为注释不起作用,但我不知道为什么。 这是验证UsernameToken 的正确方法吗? 端点属性注释是否正确?

注意我无法像documentation 中建议的那样设置端点属性,因为我无法访问端点实例。 一个示例项目可用here

【问题讨论】:

    标签: java soap cxf ws-security


    【解决方案1】:

    终于找到了解决办法:

    @WebService(targetNamespace = "http://tempuri.org/", name = "MyService")
    
    @EndpointProperties(value = {
            @EndpointProperty(key = "webservice.security.authMethod", value = "WS-SECURITY")
            @EndpointProperty(key = "ws-security.callback-handler", value = "org.tempuri.ServerPasswordCallback")
        }
    )
    
    
    public interface MyService {
    ...
    }
    

    为了使注解生效,必须在 EndpointProperties 中包含以下注解:

    @EndpointProperty(key = "webservice.security.authMethod", value = "WS-SECURITY")
    

    【讨论】:

      猜你喜欢
      • 2013-07-01
      • 1970-01-01
      • 1970-01-01
      • 2019-06-01
      • 1970-01-01
      • 2013-08-23
      • 2021-06-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多