CXF全接触 --- WS-Security的实现 (转)

转自 http://blog.csdn.net/kunshan_shenbin/article/details/3813000

 

我们使用Apache WSS4J这个WS-Security的开源实现,相关内容请参阅:

 

http://ws.apache.org/wss4j/

WSS4J支持如下几种模式:

XML Security

    XML Signature

    XML Encryption

Tokens

    Username Tokens

    Timestamps

    SAML Tokens

这里将使用Timestamps+Encryption+Signature组合。

 

首先需要生成服务端及客户端密钥文件:

generateKeyPair.bat

 

rem @echo off
echo alias %1
echo keypass %2
echo keystoreName %3
echo KeyStorePass %4
echo keyName %5

echo keyName %5
keytool -genkey -alias %1 -keypass %2 -keystore %3 -storepass %4  -dname "cn=%1" -keyalg RSA
keytool -selfcert -alias %1 -keystore %3 -storepass %4 -keypass %2
keytool -export -alias %1 -file %5 -keystore %3 -storepass %4


generateServerKey.bat

call generateKeyPair.bat apmserver apmserverpass serverStore.jks keystorePass serverKey.rsa
call generateKeyPair.bat apmclient apmclientpass clientStore.jks keystorePass clientKey.rsa
keytool -import -alias apmserver -file serverKey.rsa -keystore clientStore.jks -storepass keystorePass -noprompt
keytool -import -alias apmclient -file clientKey.rsa -keystore serverStore.jks -storepass keystorePass -noprompt


执行generateServerKey.bat批处理,生成clientStore.jks及serverStore.jks文件。

生成的密钥文件中包含的信息:

服务端 账户:apmserver / apmserverpass

客户端 账户:apmclient / apmclientpass

 

如下图所示建立工程:

工程视图

 所使用到的Jar包一览

jar包一览

 PasswordHandler.java

package com.cecltd.security;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.UnsupportedCallbackException;

import org.apache.ws.security.WSPasswordCallback;

public class PasswordHandler implements CallbackHandler {

	private Map<String, String> passwords = new HashMap<String, String>();

	public PasswordHandler() {
		passwords.put("apmserver", "apmserverpass");
        passwords.put("apmclient", "apmclientpass");
	}

	public void handle(Callback[] callbacks) throws IOException,
			UnsupportedCallbackException {
		WSPasswordCallback pc = (WSPasswordCallback) callbacks[0];
		String id = pc.getIdentifer();
		pc.setPassword((String) passwords.get(id));
	}
}


 

SayHiSrvcImpl.java

package com.cecltd.service.impl;

import com.cecltd.service.SayHiSrvc;

public class SayHiSrvcImpl implements SayHiSrvc {

	public String sayHi(String username) {
		
		return "Hi, " + username + "!";
	}
}


 

SayHiSrvc.java

package com.cecltd.service;

import javax.jws.WebService;

@WebService
public interface SayHiSrvc {

	public String sayHi(String username);
}


 

server_insecurity_enc.properties

org.apache.ws.security.crypto.provider=org.apache.ws.security.components.crypto.Merlin
org.apache.ws.security.crypto.merlin.keystore.type=jks
org.apache.ws.security.crypto.merlin.keystore.password=keystorePass
org.apache.ws.security.crypto.merlin.alias.password=apmserverpass
org.apache.ws.security.crypto.merlin.keystore.alias=apmserver
org.apache.ws.security.crypto.merlin.file=serverStore.jks


 

server_insecurity_sign.properties

org.apache.ws.security.crypto.provider=org.apache.ws.security.components.crypto.Merlin
org.apache.ws.security.crypto.merlin.keystore.type=jks
org.apache.ws.security.crypto.merlin.keystore.password=keystorePass
#org.apache.ws.security.crypto.merlin.alias.password=apmserverpass
org.apache.ws.security.crypto.merlin.keystore.alias=apmserver
org.apache.ws.security.crypto.merlin.file=serverStore.jks


 

server_outsecurity_enc.properties

org.apache.ws.security.crypto.provider=org.apache.ws.security.components.crypto.Merlin
org.apache.ws.security.crypto.merlin.keystore.type=jks
org.apache.ws.security.crypto.merlin.keystore.password=keystorePass
#org.apache.ws.security.crypto.merlin.alias.password=apmserverpass
#org.apache.ws.security.crypto.merlin.keystore.alias=apmserver
org.apache.ws.security.crypto.merlin.file=serverStore.jks


 

SayHiServiceTest.java

package com.service.test;

import static org.junit.Assert.*;
import org.junit.BeforeClass;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.cecltd.service.SayHiSrvc;

public class SayHiServiceTest {

	private static SayHiSrvc sayHiSrvc;
	
	@BeforeClass
	public static void setUp() {
		
		ApplicationContext context = new ClassPathXmlApplicationContext(new String[] { "applicationContext.xml" });
		sayHiSrvc = (SayHiSrvc)context.getBean("SayHiSrvc");
	}
	
	@Test
	public void testSayHi() {
	
		assertEquals("Hi, ShenBin!", sayHiSrvc.sayHi("ShenBin"));
	}
}


 

applicationContext.xml

<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:jaxws="http://cxf.apache.org/jaxws"
	xsi:schemaLocation="
    http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
	http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd">

	<bean id="SayHiSrvc" class="com.cecltd.service.SayHiSrvc" factory-bean="SayHiSrvcFactory" factory-method="create"/>

	<bean id="SayHiSrvcFactory" class="org.apache.cxf.jaxws.JaxWsProxyFactoryBean">
		<property name="serviceClass" value="com.cecltd.service.SayHiSrvc" />
		<property name="address" value="${host.url}/SayHiSrvc" />
		<property name="outInterceptors">
			<list>
				<bean class="org.apache.cxf.binding.soap.saaj.SAAJOutInterceptor" />
				<ref bean="wss4jOutConfiguration" />
			</list>
		</property>
		<property name="inInterceptors">
			<list>
				<bean class="org.apache.cxf.binding.soap.saaj.SAAJInInterceptor" />
				<ref bean="wss4jInConfiguration" />
			</list>
		</property>
	</bean>
	
	<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
		<property name="locations">
			<list>
				<value>serverhost.properties</value>
			</list>
		</property>
	</bean>
	
	<bean id="wss4jOutConfiguration" class="org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor">
		<property name="properties">
			<map>
				<entry key="action" value="Timestamp Encrypt Signature" />
				<entry key="user" value="apmclient" />
				<entry key="encryptionUser" value="apmserver" />
				<entry key="signaturePropFile" value="outsecurity_sign.properties" />
				<entry key="signatureKeyIdentifier" value="IssuerSerial" />
				<entry key="encryptionPropFile" value="outsecurity_enc.properties" />
				<entry>
					<key>
						<value>passwordCallbackRef</value>
					</key>
					<ref bean="passwordCallback" />
				</entry>
			</map>
		</property>
	</bean>
	
	<bean id="wss4jInConfiguration" class="org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor">
		<property name="properties">
			<map>
				<entry key="action" value="Timestamp Encrypt Signature" />
				<entry key="user" value="apmclient" />
				<entry key="decryptionPropFile" value="insecurity_enc.properties" />
				<entry key="enableSignatureConfirmation" value="true" />
				<entry key="signaturePropFile" value="outsecurity_sign.properties" />
				<entry key="signatureKeyIdentifier" value="IssuerSerial" />
				<entry>
					<key>
						<value>passwordCallbackRef</value>
					</key>
					<ref bean="passwordCallback" />
				</entry>
			</map>
		</property>
	</bean>
	
	<bean id="passwordCallback" class="com.cecltd.security.PasswordHandler"/>

</beans>


 

insecurity_enc.properties

org.apache.ws.security.crypto.provider=org.apache.ws.security.components.crypto.Merlin
org.apache.ws.security.crypto.merlin.keystore.type=jks
org.apache.ws.security.crypto.merlin.keystore.password=keystorePass
org.apache.ws.security.crypto.merlin.alias.password=apmclientpass
org.apache.ws.security.crypto.merlin.keystore.alias=apmclient
org.apache.ws.security.crypto.merlin.file=clientStore.jks


 

outsecurity_enc.properties

org.apache.ws.security.crypto.provider=org.apache.ws.security.components.crypto.Merlin
org.apache.ws.security.crypto.merlin.keystore.type=jks
org.apache.ws.security.crypto.merlin.keystore.password=keystorePass
org.apache.ws.security.crypto.merlin.alias.password=apmclientpass
org.apache.ws.security.crypto.merlin.keystore.alias=apmclient
org.apache.ws.security.crypto.merlin.file=clientStore.jks


 

outsecurity_sign.properties

org.apache.ws.security.crypto.provider=org.apache.ws.security.components.crypto.Merlin
org.apache.ws.security.crypto.merlin.keystore.type=jks
org.apache.ws.security.crypto.merlin.keystore.password=keystorePass
org.apache.ws.security.crypto.merlin.alias.password=apmclientpass
org.apache.ws.security.crypto.merlin.keystore.alias=apmclient
org.apache.ws.security.crypto.merlin.file=clientStore.jks


 

serverhost.properties

host.url=http://127.0.0.1:8080/J6CxfSrvc/services


 

cxf-config.xml

<beans xmlns="http://www.springframework.org/schema/beans" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:jaxws="http://cxf.apache.org/jaxws" 
    xsi:schemaLocation=" 
    http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd 
    http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd"> 

    <import resource="classpath:META-INF/cxf/cxf.xml" /> 
    <import resource="classpath:META-INF/cxf/cxf-extension-soap.xml" /> 
    <import resource="classpath:META-INF/cxf/cxf-servlet.xml" /> 

    <jaxws:endpoint id="SayHiSrvc" implementor="com.cecltd.service.impl.SayHiSrvcImpl" address="/SayHiSrvc"> 
        <jaxws:inInterceptors>
			<bean class="org.apache.cxf.interceptor.LoggingInInterceptor"/> 
			<bean class="org.apache.cxf.binding.soap.saaj.SAAJInInterceptor"/>
			<ref bean="wss4jInConfiguration"/>
		</jaxws:inInterceptors>
		<jaxws:outInterceptors>
			<bean class="org.apache.cxf.interceptor.LoggingOutInterceptor"/>
			<bean class="org.apache.cxf.binding.soap.saaj.SAAJOutInterceptor"/>
			<ref bean="wss4jOutConfiguration"/>
		</jaxws:outInterceptors>
    </jaxws:endpoint> 

    	<bean id="wss4jInConfiguration" class="org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor">
		<property name="properties">
			<map>
				<entry key="action" value="Timestamp Encrypt Signature"/>
				<entry key="decryptionPropFile" value="server_insecurity_enc.properties"/>
				<entry key="signaturePropFile" value="server_insecurity_sign.properties"/>
				<entry>
					<key>
						<value>passwordCallbackRef</value>
					</key>
					<ref bean="passwordCallback"/>
				</entry>
			</map>
		</property>
	</bean>
	
	<bean id="wss4jOutConfiguration" class="org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor">
		<property name="properties">
			<map>
				<entry key="action" value="Timestamp Encrypt Signature"/>
				<entry key="user" value="apmserver" />
				<entry key="encryptionUser" value="apmclient" />
				<entry key="encryptionPropFile" value="server_outsecurity_enc.properties"/>
				<entry key="signaturePropFile" value="server_insecurity_sign.properties"/>
				<entry>
					<key>
						<value>passwordCallbackRef</value>
					</key>
					<ref bean="passwordCallback"/>
				</entry>
			</map>
		</property>
	</bean>
     
    <bean id="passwordCallback" class="com.cecltd.security.PasswordHandler"/> 
     
</beans>


 

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
	http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">

	 <context-param> 
        <param-name>contextConfigLocation</param-name> 
        <param-value>WEB-INF/cxf-config.xml</param-value> 
    </context-param> 

    <listener> 
        <listener-class> 
            org.springframework.web.context.ContextLoaderListener 
        </listener-class> 
    </listener> 

	<servlet>
		<servlet-name>CXFServlet</servlet-name>
		<servlet-class>
			org.apache.cxf.transport.servlet.CXFServlet
		</servlet-class>
		<load-on-startup>1</load-on-startup>
	</servlet>

	<servlet-mapping>
		<servlet-name>CXFServlet</servlet-name>
		<url-pattern>/services/*</url-pattern>
	</servlet-mapping>

</web-app>


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值