簡體   English   中英

Apache CXF和WS-Security - 密碼回調

[英]Apache CXF and WS-Security - Password Callback

我已經完成了幾個教程的混搭,也沒有太成功!

我試圖讓Apache CXF和WS-Security回調我的Spring Security身份驗證器。 一切都接近工作但是在某個時刻,我在獲取密碼以使Spring安全性退出WS-call時遇到問題。

下面的處理程序變得很難,但pc.getPassword()為空。 我希望這是在Soap中發送的密碼,所以我可以把它傳遞給spring

public class ServerPasswordCallback implements CallbackHandler {

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

    WSPasswordCallback pc = (WSPasswordCallback) callbacks[0];

    pc.setPassword( pc.getPassword() );
}

我的攔截器設置如此

 <bean id="wsAuthenticationInterceptor" class="com.olympus.viewtheworld.server.security.auth.WSAuthenticationInInterceptor">
    <constructor-arg index="0">
        <map key-type="java.lang.String" value-type="java.lang.Object">
            <entry key="action" value="UsernameToken" />
            <entry key="passwordType" value="PasswordText" />
            <entry key="passwordCallbackClass" value="com.olympus.viewtheworld.server.security.auth.ServerPasswordCallback" />
        </map>
    </constructor-arg>
    <property name="authenticationManager" ref="authenticationManager"/>
</bean>

 <jaxws:endpoint id="secureHelloService"
                 implementor="#secureHelloServiceImpl"
                 implementorClass="com.olympus.viewtheworld.server.service.Impl.SecureHelloServiceImpl"
                 address="/SoapService/secure/hello">
    <jaxws:serviceFactory>
        <ref bean="jaxws-and-aegis-service-factory" />
    </jaxws:serviceFactory>
    <jaxws:inInterceptors>
        <bean class="org.apache.cxf.binding.soap.saaj.SAAJInInterceptor"/>
        <ref bean="wsAuthenticationInterceptor" />
    </jaxws:inInterceptors>
</jaxws:endpoint>

我從SoapUI發出的soap請求是

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:test="http://test/">
   <soapenv:Header>
<wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<wsse:UsernameToken>
<wsse:Username>rob2</wsse:Username>
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">passwordxx</wsse:Password>
</wsse:UsernameToken>
</wsse:Security>
</soapenv:Header>
   <soapenv:Body>
      <test:hello>
         <!--Optional:-->
         <hello>asdf</hello>
      </test:hello>
   </soapenv:Body>
</soapenv:Envelope>

版本明智的是Spring 3.1和CXF 2.7.0

在ServerPasswordCallback類中查看“passwordxx”需要做什么? 是Soap請求,配置還是錯誤?!

干杯,羅布

org.apache.ws.security.handler.WSHandlerConstants.PW_CALLBACK_CLASS上的文檔中可以看出,該方法應該使用存儲的密碼調用pc.setPassword來比較用戶提供的密碼作為參數,而不是用戶提供的密碼本身:

此標記引用用於獲取密碼的CallbackHandler實現類。 此標記的值必須是javax.security.auth.callback.CallbackHandler實例的類名。 回調函數

javax.security.auth.callback.CallbackHandler.handle(javax.security.auth.callback.Callback[])

獲取org.apache.ws.security.WSPasswordCallback對象的數組。 僅使用數組的第一個條目。 該對象包含用戶名/密鑰名稱作為標識符。 回調處理程序必須在返回之前設置與此標識符關聯的密碼或密鑰。 應用程序可以使用以下方法設置此參數:

call.setProperty(WSHandlerConstants.PW_CALLBACK_CLASS, "PWCallbackClass");


我正在使用org.apache.ws.security.validate.Validator來檢查提供的密碼的有效性,並在那里設置Spring安全上下文:

@Bean(name = "wssforjInInterceptor")
public WSS4JInInterceptor wssforjInInterceptor() {
    // Configure how we ask for username and password
    Map<String, Object> props = new HashMap<>();
    props.put(WSHandlerConstants.ACTION, WSHandlerConstants.USERNAME_TOKEN);
    props.put(WSHandlerConstants.PASSWORD_TYPE, WSConstants.PW_TEXT);

    // Password callback
    props.put(WSHandlerConstants.PW_CALLBACK_REF, passwordCallbackHandler());

    // Validator registration
    Map<QName, Object> validators = new HashMap<>();
    String WSS_WSSECURITY_SECEXT_1_0_XSD = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd";
    QName qName = new QName(WSS_WSSECURITY_SECEXT_1_0_XSD, WSHandlerConstants.USERNAME_TOKEN, "");
    validators.put(qName, usernameTokenValidator());
    props.put(WSS4JInInterceptor.VALIDATOR_MAP, validators);

    WSS4JInInterceptor wss4jInInterceptor = new WSS4JInInterceptor(props);
    return wss4jInInterceptor;
}

我不確定這種方法是好還是壞(我很感激對此的一些反饋),但也許這對下一個人遇到這個問題很有用。 似乎缺乏關於如何集成Spring安全性和CXF的最新文檔。

好的,所以這不是理想的解決方案,希望更好的答案會在稍后的時候出現,最有可能的是,當我有更多時間來看這個時。

我使用正則表達式檢查完整數據包並拔出密碼字段。 代碼如下。 稍后當我找到正確的方法來執行此操作時會更新,因為這不是defintley!

 WSPasswordCallback pc = (WSPasswordCallback) callbacks[0];
        String mydata= pc.getRequestData().getMsgContext().toString();        
        Pattern pattern = Pattern.compile("<wsse:Password Type=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText\">(.*?)<");
        Matcher matcher = pattern.matcher(mydata);
        if (matcher.find())
        {
             pc.setPassword( matcher.group(1) );
        }

暫無
暫無

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

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