欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費電子書(shū)等14項超值服

開(kāi)通VIP
實(shí)現安全的AXIS Web服務(wù),第2部分

本文是J2EE Web服務(wù)開(kāi)發(fā)系列文章的第十三篇,本文將首先簡(jiǎn)單介紹Web 服務(wù)安全性相關(guān)技術(shù)和開(kāi)發(fā)工具,然后介紹了使用WSSecurity工具SOAP消息進(jìn)行簽名和驗證的方法;接下來(lái)深入討論了使用現成的WS-Security工具,結合Handler模型開(kāi)發(fā)一個(gè)axis下實(shí)現WS-Security的通用應用框架。

閱讀本文前您需要以下的知識和工具:

  • Apache axis1.1,并且會(huì )初步使用;
  • Tomcat 5.0.16以上, 并且會(huì )初步使用;
  • SOAP消息(SOAP Message)編程知識;
  • Java安全編程基礎知識;
  • JAX-RPC編程基礎知識;
  • Servlet的開(kāi)發(fā)經(jīng)驗;
  • Sun提供的JAX-RPC參考實(shí)現(jaxrpc-impl.jar,在J2EESDK1.4或者JWSDP1.4中可找到);
  • 一個(gè)JSSE安全提供者(如ISNetworks);
  • Trust Services Integration Kit,可在http://www.xmltrustcenter.org上獲得。

本文的參考資料見(jiàn) 參考資料。

本文的全部代碼在這里 下載。

Web 服務(wù)安全性相關(guān)技術(shù)和開(kāi)發(fā)工具

Web 服務(wù)安全性規范是一套可以幫助 Web 服務(wù)開(kāi)發(fā)者保證 SOAP 消息交換的安全的機制。WS-Security 特別描述了對現有的 SOAP 消息傳遞的增強,從而通過(guò)對 SOAP 消息應用消息完整性、消息機密性和單消息認證提供了保護級別。這些基本機制可以通過(guò)各種方式聯(lián)合,以適應構建使用多種加密技術(shù)的多種安全性模型。

圍繞Web服務(wù)的安全,有很多相關(guān)的技術(shù),比如WS-Security,WS-Trace等,另外,還有以下相關(guān)技術(shù):

  • XML Digital Signature(XML數字簽名)
  • XML Encryption (XML加密)
  • XKMS (XML Key Management Specification)
  • XACML (eXtensible Access Control Markup Language)
  • SAML (Secure Assertion Markup Language)
  • ebXML Message Service Security
  • Identity Management & Liberty Project

由于本文是一個(gè)實(shí)例性文章,故不對WS-Security做詳細的探討,你可以在develperWorks Web 服務(wù)安全專(zhuān)題找到許多相關(guān)資料(見(jiàn)參考資料)。

Trust Services Integration Kit提供了一個(gè)WS-Security實(shí)現。你可以從http://www.xmltrustcenter.org獲得相關(guān)庫文件,分別是wssecurity.jar和tsik.jar。wssecurity.jar中包含一個(gè)WSSecurity類(lèi),可以使用它來(lái)對XML進(jìn)行數字簽名和驗證,加密與解密。

下面我們使用WS-Security來(lái)對SOAP消息進(jìn)行數字簽名,然后再進(jìn)行驗證。



回頁(yè)首


SOAP消息的簽名和驗證

使用WSSecurity對SOAP消息數字簽名

在對SOAP消息進(jìn)行簽名前,首先生成一個(gè)keystore。keystore包含了進(jìn)行數字簽名所需要的身份信息。通過(guò)以下批處理腳本來(lái)創(chuàng )建keystore:


例程1 創(chuàng )建keystore(server.keystore)
set SERVER_DN="CN=hellking-Server, OU=huayuan, O=huayuan, L=BEIJINGC, S=BEIJING, C=CN"set KS_PASS=-storepass changeitset KS_TYPE=-storetype JKSset KEYINFO=-keyalg RSA#生成服務(wù)器端keystore。keytool -genkey -dname %SERVER_DN% %KS_PASS% %KS_TYPE% -keystore server.keystore %KEYINFO% -keypass changeit

SignAndVerifySoap類(lèi)中包含了一個(gè)對XML進(jìn)行簽名的方法,它就是sign(),這個(gè)方法將對SOAP消息進(jìn)行簽名,然后輸出和WS-Security兼容的SOAP消息。下面我們看具體代碼。


例程2 對SOAP消息簽名
	package com.hellking.study.webservice;import com.verisign.messaging.WSSecurity;...public class SignAndVerifySoap {		final String KEY_STORE = "server.keystore";    final String SOTE_PASS = "changeit";    final String KEY_ALIAS="mykey";    final String TARGET_FILE="signed.xml";//簽名后的SOAP消息    final String SOURE_FILE="source.xml";//簽名前的SOAP消息    final String KEY_TYPE="JKS";		/**	 *對xml進(jìn)行簽名	 */	public void sign()	{			try		{			System.out.println("開(kāi)始對SOAP消息進(jìn)行簽名,使用的密匙庫:" + KEY_STORE + "\n");				// 獲得私有key和相關(guān)證書(shū),請參考JAVA安全編程相關(guān)書(shū)籍		FileInputStream fileInputStream = new FileInputStream(KEY_STORE);		System.out.println(java.security.KeyStore.getDefaultType());		java.security.KeyStore store = java.security.KeyStore.getInstance(KEY_TYPE);		store.load(fileInputStream, SOTE_PASS.toCharArray());		PrivateKey key = (PrivateKey)store.getKey(KEY_ALIAS, SOTE_PASS.toCharArray());		X509Certificate certification = (X509Certificate)store.getCertificate(KEY_ALIAS);		// 讀取XML源文件到文檔中		Document source = readFile(SOURE_FILE);		SigningKey signingKey = SigningKeyFactory.makeSigningKey(key);		KeyInfo keyInfo = new KeyInfo();		keyInfo.setCertificate(certification);		WSSecurity wsSecurity = new WSSecurity();		wsSecurity.setPreferredNamespace("http://schemas.xmlsoap.org/ws/2003/06/secext");		//對SOAP消息進(jìn)行簽名		wsSecurity.sign(source, signingKey, keyInfo);		// 保存簽名后的SOAP消息			writeFile(source, new FileOutputStream(TARGET_FILE));		System.out.println("把簽名后的文件寫(xiě)入: " + TARGET_FILE + ",請查看結果!");	}	catch(Exception e)	{		e.printStackTrace();	}			}	

在執行此程序前,請把wssecurity.jar、source.xml和tsik.jar設置到類(lèi)路徑環(huán)境變量中。簽名前的SOAP為:


例程3 簽名前的SOAP消息(source.xml)
<?xml version="1.0" encoding="UTF-8"?><soapenv:Envelope 	xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" 	xmlns:xsd="http://www.w3.org/2001/XMLSchema" 	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <soapenv:Body>  <ns1:getTax soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"xmlns:ns1="http://hellking.webservices.com/">   <op1 xsi:type="xsd:double">5000.0</op1>  </ns1:getTax> </soapenv:Body></soapenv:Envelope>

簽名后的SOAP消息如例程4所示。


例程4 簽名后的SOAP消息(signed.xml)
<?xml version="1.0" encoding="UTF-8"?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <soapenv:Header><wsse:Security xmlns:wsse="http://schemas.xmlsoap.org/ws/2003/06/secext"><wsse:BinarySecurityToken EncodingType="wsse:Base64Binary" ValueType="wsse:X509v3" wsu:Id="wsse-ee805a80-cd95-11d8-9cf9-fd6213c0f8be" xmlns:wsu="http://schemas.xmlsoap.org/ws/2003/06/utility">MIICUjCCAbsCBEDB0GIwDQYJKoZIhvcNAQE…VkTkPw==</wsse:BinarySecurityToken><ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#"><ds:SignedInfo><ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/><ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/><ds:Reference URI="#wsse-ee5308f0-cd95-11d8-9cf9-fd6213c0f8be"><ds:Transforms><ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/></ds:Transforms><ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/><ds:DigestValue>ZjRVnI2g7kcX0h9r4JtiltpYQPA=</ds:DigestValue></ds:Reference><ds:Reference URI="#wsse-ee4e4e00-cd95-11d8-9cf9-fd6213c0f8be"><ds:Transforms><ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/></ds:Transforms><ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/><ds:DigestValue>moZ0d+8mH1kfNw0VEK39V0Td9EM=</ds:DigestValue></ds:Reference></ds:SignedInfo><ds:SignatureValue>fPpYrf0uNP8W2XVVIQNc3OQt2Wn90M/0uJ0dDZTNRR0NxBBBX36wSXt7NfI5Fmh4ru44Wk34EGI7mqMAE5O0/wtIlFRJt3zAvA6k3nhgcYj6tn/9kZwwxh1RkFTfTX9xdQ6Xn+P6m+YBm1YEEcTWkJd7XcxdyDEns2kYOhONx1U=</ds:SignatureValue><ds:KeyInfo><wsse:SecurityTokenReference><wsse:Reference URI="#wsse-ee805a80-cd95-11d8-9cf9-fd6213c0f8be"/></wsse:SecurityTokenReference></ds:KeyInfo></ds:Signature></wsse:Security><wsu:Timestamp xmlns:wsu="http://schemas.xmlsoap.org/ws/2003/06/utility"><wsu:Created wsu:Id="wsse-ee4e4e00-cd95-11d8-9cf9-fd6213c0f8be">2004-07-04T08:41:23Z</wsu:Created></wsu:Timestamp></soapenv:Header><soapenv:Body wsu:Id="wsse-ee5308f0-cd95-11d8-9cf9-fd6213c0f8be" 	xmlns:wsu="http://schemas.xmlsoap.org/ws/2003/06/utility">  <ns1:getTax soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"   	xmlns:ns1="http://hellking.webservices.com/">   <op1 xsi:type="xsd:double">5000.0</op1>  </ns1:getTax> </soapenv:Body></soapenv:Envelope>

簽名后的SOAP消息中,頭部包含了簽名信息以及驗證SOAP消息所需要的key。<SignedInfo> </SignedInfo> 描述了已簽署的消息內容。<SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/> 指出了簽名算法(Signature Method Algorithm)。這個(gè)算法被用來(lái)將規范算法的輸出轉換成簽名值(Signature Value)。Key Info 元素包含的部分就是數字證書(shū)本身。

對簽名的SOAP消息進(jìn)行驗證

對SOAP消息進(jìn)行驗證就是使用keystore的信息生成TrustVerifier對象,然后調用WSSecurity的verify方法進(jìn)行驗證。


例程5 驗證簽名后的SOAP消息
	/**	 *驗證已經(jīng)簽名的SOAP消息	 */	public void verify()	{		try		{			System.out.println("開(kāi)始檢驗SOAP消息,使用的密匙庫:" + KEY_STORE + "\n");				// 獲得私有key和相關(guān)證書(shū),請參考JAVA安全編程相關(guān)書(shū)籍		FileInputStream fileInputStream = new FileInputStream(KEY_STORE);		java.security.KeyStore store = java.security.KeyStore.getInstance(KEY_TYPE);		store.load(fileInputStream, SOTE_PASS.toCharArray());			// 讀取XML源文件到文檔中		Document source = readFile(TARGET_FILE);		org.xmltrustcenter.verifier.TrustVerifier verifier =            new org.xmltrustcenter.verifier.X509TrustVerifier(store);		WSSecurity wsSecurity = new WSSecurity();        com.verisign.messaging.MessageValidity[] resa =     wsSecurity.verify(source,verifier,null,null);       System.out.println("檢驗結果:");	   for (int len = 0; len < resa.length; len++){      System.out.println("result[" + len + "] = " + (resa[len].isValid()?"驗證通過(guò)":"驗證不通過(guò)"));    }    }    catch(Exception e)	{		e.printStackTrace();	}}

執行SignAndVerifySoap的verify方法,可以看到類(lèi)似以下的結果。


圖1 對SOAP消息進(jìn)行驗證



回頁(yè)首


在A(yíng)XIS下實(shí)現WS-Security的應用框架

待開(kāi)發(fā)的應用開(kāi)發(fā)框架基于Handler實(shí)現,將達到以下目標:此框架基于JAX-RPC環(huán)境下實(shí)現WS-Security應用,它可以部署到任何需要實(shí)現WS-Security的axis環(huán)境下的Web服務(wù)應用中,同時(shí)具體的應用程序不做任何編碼修改。

由于此基于Handler實(shí)現,我們有必要回顧一下Handler的一些基礎知識。

SOAP消息Handler能夠訪(fǎng)問(wèn)代表RPC請求或者響應的SOAP消息。在JAX-RPC技術(shù)中,SOAP消息Handler可以部署在服務(wù)端,也可以在客戶(hù)端使用。

SOAP消息Handler非常像Servlet技術(shù)中的Filter,它們共同的特點(diǎn)是請求發(fā)送到目標前,Handler/Filter可以截取這些請求,并對請求做一些處理,從而達到一些輔助的功能。多個(gè)Handler可以組成一個(gè)Handler鏈,鏈上的每個(gè)Handler都完成某個(gè)特定的任務(wù)。比如有的Handler進(jìn)行權限驗證,有的Handler進(jìn)行日志處理等。關(guān)于Handler更詳細的介紹,請參考本系列文章《 J2EE Web服務(wù)開(kāi)發(fā)系列之六: 使用Handler來(lái)增強Web服務(wù)的功能》。

實(shí)現原理

圖2是此例子具體實(shí)現原理圖。


圖2 Handler結合WSSecurity實(shí)現Web服務(wù)安全的工作原理

處理流程如下:

1、 客戶(hù)端(WSSClient)發(fā)出調用Web服務(wù)請求;

2、 客戶(hù)端Handler(WSSecurityClientHandler)截獲請求的SOAP消息;

3、 客戶(hù)端Handler對截獲的SOAP消息進(jìn)行數字簽名(使用client.keystore作為簽名依據);

4、 客戶(hù)端Handler對簽名后的SOAP消息進(jìn)行加密(使用RSA算法加密);

5、 被加密的SOAP消息通過(guò)互聯(lián)網(wǎng)傳送到目標Web服務(wù)端口;

6、 服務(wù)器端Handler(WSSecurityServerHandler)截獲加密的SOAP消息;

7、 服務(wù)器端Handler對加密的SOAP消息進(jìn)行解密;

8、 服務(wù)器端Handler對SOAP消息進(jìn)行身份驗證(server.truststore包含了所信任的身份信息),如果驗證不通過(guò),將拋出異常;

9、 服務(wù)器端Handler刪除被解密后的SOAP消息中與WS-Security相關(guān)的元素;

10、 解密后的原始SOAP消息被發(fā)送到目標Web服務(wù)端口(如TaxService);

11、 目標Web服務(wù)對Web服務(wù)請求進(jìn)行處理,然后返回響應的SOAP消息;

12、 服務(wù)器端Handler截獲響應的SOAP消息;

13、 服務(wù)器端Handler對截獲的SOAP消息進(jìn)行數字簽名(使用server.keystore作為簽名依據);

14、 服務(wù)器端Handler對簽名后的SOAP消息進(jìn)行加密(使用RSA算法加密);

15、 被加密的SOAP消息通過(guò)互聯(lián)網(wǎng)傳送到目客戶(hù)端;

16、 客戶(hù)端Handler截獲加密的SOAP消息;

17、 客戶(hù)端Handler對加密的SOAP消息進(jìn)行解密;

18、 客戶(hù)端Handler對SOAP消息進(jìn)行身份驗證(client.truststore包含了所信任的身份信息),如果驗證不通過(guò),將拋出異常;

19、 客戶(hù)端Handler刪除被解密后的SOAP消息中與WS-Security相關(guān)的元素;

20、 被解密后的SOAP消息發(fā)送到目標客戶(hù)端,客戶(hù)端輸出調用結果。

從上面可以看出,在一個(gè)SOAP調用回合中,要對SOAP消息進(jìn)行四次處理?;旧隙际?簽名‘加密‘解密‘驗證"的過(guò)程。

創(chuàng )建相關(guān)密匙庫

客戶(hù)端和服務(wù)端都有相關(guān)的密匙庫,其中:

  • client.keystore:客戶(hù)端自身的身份信息;
  • client.truststore:客戶(hù)端所信任的身份信息,在此例中也就是包含了服務(wù)器的身份信息;
  • server.keystore:服務(wù)器自身的身份信息;
  • server.truststore:服務(wù)器所信任的身份信息(即客戶(hù)端身份信息)。

你可以使用以下的批處理腳本創(chuàng )建上面四個(gè)密匙庫。


例程6 創(chuàng )建相關(guān)密匙庫(gen-cer-store.bat)
set SERVER_DN="CN=hellking-Server, OU=huayuan, O=huayuan, L=BEIJINGC, S=BEIJING, C=CN"set CLIENT_DN="CN=hellking-Client, OU=tsinghua, O=tsinghua, L=BEIJING, S=BEIJING, C=CN"set KS_PASS=-storepass changeitset KEYINFO=-keyalg RSA#生成server.keystore。keytool -genkey -dname %SERVER_DN% %KS_PASS% -keystore server.keystore %KEYINFO% -keypass changeit#從server.keystore導出數字證書(shū)。keytool -export -file test_axis.cer %KS_PASS% -keystore server.keystore#從服務(wù)器的數字證書(shū)導出到客戶(hù)端信任的truststore中。keytool -import -file test_axis.cer %KS_PASS% -keystore client.truststore -alias serverkey -noprompt#生成client.keystore。keytool -genkey -dname %CLIENT_DN% %KS_PASS% -keystore client.keystore %KEYINFO% -keypass changeit#從client.keystore導出數字證書(shū)。keytool -export -file test_axis.cer %KS_PASS% -keystore client.keystore#從客戶(hù)端的數字證書(shū)導出到服務(wù)器信任的truststore中。keytool -import -file test_axis.cer %KS_PASS% -keystore server.truststore -alias clientkey -noprompt#end

簽名、加密、解密、身份驗證的實(shí)現

對SOAP消息的簽名、加密、解密、身份驗證都放在一個(gè)名為WSSHelper的類(lèi)中進(jìn)行。


例程7 簽名、加密、解密、身份驗證功能的實(shí)現――WSSHelper.java
package com.hellking.study.webservice;import com.verisign.messaging.WSSecurity;...public class WSSHelper {	static String PROVIDER="ISNetworks";//JSSE安全提供者。	   //添加JSSE安全提供者,你也可以使用其它安全提供者。只要支持DESede算法。	static	{	java.security.Security.addProvider(new com.isnetworks.provider.jce.ISNetworksProvider());    }    /**     *對XML文檔進(jìn)行數字簽名。     */	public static void sign(Document doc, String keystore, String storetype,						String storepass, String alias, String keypass) throws Exception {		FileInputStream fileInputStream = new FileInputStream(keystore);		java.security.KeyStore keyStore = java.security.KeyStore.getInstance(storetype);		keyStore.load(fileInputStream, storepass.toCharArray());		PrivateKey key = (PrivateKey)keyStore.getKey(alias, keypass.toCharArray());		X509Certificate cert = (X509Certificate)keyStore.getCertificate(alias);		SigningKey sk = SigningKeyFactory.makeSigningKey(key);		KeyInfo ki = new KeyInfo();		ki.setCertificate(cert);		WSSecurity wSSecurity = new WSSecurity();		wSSecurity.sign(doc, sk, ki);//簽名。	}    /**     *對XML文檔進(jìn)行身份驗證。     */	public static boolean verify(Document doc, String keystore, String storetype,						String storepass) throws Exception {		FileInputStream fileInputStream = new FileInputStream(keystore);		java.security.KeyStore keyStore = java.security.KeyStore.getInstance(storetype);		keyStore.load(fileInputStream, storepass.toCharArray());		TrustVerifier verifier = new X509TrustVerifier(keyStore);		WSSecurity wSSecurity = new WSSecurity();		MessageValidity[] resa = wSSecurity.verify(doc, verifier, null,null);		if (resa.length > 0)			return resa[0].isValid();		return false;	}   /**    *對XML文檔進(jìn)行加密。必須有JSSE提供者才能加密。    */	public static void encrypt(Document doc, String keystore, String storetype,						String storepass, String alias) throws Exception {		try		{						FileInputStream fileInputStream = new FileInputStream(keystore);		java.security.KeyStore keyStore = java.security.KeyStore.getInstance(storetype);		keyStore.load(fileInputStream, storepass.toCharArray());		X509Certificate cert = (X509Certificate)keyStore.getCertificate(alias);				PublicKey pubk = cert.getPublicKey();		KeyGenerator keyGenerator = KeyGenerator.getInstance("DESede",PROVIDER);				keyGenerator.init(168, new SecureRandom());		SecretKey key = keyGenerator.generateKey();		KeyInfo ki = new KeyInfo();		ki.setCertificate(cert);		WSSecurity wSSecurity = new WSSecurity();		//加密。		wSSecurity.encrypt(doc, key, AlgorithmType.TRIPLEDES, pubk, AlgorithmType.RSA1_5, ki);	}	catch(Exception e)	{		e.printStackTrace();	}	}    /**     *對文檔進(jìn)行解密。     */	public static void decrypt(Document doc, String keystore, String storetype,						String storepass, String alias, String keypass) throws Exception {		FileInputStream fileInputStream = new FileInputStream(keystore);		java.security.KeyStore keyStore = java.security.KeyStore.getInstance(storetype);		keyStore.load(fileInputStream, storepass.toCharArray());		PrivateKey prvk2 = (PrivateKey)keyStore.getKey(alias, keypass.toCharArray());		WSSecurity wSSecurity = new WSSecurity();		//解密。		wSSecurity.decrypt(doc, prvk2, null);		WsUtils.removeEncryptedKey(doc);//從 WS-Security Header中刪除 EncryptedKey 元素	}	public static void removeWSSElements(Document doc) throws Exception {		WsUtils.removeWSSElements(doc);// 刪除WSS相關(guān)的元素。	}		}

WSSHelper類(lèi)中使用了ISNetworks安全提供者,ISNetworks實(shí)現了RSA加密、解密算法。當然,你也可以使用其它的安全提供者,并且可以使用不同的加密算法??梢詮木W(wǎng)絡(luò )上下載ISNetworks相關(guān)包。

WSSHelper中包含了一個(gè)WsUtils類(lèi),它的功能就是從加密后的SOAP消息中刪除一些WS-Security元素,刪除這些元素后的SOAP消息才能被最終的客戶(hù)端或者Web服務(wù)端處理。

服務(wù)器端Handler開(kāi)發(fā)

當請求到達后,服務(wù)端Handler調用handleRequest方法,執行如下過(guò)程:對請求SOAP消息解密‘身份驗證‘刪除WSS元素‘把Document轉換成SOAP消息。 Web服務(wù)端點(diǎn)對請求做出響應后,將調用handleResponse方法,執行如下過(guò)程:對響應的SOAP消息進(jìn)行數字簽名‘加密‘把Document轉換成SOAP消息。


例程8 服務(wù)器端Handler(WSSecurityServerHandler.java)
package com.hellking.study.webservice;...//服務(wù)器端Handlerpublic class WSSecurityServerHandler implements Handler {	 	//密匙庫相關(guān)信息private String keyStoreFile = null;		private String keyStoreType = "JKS";		。。。				public WSSecurityServerHandler()		{			System.out.println("服務(wù)端Handler:構造方法");		}	    /**	     *處理請求	     *流程:解密-->身份驗證-->刪除WSS元素‘把Document轉換成SOAP消息。	     */	     	    public boolean handleRequest(MessageContext messageContext) {	 		        	System.out.println("開(kāi)始處理請求。。。");    	if (messageContext instanceof SOAPMessageContext){			try {	SOAPMessageContext soapMessageContext = (SOAPMessageContext)messageContext;				SOAPMessage soapMessage = soapMessageContext.getMessage();				soapMessage.writeTo(System.out);	Document doc = MessageConveter.convertSoapMessageToDocument(soapMessage);                    //解密				WSSHelper.decrypt(doc, keyStoreFile, keyStoreType,						keyStorePassword, keyAlias, keyEntryPassword);                     //身份驗證				WSSHelper.verify(doc, trustStoreFile, trustStoreType, trustStorePassword);				//刪除WSS元素WSSHelper.removeWSSElements(doc);				soapMessage = MessageConveter.convertDocumentToSOAPMessage(doc);				soapMessageContext.setMessage(soapMessage);			} catch (Exception e){				System.err.println("在處理請求時(shí)發(fā)生了異常: " + e);				e.printStackTrace();				return false;			}		} else {			System.out.println("MessageContext是以下類(lèi)的實(shí)例: " + messageContext.getClass());		}		 System.out.println("處理請求完畢!");        return true;    }        /**     *處理響應     *流程:數字簽名-->加密-->把Document轉換成SOAP消息。     */     public boolean handleResponse(MessageContext messageContext) {        	System.out.println("開(kāi)始處理Web服務(wù)響應。。。");        if (messageContext instanceof SOAPMessageContext){			try {		SOAPMessageContext soapMessageContext = (SOAPMessageContext)messageContext;				SOAPMessage soapMessage = soapMessageContext.getMessage();		Document doc = MessageConveter.convertSoapMessageToDocument(soapMessage);				WSSHelper.sign(doc, keyStoreFile, keyStoreType,						keyStorePassword, keyAlias, keyEntryPassword);				WSSHelper.encrypt(doc, trustStoreFile, trustStoreType,						trustStorePassword, certAlias);				soapMessage = MessageConveter.convertDocumentToSOAPMessage(doc);				soapMessageContext.setMessage(soapMessage);			} catch (Exception e){				System.err.println("在處理響應時(shí)發(fā)生以下錯誤: " + e);				e.printStackTrace();				return false;			}		}			System.out.println("處理響應完畢!");        return true;    }    /**     *初始化,主要是初始化一些相關(guān)參數。     */     public void init(HandlerInfo config) {		System.out.println("WSSecurityServerHandler初始化");		Object param = "";		Map configs = config.getHandlerConfig();		keyStoreFile = (String)configs.get("keyStoreFile");		trustStoreFile = (String)configs.get("trustStoreFile");		…//其它參數初始化	    }	…}

客戶(hù)端Handler開(kāi)發(fā)

客戶(hù)端Handler可以是任何JAX-RPC兼容的Handler處理器。比如AXIS Handler實(shí)現或者SUN 提供的JAX-RPC Handler參考實(shí)現。這里使用后者來(lái)作為客戶(hù)端Handler處理器。

客戶(hù)端Handler和服務(wù)器端Handler原理一樣,但處理過(guò)程完全相反。


例程9 客戶(hù)端Handler(WSSecurityClientHandler.java)
package com.hellking.study.webservice;…//客戶(hù)端Handlerpublic class WSSecurityClientHandler implements Handler {              //密匙庫相關(guān)信息   	    ...			    /**	     *處理請求	     *流程:數字簽名-->加密-->把Document轉換成SOAP消息。	     */	     	    public boolean handleRequest(MessageContext messageContext) {	 		        	System.out.println("開(kāi)始處理請求。。。");           …		       	WSSHelper.sign(doc, keyStoreFile, keyStoreType,				keyStorePassword, keyAlias, keyEntryPassword);			    WSSHelper.encrypt(doc, trustStoreFile, trustStoreType,trustStorePassword, certAlias);				soapMessage = MessageConveter.convertDocumentToSOAPMessage(doc);				soapMessageContext.setMessage(soapMessage);			…		 System.out.println("處理請求完畢!");        return true;    }        /**     *處理響應     *流程:解密-->身份驗證-->刪除WSS元素‘把Document轉換成SOAP消息。     */     public boolean handleResponse(MessageContext messageContext) {        	System.out.println("開(kāi)始處理Web服務(wù)響應。。。");       …			    WSSHelper.decrypt(doc, keyStoreFile, keyStoreType,						keyStorePassword, keyAlias, keyEntryPassword);												WSSHelper.verify(doc, trustStoreFile, trustStoreType, trustStorePassword);				WSSHelper.removeWSSElements(doc);								soapMessage = MessageConveter.convertDocumentToSOAPMessage(doc);								System.out.println("the final message is:");								soapMessage.writeTo(System.out);				soapMessageContext.setMessage(soapMessage);			…					System.out.println("處理響應完畢!");        return true;    }    /**     *初始化,主要是初始化一些相關(guān)參數。     */     public void init(HandlerInfo config) {		…    }	…}

部署服務(wù)器端Handler

為了使用Handler,需要在Web服務(wù)部署描述符中指定使用此Handler。Handler包含的初始化參數也在此描述,如例程10所示。


例程10 服務(wù)器端Handler部署代碼
  <service name="PersonalTaxServicePort" provider="java:RPC">  <parameter name="allowedMethods" value="*"/>  <parameter name="className" value="com.hellking.study.webservice.PersonalTaxService"/>  <parameter name="wsdlTargetNamespace" value="http://hellking.webservices.com/"/>  <parameter name="wsdlServiceElement" value="PersonalTaxService"/>  <parameter name="wsdlServicePort" value="PersonalTaxServicePort"/>  <parameter name="wsdlPortType" value="PersonalTaxService"/>  <requestFlow>   <handler type="java:org.apache.axis.handlers.JAXRPCHandler">    <parameter name="scope" value="session"/>    <parameter name="className"            value="com.hellking.study.webservice.WSSecurityServerHandler"/>    <parameter name="keyStoreFile"            value="K:\\jakarta-tomcat-5.0.16\\server.keystore"/>    <parameter name="trustStoreFile"            value="K:\\jakarta-tomcat-5.0.16\\server.truststore"/>    <parameter name="certAlias" value="clientkey"/>   </handler>  </requestFlow>  <responseFlow>   <handler type="java:org.apache.axis.handlers.JAXRPCHandler">    <parameter name="scope" value="session"/>    <parameter name="className"            value="com.hellking.study.webservice.WSSecurityServerHandler"/>    <parameter name="keyStoreFile"            value="K:\\jakarta-tomcat-5.0.16\\server.keystore"/>    <parameter name="trustStoreFile"            value="K:\\jakarta-tomcat-5.0.16\\server.truststore"/>    <parameter name="certAlias" value="clientkey"/>   </handler>  </responseFlow>  </service>  

requestFlow表示W(wǎng)eb服務(wù)PersonalTaxServicePort的請求處理Handler鏈。這里只有一個(gè)Handler,就是WSSecurityServerHandler。當Web服務(wù)請求到達PersonalTaxServicePort時(shí),WSSecurityServerHandler的handleRequest方法將被自動(dòng)調用。

注意:部署時(shí),請改變Handler相關(guān)參數以和目標的Web服務(wù)一致,比如trustStoreFile的路徑等。

調用測試

這里采用代理的方式來(lái)調用Web服務(wù),先編寫(xiě)一個(gè)Web服務(wù)接口。


例程11 TaxServiceInterface
package com.hellking.study.webservice;…/** *個(gè)人所得稅Web服務(wù)。 */public interface TaxServiceInterface extends Remote{	public double getTax(double salary)throws java.rmi.RemoteException;}

WSSClient客戶(hù)端程序是通過(guò)代理的方式來(lái)訪(fǎng)問(wèn)Web服務(wù)的。由于要使用Handler,所以在訪(fǎng)問(wèn)前通過(guò)registerHandlers()方法注冊了WSSecurityClientHandler,并且初始化了WSSecurityClientHandler的相關(guān)參數。當然,JAX-RPC"參考實(shí)現"還支持在Web服務(wù)客戶(hù)端配置文件中描述Handler信息,這樣就不需要在客戶(hù)端代碼中對Handler進(jìn)行注冊了,你可以參考相關(guān)文檔。


例程12 測試客戶(hù)端程序(WSSClient)
package com.hellking.study.webservice;.../** *調用需要驗證的Web服務(wù) */public class WSSClient{	static	final double salary=5000;    public static void main(String [] args)    {        try {        	//服務(wù)端的url,需要根據情況更改。                        String endpointURL = "http://localhost:8080/axis/services/PersonalTaxServicePort";            String wsdlURL=endpointURL+"?wsdl";            java.net.URL targetURL= new java.net.URL(wsdlURL);            String nameSpaceUri = "http://hellking.webservices.com/";            String svcName = "PersonalTaxService";				    String portName = "PersonalTaxServicePort";            ServiceFactory svcFactory = ServiceFactory.newInstance();            Service svc = svcFactory.createService(targetURL, new QName(nameSpaceUri, svcName));            //cfg表示客戶(hù)端的配置信息。            java.util.HashMap cfg = new java.util.HashMap();						cfg.put("keyStoreFile", "client.keystore");						cfg.put("trustStoreFile", "client.truststore");						cfg.put("certAlias", "changeit");					    Class hdlrClass = com.hellking.study.webservice.WSSecurityClientHandler.class;						java.util.List list = svc.getHandlerRegistry().						               getHandlerChain(new QName(nameSpaceUri, portName));						list.add(new javax.xml.rpc.handler.HandlerInfo(hdlrClass, cfg, null));					     registerHandlers (svc);						 TaxServiceInterface myProxy =                ( TaxServiceInterface) svc.getPort(new QName(nameSpaceUri, portName),                  TaxServiceInterface.class);                     double ret=myProxy.getTax(5000);			System.out.println("使用HTTP協(xié)議來(lái)作為Web服務(wù)的傳輸協(xié)議!");			            System.out.println("已經(jīng)成功調用。請參看服務(wù)端的輸出!");            System.out.println("輸入工資"+salary+"元,應交個(gè)人所得稅:"+ret);        } catch (Exception e) {        	e.printStackTrace();        }    }    //注冊Handler    private static void registerHandlers ( Service service ) 		throws javax.xml.rpc.ServiceException {				java.util.HashMap cfg = new java.util.HashMap();						cfg.put("keyStoreFile", "client.keystore");						cfg.put("trustStoreFile", "client.truststore");						cfg.put("certAlias", "changeit");					/*		* 封裝客戶(hù)端Handler到HandlerInfo 中,然后添加到Handler鏈中。		*/ 	javax.xml.rpc.handler.HandlerInfo info = new javax.xml.rpc.handler.HandlerInfo	(com.hellking.study.webservice.WSSecurityClientHandler.class, cfg, null );		java.util.ArrayList handlerList = new java.util.ArrayList();		handlerList.add(info);				/*		* 獲得Handler注冊		*/		javax.xml.rpc.handler.HandlerRegistry handlerRegistry = service.getHandlerRegistry();				/*		* 把Handler添加到所有的port中。		*/		java.util.Iterator portIterator = service.getPorts();		while ( portIterator.hasNext()) {			Object obj=portIterator.next();		QName portName = (QName) obj;		handlerRegistry.setHandlerChain(portName, handlerList);		}    }    }

注意:由于客戶(hù)端使用了SUN公司提供的"JAX-RPC參考實(shí)現",所以必須把jaxrpc-impl.jar包設置在CLASSPATH環(huán)境變量中,并且不要把axis.jar設置在客戶(hù)端CLASSPATH環(huán)境變量,否則會(huì )出現ClassCastException異常。這是因為axis也是JAX-RPC的實(shí)現,如果它在CLASSPATH環(huán)境變量中,當調用:

ServiceFactory svcFactory = ServiceFactory.newInstance()方法時(shí),就可能初始化一個(gè)axis的ServiceFactory 實(shí)現。

本文源代碼中client目錄下wss-client.bat文件包含了執行WSSClient腳本,修改了部分環(huán)境變量參數后,才能執行。



回頁(yè)首


總結

本文和上一篇文章介紹了幾種不同實(shí)現Web服務(wù)安全的方法,你可以根據具體應用對安全的要求級別采用不同的方式。對于安全級別要求不高的應用,可以采用在Web服務(wù)器上使用基本認證、使用Axis的Handler或者使用Servlet過(guò)濾器來(lái)實(shí)現訪(fǎng)問(wèn)控制;對于安全要求高的應用,可以采用本篇介紹開(kāi)發(fā)的"axis下實(shí)現WS-Security的通用應用框架"來(lái)實(shí)現安全性。



回頁(yè)首


參考資料

本站僅提供存儲服務(wù),所有內容均由用戶(hù)發(fā)布,如發(fā)現有害或侵權內容,請點(diǎn)擊舉報。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
AXIS學(xué)習筆記(四)(建立安全的AXIS服務(wù)下)
在 WebSphere Message Broker V7 中實(shí)現 Web Services Security
JAVA如何從一個(gè).p12或.pfx文件中獲取公鑰和私鑰?
JAVA對數字證書(shū)的常用操作
Java 結合 keytool 實(shí)現非對稱(chēng)加密和解密
Linux openssl 生成證書(shū)的詳解
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導長(cháng)圖 關(guān)注 下載文章
綁定賬號成功
后續可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服

欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久