CXFカスタムブロッカーによる権限制御

7529 ワード

一.ブロッキング
私达がJavaの征途を学ぶ中で多くの遮断器に出会った:サーブレットの中のFilterは1つの遮断器で、Struts 2の中にも遮断器があって、.
CXFにおけるブロッカーの基本原理はやはり動的エージェントを使用することであり、コアモジュールを修正することなく、いくつかの機能を動的に追加することで、コードの結合性を低減することができる.
二.CXFブロッキング
CXFは、Interceptorにおいてメッセージを特殊な処理を行うことにより、ログ記録、soapメッセージ処理、メッセージの圧縮処理など、多くの重要な機能モジュールを実現する.
次の例では、CXFログブロッキングについて説明します.
1.サービス側にログ・ブロッカーを追加する:
public class MyServer {
	public static void main(String[] args) {
		HelloService helloService = new HelloServiceImpl();
		EndpointImpl epi = (EndpointImpl)Endpoint.publish("http://localhost/sayHello", helloService);
		epi.getInInterceptors().add(new LoggingInInterceptor()); //       in log   
		epi.getOutInterceptors().add(new LoggingOutInterceptor()); //       out log   
		System.out.println("Web Service     ");
	}
}

2.クライアントがログブロックを追加
public class MyClient {
	public static void main(String[] args) {
		HelloServiceImplService factory = new HelloServiceImplService();
		HelloService helloService = factory.getHelloServiceImplPort();

		Client client = ClientProxy.getClient(helloService);
		client.getInInterceptors().add(new LoggingInInterceptor()); //      in log   
		client.getOutInterceptors().add(new LoggingOutInterceptor()); //      out log   

		System.out.println(helloService.sayHello("zhangsan"));
	}
}

その他のプログラムコードは、前のブログを参照してください.http://blog.csdn.net/zdp072/article/details/27829831
クライアントは、cxf-2.2.10のjarパッケージを導入する必要があります.jar  wsdl4j-1.6.2.jar  XmlSchema-1.4.5.jar
3.ログは次のとおりです.
--サービス側
2014-6-7 23:04:28 org.apache.cxf.service.factory.ReflectionServiceFactoryBean buildServiceFromClass
  : Creating Service {http://impl.service.zdp.com/}HelloServiceImplService from class com.zdp.service.HelloService
2014-6-7 23:04:28 org.apache.cxf.endpoint.ServerImpl initDestination
  : Setting the server's publish address to be http://localhost:80/sayHello
2014-06-07 23:04:28.718::INFO:  Logging to STDERR via org.mortbay.log.StdErrLog
2014-06-07 23:04:28.726::INFO:  jetty-6.1.21
2014-06-07 23:04:28.799::INFO:  Started SelectChannelConnector@localhost:80
Web Service     
--クライアント
2014-6-7 23:05:26 org.apache.cxf.service.factory.ReflectionServiceFactoryBean buildServiceFromWSDL
  : Creating Service {http://impl.service.zdp.com/}HelloServiceImplService from WSDL: http://localhost/sayHello?wsdl
2014-6-7 23:05:26 org.apache.cxf.interceptor.LoggingOutInterceptor$LoggingCallback onClose
  : Outbound Message
---------------------------
ID: 1
Address: http://localhost/sayHello
Encoding: UTF-8
Content-Type: text/xml
Headers: {SOAPAction=[""], Accept=[*/*]}
Payload: <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><ns2:sayHello xmlns:ns2="http://service.zdp.com/"><arg0>zhangsan</arg0></ns2:sayHello></soap:Body></soap:Envelope>
--------------------------------------
2014-6-7 23:05:26 org.apache.cxf.interceptor.LoggingInInterceptor logging
  : Inbound Message
----------------------------
ID: 1
Response-Code: 200
Encoding: UTF-8
Content-Type: text/xml; charset=utf-8
Headers: {content-type=[text/xml; charset=utf-8], Content-Length=[275], Server=[Jetty(6.1.21)]}
Payload: <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><ns1:sayHelloResponse xmlns:ns1="http://service.zdp.com/"><return>zhangsan,   !       : Sat Jun 07 23:05:26 CST 2014</return></ns1:sayHelloResponse></soap:Body></soap:Envelope>
--------------------------------------
zhangsan,   !       : Sat Jun 07 23:05:26 CST 2014

三.CXFカスタムブロッキング
CXFを使用して権限制御を行うにはどうすればいいですか?
考え方:サーバ側はinputメッセージに常にユーザー名、パスワード情報を携帯することを要求し、ユーザー名とパスワード情報がなければ、呼び出しを直接拒否する.
コード実装:
1.サーバー側ブロック:
/**  
 *         
 */
public class AuthInterceptor extends AbstractPhaseInterceptor<SoapMessage> {

	public AuthInterceptor() {
		super(Phase.PRE_INVOKE); //            SOAP  
	}
    
	//      
	@Override
	public void handleMessage(SoapMessage msg) throws Fault {
		System.out.println("come to auth interceptor...");
		//  SOAP     Header
		List<Header> headers = msg.getHeaders();
		
		if(headers == null || headers.size() < 1) {
			throw new Fault(new IllegalArgumentException("  Header,       "));
		}
		//  Header          
		Header firstHeader = headers.get(0);
		Element element = (Element) firstHeader.getObject();
		
		NodeList userNameElement = element.getElementsByTagName("userName");
		NodeList passwordElement = element.getElementsByTagName("password");
		
		if (userNameElement.getLength() != 1) {
			throw new Fault(new IllegalArgumentException("       "));
		}
			
		if (passwordElement.getLength() != 1) {
			throw new Fault(new IllegalArgumentException("        "));
		}
		
		//         
		String userName = userNameElement.item(0).getTextContent();
		String password = passwordElement.item(0).getTextContent();
		
		//      ,         ,     ,          webservice
		if (!userName.equals("zhangsan") || !password.equals("123456")) {
			throw new Fault(new IllegalArgumentException("         "));
		}
	}
}

2.クライアントブロック
/**
 *       ( xml      )
 */
public class AddHeaderInterceptor extends AbstractPhaseInterceptor<SoapMessage>{
    
	private String userName;
	private String password;
	
	public AddHeaderInterceptor(String userName, String password) {
		super(Phase.PREPARE_SEND);
		this.userName = userName;
		this.password = password; 
	}

	@Override
	public void handleMessage(SoapMessage msg) throws Fault {
		
		List<Header> headers = msg.getHeaders();
		
		//  Document  
		Document document = DOMUtils.createDocument();
		Element element = document.createElement("authHeader"); 
		
		//      Head       
		Element userNameElement= document.createElement("userName"); 
		userNameElement.setTextContent(userName);
		Element passwordElement = document.createElement("password"); 
		passwordElement.setTextContent(password);
		
		element.appendChild(userNameElement);
		element.appendChild(passwordElement);
		headers.add(new Header(new QName(""), element));
		/**
		 *    XML  
		 * <authHeader>
		 * 	    <userName>zhangsan</userName>
		 * 	    <password>123456</password>
		 * </authHeader>
		 */
	}
}

3.サービス側
public class MyServer {
	public static void main(String[] args) {
		HelloService helloService = new HelloServiceImpl();
		EndpointImpl epi = (EndpointImpl)Endpoint.publish("http://localhost/sayHello", helloService);

		//       in      ,  AuthInterceptor         ,       
		epi.getInInterceptors().add(new AuthInterceptor()); 
		System.out.println("Web Service     ");
	}
}

4.クライアント
public class MyClient {
	public static void main(String[] args) {
		HelloServiceImplService factory = new HelloServiceImplService();
		
		//        webservice   
		HelloService helloService = factory.getHelloServiceImplPort();
		Client client = ClientProxy.getClient(helloService);
		client.getOutInterceptors().add(new AddHeaderInterceptor("zhangsan", "123456")); 
		System.out.println(helloService.sayHello("zhangsan"));
	}
}