基於Xfire SOAP Header的WebService安全驗證教程


WebSerice是一種開放的web服務,任何人都可以訪問,但我們有時候需要考慮只有付費用戶才能使用WS,所以,我們就需要對WS加入安全驗證機制,當然,可以利用防火牆的IP過濾,web應用的配置從最外層去隔離非法用戶,但在內層,我們也可以使用SOAP Header的方式,由客戶端發送驗證數據,服務端驗通過后基WS訪問權限

首先根據我的這篇Blog

http://blog.csdn.net/daryl715/archive/2007/07/25/1707161.aspx

配置WS Server和WS Client,其中Client端的測試代碼類名由Client改為ClientTest,因為我們要用到Xfire的一個名為Client的類 

 

首先我們編寫服務端驗證類繼承AbstractHandler

 

package test;

import org.codehaus.xfire.MessageContext;
import org.codehaus.xfire.handler.AbstractHandler;
import org.jdom.Element;

public class AuthenticationHandler extends AbstractHandler {

    
public void invoke(MessageContext cfx) throws Exception {
           
if(cfx.getInMessage().getHeader() == null)
           
{
               
throw new org.codehaus.xfire.fault.XFireFault("請求必須包含驗證信息",org.codehaus.xfire.fault.XFireFault.SENDER);
           }

           Element token
=cfx.getInMessage().getHeader().getChild("AuthenticationToken");
           
if (token == null
           

            
throw new org.codehaus.xfire.fault.XFireFault("請求必須包含身份驗證信息", org.codehaus.xfire.fault.XFireFault.SENDER); 
           }
 

              String username 
= token.getChild("Username").getValue(); 
              String password 
= token.getChild("Password").getValue(); 
              
try 
              

                  
//進行身份驗證 ,只有abcd@1234的用戶為授權用戶
                 if(username.equals("abcd"&& password.equals("1234"))
                  
//這語句不顯示
                  System.out.println("身份驗證通過");
                 
else throw new Exception();
              }
 
              
catch (Exception e) 
              

                  
throw new   org.codehaus.xfire.fault.XFireFault("非法的用戶名和密碼",   org.codehaus.xfire.fault.XFireFault.SENDER); 
              }
 

          }
 



}

 

下面是Client發送授權信息

 

package test;

import org.codehaus.xfire.MessageContext;
import org.codehaus.xfire.handler.AbstractHandler;
import org.jdom.Element;

public class ClientAuthenticationHandler extends AbstractHandler {

     
private String username = null

     
private String password = null

     
public ClientAuthenticationHandler() 

     }
 

     
public ClientAuthenticationHandler(String username,String password) 

         
this.username = username; 

         
this.password = password; 
     }
 

     
public void setUsername(String username) 

         
this.username = username; 

     }
 

     
public void setPassword(String password) 

         
this.password = password; 

     }
 

     
public void invoke(MessageContext context) throws Exception 

         
//為SOAP Header構造驗證信息
         Element el = new Element("header"); 
         context.getOutMessage().setHeader(el); 
         Element auth 
= new Element("AuthenticationToken"); 
         Element username_el 
= new Element("Username"); 
         username_el.addContent(username); 
         Element password_el 
= new Element("Password"); 
         password_el.addContent(password); 
         auth.addContent(username_el); 
         auth.addContent(password_el); 
         el.addContent(auth); 
     }
 



}

為ClientTest.java加入以下代碼

 XFireProxy proxy = (XFireProxy)Proxy.getInvocationHandler(service);
Client client = proxy.getClient();
client.addOutHandler(new ClientAuthenticationHandler("abcd1","1234"));

等等,還沒有完,修改Services.xm為WS綁定Handler

  

<?xml version="1.0" encoding="UTF-8"?>


<beans>
<service xmlns="http://xfire.codehaus.org/config/1.0">
<name>HelloService</name>
<namespace>http://test/HelloService</namespace>
<serviceClass>test.IHelloService</serviceClass>
<implementationClass>test.HelloServiceImpl</implementationClass>
 
<inHandlers> 
 
<handler  handlerClass ="test.AuthenticationHandler" ></handler > 
 
</inHandlers>
</service>
</beans>


這樣我們就完成了編碼,下面啟動tomcat,運行客戶端代碼,本文為abcd@1234位授權用戶,使用abcd@1234,可以正常訪問WS,如果用錯誤帳號,則會有以下異常

 

Exception in thread "main" org.codehaus.xfire.XFireRuntimeException: Could not invoke service.. Nested exception is org.codehaus.xfire.fault.XFireFault: 非法的用戶名和密碼
org.codehaus.xfire.fault.XFireFault: 非法的用戶名和密碼
    at org.codehaus.xfire.fault.Soap11FaultSerializer.readMessage(Soap11FaultSerializer.java:31)
    at org.codehaus.xfire.fault.SoapFaultSerializer.readMessage(SoapFaultSerializer.java:28)
    at org.codehaus.xfire.soap.handler.ReadHeadersHandler.checkForFault(ReadHeadersHandler.java:111)
    at org.codehaus.xfire.soap.handler.ReadHeadersHandler.invoke(ReadHeadersHandler.java:67)
    at org.codehaus.xfire.handler.HandlerPipeline.invoke(HandlerPipeline.java:131)
    at org.codehaus.xfire.client.Client.onReceive(Client.java:406)
    at org.codehaus.xfire.transport.http.HttpChannel.sendViaClient(HttpChannel.java:139)
    at org.codehaus.xfire.transport.http.HttpChannel.send(HttpChannel.java:48)
    at org.codehaus.xfire.handler.OutMessageSender.invoke(OutMessageSender.java:26)
    at org.codehaus.xfire.handler.HandlerPipeline.invoke(HandlerPipeline.java:131)
    at org.codehaus.xfire.client.Invocation.invoke(Invocation.java:79)
    at org.codehaus.xfire.client.Invocation.invoke(Invocation.java:114)
    at org.codehaus.xfire.client.Client.invoke(Client.java:336)
    at org.codehaus.xfire.client.XFireProxy.handleRequest(XFireProxy.java:77)
    at org.codehaus.xfire.client.XFireProxy.invoke(XFireProxy.java:57)
    at $Proxy0.getUser(Unknown Source)
    at test.ClientTest.main(ClientTest.java:39)

 

如果不在CientTest加以下增加Heade則會有以下異常

 XFireProxy proxy = (XFireProxy)Proxy.getInvocationHandler(service);
Client client = proxy.getClient();
 client.addOutHandler(new ClientAuthenticationHandler("abcd1","1234"));

Exception in thread "main" org.codehaus.xfire.XFireRuntimeException: Could not invoke service.. Nested exception is org.codehaus.xfire.fault.XFireFault: 請求必須包含驗證信息
org.codehaus.xfire.fault.XFireFault: 請求必須包含驗證信息
    at org.codehaus.xfire.fault.Soap11FaultSerializer.readMessage(Soap11FaultSerializer.java:31)
    at org.codehaus.xfire.fault.SoapFaultSerializer.readMessage(SoapFaultSerializer.java:28)
    at org.codehaus.xfire.soap.handler.ReadHeadersHandler.checkForFault(ReadHeadersHandler.java:111)
    at org.codehaus.xfire.soap.handler.ReadHeadersHandler.invoke(ReadHeadersHandler.java:67)
    at org.codehaus.xfire.handler.HandlerPipeline.invoke(HandlerPipeline.java:131)
    at org.codehaus.xfire.client.Client.onReceive(Client.java:406)
    at org.codehaus.xfire.transport.http.HttpChannel.sendViaClient(HttpChannel.java:139)
    at org.codehaus.xfire.transport.http.HttpChannel.send(HttpChannel.java:48)
    at org.codehaus.xfire.handler.OutMessageSender.invoke(OutMessageSender.java:26)
    at org.codehaus.xfire.handler.HandlerPipeline.invoke(HandlerPipeline.java:131)
    at org.codehaus.xfire.client.Invocation.invoke(Invocation.java:79)
    at org.codehaus.xfire.client.Invocation.invoke(Invocation.java:114)
    at org.codehaus.xfire.client.Client.invoke(Client.java:336)
    at org.codehaus.xfire.client.XFireProxy.handleRequest(XFireProxy.java:77)
    at org.codehaus.xfire.client.XFireProxy.invoke(XFireProxy.java:57)
    at $Proxy0.getUser(Unknown Source)
    at test.ClientTest.main(ClientTest.java:35)

注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2020 ITdaan.com