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");
 
        }
 
       
 
   
 
}

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