cxf wss4j 令牌驗證 爲什麼 回調是空?

客戶端明明是加了密碼的,但是爲什麼在服務端打印出來的是null呢?而且還報

Exception in thread "main" javax.xml.ws.soap.SOAPFaultException:The security token could not be authenticated or authorized
 atorg.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:155)
 at $Proxy28.getKeyValue(Unknown Source)
 atcom.cxf.Client.KeyValueClient.main(KeyValueClient.java:56)
Caused by: org.apache.cxf.binding.soap.SoapFault: The securitytoken could not be authenticated or authorized
 atorg.apache.cxf.binding.soap.interceptor.Soap11FaultInInterceptor.unmarshalFault(Soap11FaultInInterceptor.java:75)
 atorg.apache.cxf.binding.soap.interceptor.Soap11FaultInInterceptor.handleMessage(Soap11FaultInInterceptor.java:46)
 atorg.apache.cxf.binding.soap.interceptor.Soap11FaultInInterceptor.handleMessage(Soap11FaultInInterceptor.java:35)
 atorg.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:271)
 atorg.apache.cxf.interceptor.AbstractFaultChainInitiatorObserver.onMessage(AbstractFaultChainInitiatorObserver.java:114)
 atorg.apache.cxf.binding.soap.interceptor.CheckFaultInterceptor.handleMessage(CheckFaultInterceptor.java:69)
 atorg.apache.cxf.binding.soap.interceptor.CheckFaultInterceptor.handleMessage(CheckFaultInterceptor.java:34)
 atorg.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:271)
 atorg.apache.cxf.endpoint.ClientImpl.onMessage(ClientImpl.java:800)
 atorg.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleResponseInternal(HTTPConduit.java:1590)
 atorg.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleResponse(HTTPConduit.java:1488)
 atorg.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.close(HTTPConduit.java:1307)
 atorg.apache.cxf.io.CacheAndWriteOutputStream.postClose(CacheAndWriteOutputStream.java:50)
 atorg.apache.cxf.io.CachedOutputStream.close(CachedOutputStream.java:229)
 atorg.apache.cxf.transport.AbstractConduit.close(AbstractConduit.java:56)
 atorg.apache.cxf.transport.http.HTTPConduit.close(HTTPConduit.java:622)
 atorg.apache.cxf.interceptor.MessageSenderInterceptor$MessageSenderEndingInterceptor.handleMessage(MessageSenderInterceptor.java:62)
 atorg.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:271)
 atorg.apache.cxf.endpoint.ClientImpl.doInvoke(ClientImpl.java:530)
 atorg.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:463)
 atorg.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:366)
 atorg.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:319)
 atorg.apache.cxf.frontend.ClientProxy.invokeSync(ClientProxy.java:96)
 atorg.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:133)
 ... 2 more

 

最後百度到

在server端的回調函數中獲取的password 卻一直是空,搜索了好半天,才找到(這個是MD5加密的):

WSPasswordCallback 的passwordType屬性和password屬性都爲null,你只能獲得用戶名(identifier),一般這裏的邏輯是使用這個用戶名到數據庫中查詢其密碼,然後再設置到password屬性,WSS4J 會自動比較客戶端傳來的值和你設置的這個值。你可能會問爲什麼這裏CXF不把客戶端提交的密碼傳入讓我們在ServerPasswordCallbackHandler中比較呢?這是因爲客戶端提交過來的密碼在SOAP 消息中已經被加密爲MD5的字符串,如果我們要在回調方法中作比較,那麼第一步要做的就是把服務端準備好的密碼加密爲MD5 字符串,由於MD5算法參數不同結果也會有差別,另外,這樣的工作CXF 替我們完成不是更簡單嗎?

根據上面說的,我獲取的password爲null,所以這裏就不用自己判斷密碼了,只要驗證用戶名後,在設置密碼就可以自動驗證了,代碼如下:

public class ServerPasswordCallback implements CallbackHandler{ 

   
    
    public void handle(Callback[] callbacks) throwsIOException,    
 
            UnsupportedCallbackException{    
 
        WSPasswordCallback pc = (WSPasswordCallback)callbacks[0];    
 
        String pw =pc.getPassword();    
 
        String idf =pc.getIdentifier();    
 
        System.out.println("password:"+pw);    
 
        System.out.println("identifier:"+idf);  
 
        if(idf.endsWith("admin")){
 
         pc.setPassword("admin");
 
        }
 
       
 
   
 
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章