簡體   English   中英

使用Apache CXF驗證SOAP usernameToken時出現問題

[英]Problem authenticating SOAP usernameToken with Apache CXF

我正在嘗試在Apache CXF 3.0.4下開發SOAP Web服務,但是使用WS-SecurityPolicy對每個SOAP消息頭中包含的UsernameToken身份驗證時遇到了麻煩。 根據文檔 ,如果在classpath上提供了cxf-rt-ws-policycxf-rt-ws-security模塊,則會自動啟用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()從未被調用。 如果在Endpoint屬性注釋中將ws-security.validate.token設置為false ,則即使該屬性阻止令牌驗證,也會拋出前一個Exception。 這個事實使我認為注釋不起作用,但是我不知道為什么。 這是驗證UsernameToken的正確方法嗎? 端點屬性注釋正確嗎?

注意:由於無法訪問Endpoint實例,因此無法設置文檔中建議的Endpoint屬性。 這里有一個示例項目

最后,我想出了一個解決方案:

@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")

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM