WebService–安全问题
1、Ws安全框架(cxf)的介绍
①、ws安全问题
需要使用cxf安全框架首先需要引用的maven依赖
(1)需要引用的maven依赖
org.apache.cxf
cxf-rt-frontend-jaxws
3.0.5
—maven核心包
org.apache.cxf
cxf-rt-transports-http
3.0.5
--maven核心包
org.apache.cxf
cxf-rt-ws-security
3.0.5
----关于安全的包
org.apache.ws.security
wss4j
1.5.2
----关于安全的包
org.apache.cxf
cxf-rt-frontend-jaxrs
3.0.5 (jaxrs)关于rest风格发布的框架包
org.apache.cxf
cxf-rt-transports-http-jetty
3.0.5
(jaxrs)关于rest风格发布的框架包
(1)、用户身份认证(签名)
Cxf的用户名令牌(cxf的安全框架)
—配置签名与安全令牌
首先需要了解WSHandlerConstants这个类,这个类中包含了cxf存储安全框架配置信息滴常量
步骤:
步骤一:在发布的ws接口服务上加入安全拦截器
服务器端拦截器
**public class WSS4JInInterceptor extends AbstractWSS4JInterceptor {
/**
* This configuration tag specifies the default attribute name where the roles are present
* The default is “http://schemas.xmlsoap.org/ws/2005/05/identity/claims/role“.
*/
public static final String SAML_ROLE_ATTRIBUTENAME_DEFAULT =
“http://schemas.xmlsoap.org/ws/2005/05/identity/claims/role“;
public static final String TIMESTAMP_RESULT = "wss4j.timestamp.result";
public static final String SIGNATURE_RESULT = "wss4j.signature.result";
public static final String PRINCIPAL_RESULT = "wss4j.principal.result";
public static final String PROCESSOR_MAP = "wss4j.processor.map";
public static final String VALIDATOR_MAP = "wss4j.validator.map";**
客户端拦截器
public class WSS4JOutInterceptor extends AbstractWSS4JInterceptor {
/**
* Property name for a map of action IDs ({@link Integer}) to action
* class names. Values can be either {@link Class}) or Objects
- * implementing {@link Action}.
*/
public static final String WSS4J_ACTION_MAP = "wss4j.action.map";
private static final Logger LOG = LogUtils
.getL7dLogger(WSS4JOutInterceptor.class);
private WSS4JOutInterceptorInternal ending;
private SAAJOutInterceptor saajOut = new SAAJOutInterceptor();
private boolean mtomEnabled;
具体配置,在Spring—》applicationContext.xml中配置安全拦截器
1、配置拦截器的工作方式“action”(Spring)
<jaxws:endpoint address="/test" implementorClass="com.a.service.TestServiceInf">
<jaxws:inInterceptors>
<bean class="org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor">
<constructor-arg>
<map>
<entry key="action" value="UsernameToken">entry>
<entry key="passwordType" value="PasswordText">entry>
<entry key="passwordCallbackRef">
<bean class="com.a.util.MyPasswordCallback"/>
entry>
map>
constructor-arg>
bean>
jaxws:inInterceptors>
<jaxws:implementor>
<bean class="com.a.service.TestServiceImp">bean>
jaxws:implementor>
jaxws:endpoint>
2、如果是令牌拦截器,配置密码类型passwordType(参数的写法要与 WSHandlerConstants完全一致)
3、配置用户密码信息的回调函数(一定先执行有return)
/**
* 回调函数
* @author dakb
*
*/
public class MyPasswordCallback implements CallbackHandler {
@Override
public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
WSPasswordCallback wspd = (WSPasswordCallback)callbacks[0];
String identifier = wspd.getIdentifier(); //得到用户名
//根据客户端传递的用户名,生成密码
if(identifier.equals("wss4j")){
wspd.setPassword("1234");
}
}
}
步骤二:在安全拦截器中配置拦截器的参数(定义拦截器的校验方式,令牌/签名)
WSHandlerConstants父类中有如下两种属性:
UsernameToken—请求中携带用户名与密码 UsernameTokenSignature,请求中不携带用户名与密码,携带通过RSA加密的数字签名
步骤三:在拦截器中配置回调函数(确定用户名和密码信息)
ApplicationContext配置中已经配置
现在做一个小Demo
1、发布一个基于soap协议的接口,用于发布服务
import javax.jws.WebService;
/**
* 发布一个测试安全基于soap协议的服务
* @author enni
*
*/
@WebService
public interface TestServiceInf {
//定义一个ping方法
public String ping(String hello);
}
2、接口实现类
package com.a.com.service;
public class TestServiceImp implements TestServiceInf {
@Override
public String ping(String hello) {
System.out.println("收到客户端"+hello+"请求");
return "pong";
}
3、创建回调函数
package com.a.util;
**import org.apache.wss4j.common.ext.WSPasswordCallback;**
注意导入的包是wss4j的。。。。
/**
* 回调函数
* @author dushasha
*
*/
public class MyPasswordCallback implements CallbackHandler {
@Override
public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
WSPasswordCallback wspd = (WSPasswordCallback)callbacks[0];
String identifier = wspd.getIdentifier(); //得到用户名
//根据客户端传递的用户名,生成密码
if(identifier.equals("wss4j")){
wspd.setPassword("1234");
}
}
现在启动服务器,我们开始测试(加入wss安全协议)
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ser="http://service.a.com/">
<soapenv:Header>
<wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<wsse:UsernameToken >
<wsse:Username>wss4jwsse:Username>
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">1234wsse:Password>
wsse:UsernameToken>
wsse:Security>
soapenv:Header>
<soapenv:Body>
<ser:ping>
<arg0>wssdarg0>
ser:ping>
soapenv:Body>
soapenv:Envelope>
返回结果
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<ns2:pingResponse xmlns:ns2="http://service.a.com/">
<return>pongreturn>
ns2:pingResponse>
soap:Body>
soap:Envelope>