`

SOAP WebService实现WS-Security用户身份认证时间戳验证

 
阅读更多

ApacheCXF框架API实现了WS-Security协议,其中包括xml签名、用户令牌、时间戳等;

 

实现目标:在SOAP WebService的服务端实现客户端身份认证、时间戳形式的安全机制;(密钥加密及签名方式认证待续)

运行环境:apache-cxf-3.1.6、jdk1.7、tomcat7.0.68

 

cxf框架和spring高度集成,示例安全机制服务端基于spring框架,客户端调用可以使用或不使用spring框架;

对于客户端用户密码验证主要通过cxf框架的WSS4J拦截器实现,base64加密、解密过程本身由框架实现,用户只需要在服务端和客户端的拦截器实现方法中设置原始的用户名密码即可。

客户端发出请求前(请求出)拦截设置加密密码,服务端接收(请求入)后拦截解密验证密码。

 

服务端web.xml配置:

<?xml version="1.0" encoding="UTF-8"?>
<web-app 
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
	xmlns="http://java.sun.com/xml/ns/javaee" 
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" 
	id="WebApp_ID" 
	version="3.0">
  <display-name>cxfjaxwssecurityserver1</display-name>  
	<context-param>
	      <param-name>contextConfigLocation</param-name>
	      <param-value>WEB-INF/beans.xml</param-value>
	</context-param>  
    <listener>
        <listener-class>                        org.springframework.web.context.ContextLoaderListener
        </listener-class>
    </listener>
      <servlet>
        <description>Apache CXF Endpoint</description>
        <display-name>cxf</display-name>
        <servlet-name>cxf</servlet-name>
        <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>cxf</servlet-name>
        <url-pattern>/services/*</url-pattern>
    </servlet-mapping>
    <session-config>
        <session-timeout>60</session-timeout>
    </session-config>  

</web-app>

 

服务端spring bean配置:

<?xml version="1.0" encoding="UTF-8"?>
<beans 
	xmlns="http://www.springframework.org/schema/beans" 
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
	xmlns:jaxws="http://cxf.apache.org/jaxws" 
	xmlns:soap="http://cxf.apache.org/bindings/soap" 
	xmlns:util="http://www.springframework.org/schema/util"
	xsi:schemaLocation=" 
	http://www.springframework.org/schema/beans 
	http://www.springframework.org/schema/beans/spring-beans.xsd 
	http://cxf.apache.org/bindings/soap 
	http://cxf.apache.org/schemas/configuration/soap.xsd 
	http://cxf.apache.org/jaxws 
	http://cxf.apache.org/schemas/jaxws.xsd 
	http://www.springframework.org/schema/util 
    http://www.springframework.org/schema/util/spring-util.xsd">	
	
   	
	<import resource="classpath:META-INF/cxf/cxf.xml"/>
   	<import resource="classpath*:META-INF/cxf/cxf-extension-*.xml" />  
    <import resource="classpath:META-INF/cxf/cxf-servlet.xml"/>     
  
	<bean id="logIn" class="org.apache.cxf.interceptor.LoggingInInterceptor" />
	<bean id="logOut" class="org.apache.cxf.interceptor.LoggingOutInterceptor" />
	<bean id="saajIn" class="org.apache.cxf.binding.soap.saaj.SAAJInInterceptor" />
	
	<bean id="mypasswdcallback" class="cxf.jaxws.basic.server.PasswdCallback"/>
	
	<bean id="wss4jin" class="org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor">
		<constructor-arg>
			<map>
				<entry key="action" value="UsernameToken Timestamp"></entry>
				<entry key="passwordType" value="PasswordDigest"/>
				<entry key="passwordCallbackRef" >
					<ref  bean="mypasswdcallback"/>
				</entry>
			</map>			
		</constructor-arg>		
	</bean>
    
    <jaxws:endpoint id="bookinfoservice" address="/bookinfo" implementor="cxf.jaxws.basic.server.BookServiceImpl" > 		
		<jaxws:outInterceptors>
			<ref bean="logOut"/>			
		</jaxws:outInterceptors>
		
		<jaxws:inInterceptors>		
			<ref bean="logIn"/>
			<ref bean="saajIn"/>
			<ref bean="wss4jin"/>		
  	 	</jaxws:inInterceptors>
    
    </jaxws:endpoint>
  

</beans>

 服务端拦截器:

public class PasswdCallback implements CallbackHandler {

	@Override
	public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
		
		
		WSPasswordCallback pc = (WSPasswordCallback ) callbacks[0];
		
		if(pc.getIdentifier().equals("administrator")){
			pc.setPassword("merrick");
		}else{
			System.err.println("Password verified failed.");
		}
		

	}

}

 Webservice接口类、实现类、实体类:

@WebService( name="BookService", portName="BookServicePort")
public interface BookService {
	
	@WebMethod
	public String getOneBookInfo(DTOBean param);
	
	@WebMethod BookEntity getBookinfoEntity(DTOBean param);

}



public class BookServiceImpl implements BookService {
	
	@Resource
    WebServiceContext wsContext;

	@Override
	public String getOneBookInfo(DTOBean param) {

		String bookinfo = "<<A Tale of two citiest>>,2001,English";
		System.out.println("---Invoking getOneBookInfo, DTOBean: "+ param.getId() + "," + param.getName());
		
		return bookinfo;
	}

	@Override
	public BookEntity getBookinfoEntity(DTOBean param) {
		
		BookEntity be = new BookEntity();

		be.setAuthor("Mark Twen");
		be.setFirstpub("1778");
		be.setName("Tom's house");
		
		System.out.println("---Invoking getBookinfoEntity, DTOBean: "+ param.getId() + "," + param.getName());
		
		
		return be;
	}



}

 

public class BookEntity {
	
	String name;
	String author;
	String firstpub;
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getAuthor() {
		return author;
	}
	public void setAuthor(String author) {
		this.author = author;
	}
	public String getFirstpub() {
		return firstpub;
	}
	public void setFirstpub(String firstpub) {
		this.firstpub = firstpub;
	}

}

 客户端拦截器:

public class ClientPasswdCallback implements CallbackHandler {
	
	private Map<String,String> passwds = new HashMap<String,String>();
	
	public ClientPasswdCallback() {
		passwds.put("administrator", "merrick");
		
	}

	@Override
	public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {//交给wss4j API去加密(ws-security的实现,用户令牌验证)


		for (int i = 0; i < callbacks.length; i++) {
			WSPasswordCallback wsp = (WSPasswordCallback)callbacks[i];
			
			String pas = passwds.get(wsp.getIdentifier());
			
			if(pas!=null){
				wsp.setPassword(pas);
				return;
			}
		}
		

	}

}

WebService 客户端调用(无框架方式、spring方式)(客户端略):

(webservice客户端可根据WebService的wsdl url,采用cxf的wsdl2java工具生成)

	public static void clientwith_UserTokenAuth() throws Throwable {//success
/**
 * 带用户令牌验证的客户端
 * Spring配置
 * **/
		ApplicationContext  context = new ClassPathXmlApplicationContext(
                new String[] { "autoclient/test/client2.xml" });
		
	//	BookServiceImplService sv = new BookServiceImplService(u);
		BookService client = (BookService) context.getBean("client");
		
		DtoBean b = new DtoBean();
		b.setId(1);
		b.setName("a");	 
	//	
		
		String response = client.getOneBookInfo(b);
		
        System.out.println("Response: " + response);
        
        BookEntity response2 = client.getBookinfoEntity(b);
        
        System.out.println("Response: " + response2.getAuthor() + ", " + response2.getName() +", "+ response2.getFirstpub());		
	}
	/***无框架方式*/
	public static void clientwith_UserTokenAuth_withoutSpring() throws Throwable {//success
		Map<String, Object> outProps = new HashMap<String, Object>();
		
		outProps.put(WSHandlerConstants.ACTION, WSHandlerConstants.USERNAME_TOKEN +" "+ WSHandlerConstants.TIMESTAMP);//令牌+时间戳
		outProps.put(WSHandlerConstants.USER,	"administrator" );
		outProps.put(WSHandlerConstants.PASSWORD_TYPE,	WSConstants.PW_DIGEST );
		outProps.put(WSHandlerConstants.PW_CALLBACK_CLASS, "autoclient.test.ClientPasswdCallback");		
		
		JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
		factory.setServiceClass(cxfclient.jaxws.auto.BookService.class);
		// 设置ws访问地址
		factory.setAddress("http://localhost:8080/cxfjaxwssecurityserver1/services/bookinfo");
		factory.getOutInterceptors().add(new WSS4JOutInterceptor(outProps));
		//addAll(list);
		cxfclient.jaxws.auto.BookService service = (cxfclient.jaxws.auto.BookService) factory.create();
		DtoBean b = new DtoBean();
		b.setId(1);
		b.setName("a");	 
		String response = service.getOneBookInfo(b);		
		System.out.println(response);
	}

 

客户端安全机制带框架方式调用,spring配置:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
	xmlns:jaxws="http://cxf.apache.org/jaxws"
	xmlns:soap="http://cxf.apache.org/bindings/soap" 
	xsi:schemaLocation="
             http://www.springframework.org/schema/beans
             http://www.springframework.org/schema/beans/spring-beans.xsd
           	http://cxf.apache.org/bindings/soap 
			http://cxf.apache.org/schemas/configuration/soap.xsd 
             http://cxf.apache.org/jaxws 
             http://cxf.apache.org/schemas/jaxws.xsd">	

	
	<bean id="logIn"  class="org.apache.cxf.interceptor.LoggingInInterceptor" />
	<bean id="logOut" class="org.apache.cxf.interceptor.LoggingOutInterceptor" />
	<bean id="saajOut" class="org.apache.cxf.binding.soap.saaj.SAAJOutInterceptor" />
	
	<bean id="wss4jout" class="org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor">
		<constructor-arg>
			<map>
				<entry key="action" value="UsernameToken Timestamp" />
				<entry key="passwordType" value="PasswordDigest" />
				<entry key="user" value="administrator" />
				<entry key="passwordCallbackClass" value="autoclient.test.ClientPasswdCallback"/>			
			</map>		
		</constructor-arg>
	</bean>

	<jaxws:client id="client" 
		serviceClass="cxfclient.jaxws.auto.BookService" 
		address="http://localhost:8080/cxfjaxwssecurityserver1/services/bookinfo">
	
		<jaxws:inInterceptors>		
			<ref bean="logIn"/>
		</jaxws:inInterceptors>
	
		<jaxws:outInterceptors>
			<ref bean="logOut"/>	
			<ref bean="saajOut"/>	
			<ref bean="wss4jout"/>		
		</jaxws:outInterceptors>
	
	</jaxws:client>    
    
</beans>

 

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics