2012-11-18 56 views
5

我跟隨了一對夫婦教程的混搭,並且都不是太成功!Apache CXF和WS-Security - 密碼回撥

我試圖讓Apache CXF和WS-Security回撥給我的Spring Security身份驗證器。所有的工作都接近工作,但是一旦遇到問題,我們就會遇到一個問題,即讓Spring的安全性脫離WS回調。

下面的處理程序獲取了galled,但pc.getPassword()爲null。我想這是肥皂發送的密碼,所以我可以將它傳遞給春天

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> 

和SOAP請求,我發出了SoapUI的是

<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> 

版本明智的是春3.1和2.7.0 CXF

什麼我需要做的,看到「passwordxx 「在ServerPasswordCallback類中?它是肥皂請求,配置還是錯誤?!

乾杯, 羅布

回答

0

好了,所以這不是理想的解決方案,並希望一個更好的答案將沿位後回落的路線,最有可能當我有更多的時間來看看這個。

我使用正則表達式來檢查完整的數據包並提取密碼字段。代碼如下。稍後會更新,當我找出正確的方法來做到這一點,因爲這是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)); 
     } 
1

它從文檔出現在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檢查所提供的密碼的有效性,並設置了春季安全上下文有:

的 應用程序可以使用以下方法設置此參數
@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的最新文檔。