CXF 安全认证

CXF的webService已经创建好,但没有安全可言,毕竟这是Internet服务呀。
CXF给了一个很完整的安全架构,但CXF给出的ws_security DEMO太复杂了,又是password jks X509 Timestamp。 我试了很多次都没有成功。化繁为简,只实现一个user password好了。下面开始
编写cxf.xml在原来的bean的地方声明一下就可以了

Java代码

<bean id="WSS4JInInterceptor" class="org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor">

<constructor-arg>

<map>

<entry key="action" value="UsernameToken" />

<entry key="passwordType" value="PasswordText" />

<entry key="passwordCallbackClass"

value="com.xxxx.Service.ServerPasswordCallback" />

</map>

</constructor-arg>

</bean>

<jaxws:endpoint id="chartScreen" implementor="#chartScreenService"

address="/ChartScreenService" >





<jaxws:inInterceptors>

<bean class="org.apache.cxf.binding.soap.saaj.SAAJInInterceptor" />

<ref bean="WSS4JInInterceptor" />

</jaxws:inInterceptors>



</jaxws:endpoint>

<bean id="WSS4JInInterceptor" class="org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor">

<constructor-arg>

<map>

<entry key="action" value="UsernameToken" />

<entry key="passwordType" value="PasswordText" />

<entry key="passwordCallbackClass"

value="com.mms.webservice.test.ServerPasswordCallback" />

</map>

</constructor-arg>

</bean>



<jaxws:endpoint id="helloWorld"

implementor="com.mms.webservice.HelloWorldImpl"

address="/HelloWorld">

<jaxws:inInterceptors>

<!--

<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="passwordCallbackClass"

value="com.mms.webservice.test.ServerPasswordCallback" />

</map>

</constructor-arg>

</bean>

-->

<ref bean="WSS4JInInterceptor" />

</jaxws:inInterceptors>

</jaxws:endpoint>


WSS4JInInterceptor就是我们要定义的东东了。CXf已经帮你写好了。设置属性就可以了。里面属性值挺多的,CXF的文档就是太简单了,opensource的弊病!属性值就查API吧。
下面需要写server端的密码回调函数,验证logic就在这里定义了。

Java代码



public class ServerPasswordCallback implements CallbackHandler {

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

public ServerPasswordCallback(){

passwords.put("admin", "admin");

passwords.put("test", "test");

}

@Override

public void handle(Callback[] callbacks) throws IOException,

UnsupportedCallbackException {

for (int i = 0; i < callbacks.length; i++) {

WSPasswordCallback pc = (WSPasswordCallback) callbacks[i];

if(!passwords.containsKey(pc.getIdentifier()))

throw new WSSecurityException("user not match");

String pass = passwords.get(pc.getIdentifier());

String pwd = pc.getPassword();

if (pwd == null || !pwd.equals(pass)){

throw new WSSecurityException("password not match");

}

}



}



}就此server端的验证就全部ok了。这时再调用原来的调用程序就会报ws_security错误了。

下面给出Client验证程序
其实就是在soapheader上加相应内容。也需要用到inInterceptors

Java代码

public class ClientPasswordCallback implements CallbackHandler {

private Map<String, String> passwords =

new HashMap<String, String>();

public ClientPasswordCallback(){

passwords.put("admin", "admin");

passwords.put("test", "test");

}

@Override

public void handle(Callback[] callbacks) throws IOException,

UnsupportedCallbackException {

for (int i = 0; i < callbacks.length; i++) {

WSPasswordCallback pc = (WSPasswordCallback) callbacks[i];

int usage = pc.getUsage();

if(!passwords.containsKey(pc.getIdentifier()))

throw new WSSecurityException("user not exists ");

String pass = passwords.get(pc.getIdentifier());

if (usage == WSPasswordCallback.USERNAME_TOKEN && pass != null) {

pc.setPassword(pass);

return;

}

}

}

}





JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();



Map<String, Object> outProps = new HashMap<String, Object>();

outProps.put(WSHandlerConstants.ACTION,

WSHandlerConstants.USERNAME_TOKEN);

outProps.put(WSHandlerConstants.USER, "admin");

outProps.put(WSHandlerConstants.PASSWORD_TYPE, WSConstants.PW_TEXT);

outProps.put(WSHandlerConstants.PW_CALLBACK_CLASS,

ClientPasswordCallback.class.getName());



WSS4JOutInterceptor wssOut = new WSS4JOutInterceptor(outProps);

factory.getOutInterceptors().add(wssOut);

factory.getOutInterceptors().add(new SAAJOutInterceptor());





factory.setServiceClass(IChartScreenService.class);

factory.setAddress("http://localhost:8080/ECFlight/service/ChartScreenService");

IChartScreenService service = (IChartScreenService) factory.create();



也可采用spring 配置:

<!-- wssecurity -->
<bean id="clientPasswordCallback" class="com.evermoresw.megp.utilities.ClientPasswordCallback" />
<bean id="wsOutInterceptor" 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="admin" />
<entry key="passwordCallbackRef">
<ref bean="clientPasswordCallback" />
</entry>
</map>
</constructor-arg>
</bean>
<jaxws:client id="client_testService" serviceClass="com.evermore.moa.service.Test"
address="http://localhost:8080/cxfTestServer/service/testService">
<jaxws:outInterceptors>

<bean class="org.apache.cxf.binding.soap.saaj.SAAJInInterceptor" />

<ref bean="wsOutInterceptor"/>
</jaxws:outInterceptors>
</jaxws:client>



问题:Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/xml/security/Init

加上:xmlsec-1.4.3.jar包



For WS-Security support:

- bcprov-jdk15.jar

- xalan.jar

- serializer.jar

- wss4j.jar

- xmlsec.jar


本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/pengchua/archive/2009/12/26/5081164.aspx
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值