JAX-WS使用Handler实现简单的WebService权限验证

WebService如果涉及到安全保密或者使用权限的时候,WS-Security通常是最优选择。WS-Security (Web服务安全) 包含了关于如何在WebService消息上保证完整性和机密性的规约,如何将签名和加密头加入SOAP消息。不过WS-Security也有一些性能上的损耗,在信息保密要求不是很高的情况下,可以通过在SOAPHeader中添加简单的校验信息实现。

具体思路是客户端调用需要认证的服务时,在SOAPHeader中添加授权信息(如用户名、密码或者序列号等)。服务端收到请求,在SOAPHeader中校验授权信息,校验通过则执行请求,校验不通过则返回错误提示。



实例代码 http://download.csdn.net/detail/accountwcx/8922191


客户端发起请求在SOAPHeader中添加的授权数据格式如下

[html]  view plain  copy
  1. <auth xmlns="http://www.tmp.com/auth">  
  2.     <name>admin</name>  
  3.     <password>admin</password>  
  4. </auth>  


服务端


服务端授权校验Handler

[java]  view plain  copy
  1. import java.util.Iterator;  
  2. import java.util.Set;  
  3.   
  4. import javax.xml.namespace.QName;  
  5. import javax.xml.soap.SOAPBody;  
  6. import javax.xml.soap.SOAPElement;  
  7. import javax.xml.soap.SOAPEnvelope;  
  8. import javax.xml.soap.SOAPException;  
  9. import javax.xml.soap.SOAPFault;  
  10. import javax.xml.soap.SOAPHeader;  
  11. import javax.xml.soap.SOAPMessage;  
  12. import javax.xml.ws.handler.MessageContext;  
  13. import javax.xml.ws.handler.soap.SOAPHandler;  
  14. import javax.xml.ws.handler.soap.SOAPMessageContext;  
  15.   
  16. /** 
  17.  * 服务端请求校验Handler  
  18.  * @author accountwcx@qq.com 
  19.  * 
  20.  */  
  21. public class ValidateAuthHandler implements SOAPHandler<SOAPMessageContext> {  
  22.   
  23.     @Override  
  24.     public void close(MessageContext context) {  
  25.     }  
  26.   
  27.     @Override  
  28.     public boolean handleFault(SOAPMessageContext context) {  
  29.         return true;  
  30.     }  
  31.   
  32.     @Override  
  33.     public boolean handleMessage(SOAPMessageContext context) {  
  34.         // 判断消息是请求还是响应  
  35.         Boolean output = (Boolean) context.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);         
  36.           
  37.         boolean result = false;  
  38.           
  39.         SOAPMessage message = context.getMessage();  
  40.           
  41.         //如果是请求,则执行校验  
  42.         if(!output){  
  43.             result = validate(message);  
  44.               
  45.             if(!result){  
  46.                 validateFail(message);  
  47.             }  
  48.         }  
  49.           
  50.         System.out.println(output ? "服务端响应:" : "服务端接收:");  
  51.         try {  
  52.             message.writeTo(System.out);              
  53.         } catch (Exception e) {  
  54.             e.printStackTrace();  
  55.         }  
  56.           
  57.         System.out.println("\r\n");  
  58.   
  59.         return result;  
  60.     }  
  61.       
  62.     /** 
  63.      * 授权校验失败,在SOAPBody中添加SOAPFault 
  64.      * @param message 
  65.      */  
  66.     private void validateFail(SOAPMessage message) {  
  67.         try {  
  68.             SOAPEnvelope envelop = message.getSOAPPart().getEnvelope();  
  69.   
  70.             envelop.getHeader().detachNode();  
  71.             envelop.addHeader();  
  72.   
  73.             envelop.getBody().detachNode();  
  74.             SOAPBody body = envelop.addBody();  
  75.   
  76.             SOAPFault fault = body.getFault();  
  77.   
  78.             if (fault == null) {  
  79.                 fault = body.addFault();  
  80.             }  
  81.   
  82.             fault.setFaultString("授权校验失败!");  
  83.   
  84.             message.saveChanges();  
  85.         } catch (SOAPException e) {  
  86.             e.printStackTrace();  
  87.         }  
  88.     }  
  89.       
  90.     /** 
  91.      * 授权校验 
  92.      * @param message 
  93.      * @return 校验成功返回true,校验失败返回false 
  94.      */  
  95.     private boolean validate(SOAPMessage message){  
  96.         boolean result = false;  
  97.           
  98.         try {  
  99.             SOAPEnvelope envelop = message.getSOAPPart().getEnvelope();  
  100.             SOAPHeader header = envelop.getHeader();  
  101.               
  102.             if(header != null){  
  103.                 Iterator iterator = header.getChildElements(new QName("http://www.tmp.com/auth""auth"));  
  104.                 SOAPElement auth = null;  
  105.                   
  106.                 if(iterator.hasNext()){  
  107.                     //获取auth  
  108.                     auth = (SOAPElement)iterator.next();  
  109.                       
  110.                     //获取name  
  111.                     Iterator it = auth.getChildElements(new QName("http://www.tmp.com/auth""name"));  
  112.                     SOAPElement name = null;  
  113.                     if(it.hasNext()){  
  114.                         name = (SOAPElement)it.next();  
  115.                     }  
  116.                       
  117.                     //获取password  
  118.                     it = auth.getChildElements(new QName("http://www.tmp.com/auth""password"));  
  119.                     SOAPElement password = null;  
  120.                     if(it.hasNext()){  
  121.                         password = (SOAPElement)it.next();  
  122.                     }  
  123.                       
  124.                     //判断name和password是否符合要求  
  125.                     if(name != null && password != null && "admin".equals(name.getValue()) && "admin".equals(password.getValue())){  
  126.                         result = true;  
  127.                     }  
  128.                 }  
  129.             }  
  130.               
  131.         } catch (SOAPException e) {  
  132.             e.printStackTrace();  
  133.         }  
  134.           
  135.         return result;  
  136.     }  
  137.   
  138.     @Override  
  139.     public Set<QName> getHeaders() {  
  140.         return null;  
  141.     }  
  142.   
  143. }  


客户端


客户端添加授权Handler

[html]  view plain  copy
  1. import java.util.Set;  
  2.   
  3. import javax.xml.namespace.QName;  
  4. import javax.xml.soap.SOAPElement;  
  5. import javax.xml.soap.SOAPException;  
  6. import javax.xml.soap.SOAPHeader;  
  7. import javax.xml.soap.SOAPMessage;  
  8. import javax.xml.ws.handler.MessageContext;  
  9. import javax.xml.ws.handler.soap.SOAPHandler;  
  10. import javax.xml.ws.handler.soap.SOAPMessageContext;  
  11.   
  12. /**  
  13.  * 客户端添加请求授权  
  14.  * @author accountwcx@qq.com  
  15.  *  
  16.  */  
  17. public class AddAuthHandler implements SOAPHandler<SOAPMessageContext> {  
  18.   
  19.     @Override  
  20.     public boolean handleMessage(SOAPMessageContext context) {  
  21.         // 判断消息是请求还是响应  
  22.         Boolean output = (Boolean) context.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);  
  23.   
  24.         SOAPMessage message = context.getMessage();  
  25.   
  26.         if (output) {  
  27.             try {  
  28.                 SOAPHeader header = message.getSOAPHeader();  
  29.                 if (header == null) {  
  30.                     header = message.getSOAPPart().getEnvelope().addHeader();  
  31.                 }  
  32.   
  33.                 SOAPElement auth = header.addChildElement(new QName("http://www.tmp.com/auth", "auth"));  
  34.                   
  35.                 SOAPElement name = auth.addChildElement("name");  
  36.                 name.addTextNode("admin");  
  37.   
  38.                 SOAPElement password = auth.addChildElement("password");  
  39.                 password.addTextNode("admin");  
  40.                   
  41.                 message.saveChanges();  
  42.   
  43.             } catch (SOAPException e) {  
  44.                 e.printStackTrace();  
  45.             }  
  46.         }  
  47.           
  48.         System.out.println(output ? "客户端请求:" : "客户端接收:");  
  49.         try {  
  50.             message.writeTo(System.out);  
  51.         } catch (Exception e) {  
  52.             e.printStackTrace();  
  53.         }  
  54.           
  55.         System.out.println("\r\n");  
  56.   
  57.         return true;  
  58.     }  
  59.   
  60.     @Override  
  61.     public boolean handleFault(SOAPMessageContext context) {  
  62.         return true;  
  63.     }  
  64.   
  65.     @Override  
  66.     public void close(MessageContext context) {  
  67.     }  
  68.   
  69.     @Override  
  70.     public Set<QName> getHeaders() {  
  71.         return null;  
  72.     }  
  73. }  

客户端Handler配置文件handler-chain.xml

[html]  view plain  copy
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <javaee:handler-chains xmlns:javaee="http://java.sun.com/xml/ns/javaee"  
  3.     xmlns:xsd="http://www.w3.org/2001/XMLSchema">  
  4.     <javaee:handler-chain>  
  5.         <javaee:handler>  
  6.             <javaee:handler-class>com.rvho.client.handler.AddAuthHandler</javaee:handler-class>  
  7.         </javaee:handler>  
  8.     </javaee:handler-chain>  
  9. </javaee:handler-chains>  

客户端的Service中添加Handler配置文件

[java]  view plain  copy
  1. /** 
  2.  * This class was generated by the JAX-WS RI. 
  3.  * JAX-WS RI 2.2.9-b130926.1035 
  4.  * Generated source version: 2.2 
  5.  *  
  6.  */  
  7. @WebServiceClient(name = "HelloWSService", targetNamespace = "http://www.tmp.com/ws/hello", wsdlLocation = "http://localhost:8014/jaxwsserver/services/hello?wsdl")  
  8. @HandlerChain(file="handler-chain.xml")  
  9. public class HelloWSService  
  10.     extends Service  
  11. {  
  12.   
  13.     private final static URL HELLOWSSERVICE_WSDL_LOCATION;  
  14.     private final static WebServiceException HELLOWSSERVICE_EXCEPTION;  
  15.     private final static QName HELLOWSSERVICE_QNAME = new QName("http://www.tmp.com/ws/hello""HelloWSService");  
  16.   
  17.     static {  
  18.         URL url = null;  
  19.         WebServiceException e = null;  
  20.         try {  
  21.             url = new URL("http://localhost:8014/jaxwsserver/services/hello?wsdl");  
  22.         } catch (MalformedURLException ex) {  
  23.             e = new WebServiceException(ex);  
  24.         }  
  25.         HELLOWSSERVICE_WSDL_LOCATION = url;  
  26.         HELLOWSSERVICE_EXCEPTION = e;  
  27.     }  
  28.   
  29.     public HelloWSService() {  
  30.         super(__getWsdlLocation(), HELLOWSSERVICE_QNAME);  
  31.     }  
  32.   
  33.     public HelloWSService(WebServiceFeature... features) {  
  34.         super(__getWsdlLocation(), HELLOWSSERVICE_QNAME, features);  
  35.     }  
  36.   
  37.     public HelloWSService(URL wsdlLocation) {  
  38.         super(wsdlLocation, HELLOWSSERVICE_QNAME);  
  39.     }  
  40.   
  41.     public HelloWSService(URL wsdlLocation, WebServiceFeature... features) {  
  42.         super(wsdlLocation, HELLOWSSERVICE_QNAME, features);  
  43.     }  
  44.   
  45.     public HelloWSService(URL wsdlLocation, QName serviceName) {  
  46.         super(wsdlLocation, serviceName);  
  47.     }  
  48.   
  49.     public HelloWSService(URL wsdlLocation, QName serviceName, WebServiceFeature... features) {  
  50.         super(wsdlLocation, serviceName, features);  
  51.     }  
  52.   
  53.     /** 
  54.      *  
  55.      * @return 
  56.      *     returns HelloWS 
  57.      */  
  58.     @WebEndpoint(name = "HelloWSPort")  
  59.     public HelloWS getHelloWSPort() {  
  60.         return super.getPort(new QName("http://www.tmp.com/ws/hello""HelloWSPort"), HelloWS.class);  
  61.     }  
  62.   
  63.     /** 
  64.      *  
  65.      * @param features 
  66.      *     A list of {@link javax.xml.ws.WebServiceFeature} to configure on the proxy.  Supported features not in the <code>features</code> parameter will have their default values. 
  67.      * @return 
  68.      *     returns HelloWS 
  69.      */  
  70.     @WebEndpoint(name = "HelloWSPort")  
  71.     public HelloWS getHelloWSPort(WebServiceFeature... features) {  
  72.         return super.getPort(new QName("http://www.tmp.com/ws/hello""HelloWSPort"), HelloWS.class, features);  
  73.     }  
  74.   
  75.     private static URL __getWsdlLocation() {  
  76.         if (HELLOWSSERVICE_EXCEPTION!= null) {  
  77.             throw HELLOWSSERVICE_EXCEPTION;  
  78.         }  
  79.         return HELLOWSSERVICE_WSDL_LOCATION;  
  80.     }  
  81.   
  82. }  


客户端发起index请求

[java]  view plain  copy
  1. URL wsdlUrl = new URL("http://localhost:7180/jaxwsserver/services/hello?wsdl");  
  2. HelloWSService helloWSS = new HelloWSService(wsdlUrl);  
  3. HelloWS helloWS = helloWSS.getHelloWSPort();  
  4. String index = helloWS.index();  

客户端发起正确授权的请求以及服务器的响应

[html]  view plain  copy
  1. <!-- 客户端请求 -->  
  2. <S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/"  
  3.             xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">  
  4.     <SOAP-ENV:Header>  
  5.         <auth xmlns="http://www.tmp.com/auth">  
  6.             <name>admin</name>  
  7.             <password>admin</password>  
  8.         </auth>  
  9.     </SOAP-ENV:Header>  
  10.     <S:Body>  
  11.         <ns2:index xmlns:ns2="http://www.tmp.com/ws/hello" />  
  12.     </S:Body>  
  13. </S:Envelope>  
  14.   
  15. <!-- 服务端响应 -->  
  16. <S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/"  
  17.             xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">  
  18.     <SOAP-ENV:Header/>  
  19.     <S:Body>  
  20.         <ns2:indexResponse xmlns:ns2="http://www.tmp.com/ws/hello">  
  21.             <return>hello</return>  
  22.         </ns2:indexResponse>  
  23.     </S:Body>  
  24. </S:Envelope>  

客户端发起错误授权的请求以及服务器的响应

[html]  view plain  copy
  1. <!-- 客户端请求 -->  
  2. <S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/"  
  3.             xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">  
  4.     <SOAP-ENV:Header>  
  5.         <auth xmlns="http://www.tmp.com/auth">  
  6.             <name></name>  
  7.             <password></password>  
  8.         </auth>  
  9.     </SOAP-ENV:Header>  
  10.     <S:Body>  
  11.         <ns2:index xmlns:ns2="http://www.tmp.com/ws/hello" />  
  12.     </S:Body>  
  13. </S:Envelope>  
  14.   
  15. <!-- 服务器响应 -->  
  16. <S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/"   
  17.             xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">  
  18.     <S:Header/>  
  19.     <S:Body>  
  20.         <S:Fault>  
  21.             <faultcode>S:Server</faultcode>  
  22.             <faultstring>授权校验失败!</faultstring>  
  23.         </S:Fault>  
  24.     </S:Body>  
  25. </S:Envelope>  


HandlerReolver代替Handler配置文件


handler-chain配置文件对所有的请求都添加授权验证信息,有些时候不是所有的请求都需要添加授权验证,HandlerResolver提供了在编程时添加Handler的方法,可以用HandlerResolver给需要授权的接口添加Handler。

[java]  view plain  copy
  1. URL wsdlUrl = new URL("http://localhost:7180/jaxwsserver/services/hello?wsdl");  
  2. HelloWSService helloWSS = new HelloWSService(wsdlUrl);  
  3.   
  4. //通过HandlerResolver添加Handler  
  5. helloWSS.setHandlerResolver(new HandlerResolver(){  
  6.   
  7.     @Override  
  8.     @SuppressWarnings("rawtypes")             
  9.     public List<Handler> getHandlerChain(PortInfo portInfo) {  
  10.         List<Handler> handlerChain = new ArrayList<Handler>();  
  11.         handlerChain.add(new AddAuthHandler());  
  12.         return handlerChain;  
  13.     }  
  14.       
  15. });  
  16.   
  17. HelloWS helloWS = helloWSS.getHelloWSPort();  
  18.   
  19. //调用index服务  
  20. String index = helloWS.index();  


评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值