WebService CXF学习(高级篇3):WS-Security
2011-09-28 10:02
155 查看
这一节我们来探讨一下WebService安全问题,如果所有系统都运行在一个封闭的局域网内,那么可以不考虑网络攻击,拒绝服务,消息篡改,窃取等问题。但通常情况都接入互联网,那么我就得考虑信息安全问题,像前面那样直接将消息裸传,肯定不行。那么,我们就得给消息加密。CXF可以结合WSS4J来对消息安全进行管理,可以使用令牌,X.509认证对消息头或内容进行加密。这节我只对令牌加密做一个简单的描述,我们还以Demo的形式来讲解一下。
这个Demo是在CXF+Spring+Hibernate的基础修改而成。在这里我只针对修改的东西进行讲解。
Java代码
<?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"
xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.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="service"
implementor="com.itdcl.service.ServiceImpl" address="/Service">
<jaxws:inInterceptors>
<bean
class="org.apache.cxf.interceptor.LoggingInInterceptor" />
<bean
class="org.apache.cxf.binding.soap.saaj.SAAJInInterceptor" />
<bean
class="org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor">
<constructor-arg>
<map>
<entry key="action" value="UsernameToken" />
<entry key="passwordType"
value="PasswordText" />
<entry key="user" value="cxfServer" />
<entry key="passwordCallbackRef">
<ref bean="serverPasswordCallback" />
</entry>
</map>
</constructor-arg>
</bean>
</jaxws:inInterceptors>
</jaxws:endpoint>
<bean id="serverPasswordCallback"
class="com.itdcl.ws.ServerPasswordCallback" />
</beans>
action:UsernameToken指使用用户令牌
passwordType:PasswordText指密码加密策略,这里直接文本
user:cxfServer指别名
passwordCallBackRef:serverPasswordCallback指消息验证
消息验证类:
Java代码
package com.itdcl.ws;
import java.io.IOException;
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 ServerPasswordCallback implements CallbackHandler {
public void handle(Callback[] callbacks) throws IOException,
UnsupportedCallbackException {
WSPasswordCallback pc = (WSPasswordCallback) callbacks[0];
String pw = pc.getPassword();
String idf = pc.getIdentifier();
System.out.println("password:"+pw);
System.out.println("identifier:"+idf);
if (pw.equals("josen") && idf.equals("admin")) {
// 验证通过
} else {
throw new SecurityException("验证失败");
}
}
}
消息验证类通过实现CallbackHandler接口,实现handle方法来进行用户认证。
那么,客户端又怎样来验证消息是否确呢。
Java代码
<?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"
xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd">
<jaxws:client id="service"
address="http://localhost:9999/cxf/Service"
serviceClass="com.itdcl.service.IService">
<jaxws:outInterceptors>
<bean
class="org.apache.cxf.interceptor.LoggingOutInterceptor" />
<bean
class="org.apache.cxf.binding.soap.saaj.SAAJOutInterceptor" />
<bean
class="org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor">
<constructor-arg>
<map>
<entry key="action" value="UsernameToken" />
<entry key="passwordType"
value="PasswordText" />
<entry key="user" value="cxfClient" />
<entry key="passwordCallbackRef">
<ref bean="clientPasswordCallback" />
</entry>
</map>
</constructor-arg>
</bean>
</jaxws:outInterceptors>
</jaxws:client>
<bean id="clientPasswordCallback"
class="com.itdcl.ws.ClientPasswordCallback" />
</beans>
客户端在发送SOAP时对消息对认证,策略跟服务端一样。但是认证类有所区别:
Java代码
package com.itdcl.ws;
import java.io.IOException;
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 ClientPasswordCallback implements CallbackHandler {
public void handle(Callback[] callbacks) throws IOException,
UnsupportedCallbackException {
for(int i=0;i<callbacks.length;i++)
{
WSPasswordCallback pc = (WSPasswordCallback)callbacks[i];
pc.setPassword("josen");
pc.setIdentifier("admin");
}
}
}
客户端在发送消息,设置好用户名和密码。服务端用相应的用户名和密码进行验证。
令牌验证就如此简单。
这个Demo是在CXF+Spring+Hibernate的基础修改而成。在这里我只针对修改的东西进行讲解。
Java代码
<?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"
xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.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="service"
implementor="com.itdcl.service.ServiceImpl" address="/Service">
<jaxws:inInterceptors>
<bean
class="org.apache.cxf.interceptor.LoggingInInterceptor" />
<bean
class="org.apache.cxf.binding.soap.saaj.SAAJInInterceptor" />
<bean
class="org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor">
<constructor-arg>
<map>
<entry key="action" value="UsernameToken" />
<entry key="passwordType"
value="PasswordText" />
<entry key="user" value="cxfServer" />
<entry key="passwordCallbackRef">
<ref bean="serverPasswordCallback" />
</entry>
</map>
</constructor-arg>
</bean>
</jaxws:inInterceptors>
</jaxws:endpoint>
<bean id="serverPasswordCallback"
class="com.itdcl.ws.ServerPasswordCallback" />
</beans>
<?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" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.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="service" implementor="com.itdcl.service.ServiceImpl" address="/Service"> <jaxws:inInterceptors> <bean class="org.apache.cxf.interceptor.LoggingInInterceptor" /> <bean class="org.apache.cxf.binding.soap.saaj.SAAJInInterceptor" /> <bean class="org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor"> <constructor-arg> <map> <entry key="action" value="UsernameToken" /> <entry key="passwordType" value="PasswordText" /> <entry key="user" value="cxfServer" /> <entry key="passwordCallbackRef"> <ref bean="serverPasswordCallback" /> </entry> </map> </constructor-arg> </bean> </jaxws:inInterceptors> </jaxws:endpoint> <bean id="serverPasswordCallback" class="com.itdcl.ws.ServerPasswordCallback" /> </beans>
action:UsernameToken指使用用户令牌
passwordType:PasswordText指密码加密策略,这里直接文本
user:cxfServer指别名
passwordCallBackRef:serverPasswordCallback指消息验证
消息验证类:
Java代码
package com.itdcl.ws;
import java.io.IOException;
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 ServerPasswordCallback implements CallbackHandler {
public void handle(Callback[] callbacks) throws IOException,
UnsupportedCallbackException {
WSPasswordCallback pc = (WSPasswordCallback) callbacks[0];
String pw = pc.getPassword();
String idf = pc.getIdentifier();
System.out.println("password:"+pw);
System.out.println("identifier:"+idf);
if (pw.equals("josen") && idf.equals("admin")) {
// 验证通过
} else {
throw new SecurityException("验证失败");
}
}
}
package com.itdcl.ws; import java.io.IOException; 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 ServerPasswordCallback implements CallbackHandler { public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException { WSPasswordCallback pc = (WSPasswordCallback) callbacks[0]; String pw = pc.getPassword(); String idf = pc.getIdentifier(); System.out.println("password:"+pw); System.out.println("identifier:"+idf); if (pw.equals("josen") && idf.equals("admin")) { // 验证通过 } else { throw new SecurityException("验证失败"); } } }
消息验证类通过实现CallbackHandler接口,实现handle方法来进行用户认证。
那么,客户端又怎样来验证消息是否确呢。
Java代码
<?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"
xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd">
<jaxws:client id="service"
address="http://localhost:9999/cxf/Service"
serviceClass="com.itdcl.service.IService">
<jaxws:outInterceptors>
<bean
class="org.apache.cxf.interceptor.LoggingOutInterceptor" />
<bean
class="org.apache.cxf.binding.soap.saaj.SAAJOutInterceptor" />
<bean
class="org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor">
<constructor-arg>
<map>
<entry key="action" value="UsernameToken" />
<entry key="passwordType"
value="PasswordText" />
<entry key="user" value="cxfClient" />
<entry key="passwordCallbackRef">
<ref bean="clientPasswordCallback" />
</entry>
</map>
</constructor-arg>
</bean>
</jaxws:outInterceptors>
</jaxws:client>
<bean id="clientPasswordCallback"
class="com.itdcl.ws.ClientPasswordCallback" />
</beans>
<?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" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd"> <jaxws:client id="service" address="http://localhost:9999/cxf/Service" serviceClass="com.itdcl.service.IService"> <jaxws:outInterceptors> <bean class="org.apache.cxf.interceptor.LoggingOutInterceptor" /> <bean class="org.apache.cxf.binding.soap.saaj.SAAJOutInterceptor" /> <bean class="org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor"> <constructor-arg> <map> <entry key="action" value="UsernameToken" /> <entry key="passwordType" value="PasswordText" /> <entry key="user" value="cxfClient" /> <entry key="passwordCallbackRef"> <ref bean="clientPasswordCallback" /> </entry> </map> </constructor-arg> </bean> </jaxws:outInterceptors> </jaxws:client> <bean id="clientPasswordCallback" class="com.itdcl.ws.ClientPasswordCallback" /> </beans>
客户端在发送SOAP时对消息对认证,策略跟服务端一样。但是认证类有所区别:
Java代码
package com.itdcl.ws;
import java.io.IOException;
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 ClientPasswordCallback implements CallbackHandler {
public void handle(Callback[] callbacks) throws IOException,
UnsupportedCallbackException {
for(int i=0;i<callbacks.length;i++)
{
WSPasswordCallback pc = (WSPasswordCallback)callbacks[i];
pc.setPassword("josen");
pc.setIdentifier("admin");
}
}
}
package com.itdcl.ws; import java.io.IOException; 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 ClientPasswordCallback implements CallbackHandler { public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException { for(int i=0;i<callbacks.length;i++) { WSPasswordCallback pc = (WSPasswordCallback)callbacks[i]; pc.setPassword("josen"); pc.setIdentifier("admin"); } } }
客户端在发送消息,设置好用户名和密码。服务端用相应的用户名和密码进行验证。
令牌验证就如此简单。
相关文章推荐
- WebService CXF学习(高级篇3):WS-Security
- 浅谈spingmvc 整合CXF +ws-security 实现webservice安全验证
- WebService CXF学习(高级篇1):整合Spring框架
- WebService CXF学习(高级篇1):整合Spring框架
- WebService CXF学习(高级篇2):CXF+Spring+Hibernate
- WebService CXF学习(高级篇2):CXF+Spring+Hibernate
- WebService学习整理-JDK的wsimport命令和cxf的wsdl2java命令的区别和使用
- webservice cxf+spring+WS-security配置示例
- 浅谈spingmvc 整合CXF +ws-security 实现webservice安全验证
- CXF学习二(WS-Security)
- WebService CXF学习 1
- Web Service学习-CXF与Spring整合为JavaEE应用发布WebService(三)
- WebService CXF学习:整合Spring框架
- WebService学习总结(四)——使用spring+CXF开发WebService(服务端)
- 【转载】WebService —— JAX-WS 与 CXF
- 使用CXF框架学习搭建WebService(三)
- CXF学习创建WebService
- WebService学习笔记-CXF添加自定义拦截器
- WebService学习——利用Eclipse生成JAX-WS WebService客户端
- WebService学习之四:关于JAX-WS 注释