XHuiLin 2010-01-05
xfire的webservice安全机制
在原来使用xfire和spring集成的基础上,需要加入下面的这些包
在集成到jboss的时候还出了一个问题,wss4j-1.5.0.jar这个包还死活找不到,不知道是什么原因,后来找了半天
发现jboss4.2这娃在这个路径上有些安全相关的jar吧,拷贝到这里后,jboss运行正常了
D:\tool\jboss-4.2\server\default\deploy\jbossws.sar
其他的包,都仍到WEB-INF/lib下面就可以了
commons-discovery-0.2.jar
bcprov-jdk15-133.jar
wss4j-1.5.0.jar
xalan-2.7.0.jar
先说server端如何配置和加入程序:
1、server端提供出来的webservice先写个接口,可以直接继承自原来的WS接口UserServiceEnc.java:
packagecom.megaeyes.ipcamera.service.webservice.iface;
publicinterfaceUserServiceEncextendsUserService{
}
2、写一个passwordHandler来校验用户名,PasswordHandler.java:
packagecom.megaeyes.ipcamera.service.webservice.tools;
importjava.util.HashMap;
importjava.util.Map;
importjavax.security.auth.callback.Callback;
importjavax.security.auth.callback.CallbackHandler;
importorg.apache.ws.security.WSPasswordCallback;
publicclassPasswordHandlerimplementsCallbackHandler{
privatefinalMappasswords=newHashMap();
@SuppressWarnings("unchecked")
publicPasswordHandler(){
passwords.put("safedv","safedv");
passwords.put("tianyi","tianyi");
}
publicvoidhandle(Callback[]callbacks){
WSPasswordCallbackcallback=(WSPasswordCallback)callbacks[0];
Stringid=callback.getIdentifer();
callback.setPassword((String)passwords.get(id));
}
}
3、写一个WSS4JTokenHandler对加密内容的操作的handler,WSS4JTokenHandler.java:
packagecom.megaeyes.ipcamera.service.webservice.tools;
importjava.security.cert.X509Certificate;
importjava.util.Vector;
importorg.apache.commons.logging.Log;
importorg.apache.commons.logging.LogFactory;
importorg.apache.ws.security.WSConstants;
importorg.apache.ws.security.WSSecurityEngineResult;
importorg.apache.ws.security.WSUsernameTokenPrincipal;
importorg.apache.ws.security.handler.WSHandlerConstants;
importorg.apache.ws.security.handler.WSHandlerResult;
importorg.codehaus.xfire.MessageContext;
importorg.codehaus.xfire.handler.AbstractHandler;
importsun.security.x509.X500Name;
publicclassWSS4JTokenHandlerextendsAbstractHandler{
privatestaticfinalLoglog=LogFactory.getLog(WSS4JTokenHandler.class);
publicvoidinvoke(MessageContextcontext)throwsException{
Vectorresult=(Vector)context.getProperty(WSHandlerConstants.RECV_RESULTS);
if(result==null){
log.error("ClientdoesnotcontainSecurityHeader,needWSSJOutHandler");
return;
}
for(inti=0;i<result.size();i++){
WSHandlerResultres=(WSHandlerResult)result.get(i);
for(intj=0;j<res.getResults().size();j++){
WSSecurityEngineResultsecRes=(WSSecurityEngineResult)res.getResults().get(j);
intaction=secRes.getAction();
//USERTOKEN
if((action&WSConstants.UT)>0){
WSUsernameTokenPrincipalprincipal=(WSUsernameTokenPrincipal)secRes
.getPrincipal();
//SetuserpropertytouserfromUTtoallowresponseencryption
context.setProperty(WSHandlerConstants.ENCRYPTION_USER,principal.getName());
log.info("Client'sUsername:"+principal.getName()+"Client'sPassword:"
+principal.getPassword()+"\n");
}
//SIGNATURE
if((action&WSConstants.SIGN)>0){
@SuppressWarnings("unused")
X509Certificatecert=secRes.getCertificate();
X500Nameprincipal=(X500Name)secRes.getPrincipal();
//Dosomethingwhithcert
log.info("Signaturefor:"+principal.getCommonName());
}
}
}
log.info("WSS4JTokenHandlerDone!");
}
}
4、applicationContext-webservice.xml服务端专门配置文件里面加入:
<beanname="userServiceEnc"parent="baseWebService">
<propertyname="serviceBean"ref="UserServiceImpl"/>
<propertyname="serviceClass"
value="com.megaeyes.ipcamera.service.webservice.iface.UserServiceEnc"/>
<propertyname="inHandlers">
<list>
<refbean="domInHandler"/>
<refbean="wss4jInHandlerEnc"/>
<refbean="validateUserTokenHandler"/>
</list>
</property>
</bean>
<beanid="domInHandler"class="org.codehaus.xfire.util.dom.DOMInHandler"/>
<beanid="wss4jInHandlerEnc"class="org.codehaus.xfire.security.wss4j.WSS4JInHandler">
<propertyname="properties">
<props>
<propkey="action">Encrypt</prop>
<propkey="decryptionPropFile">
insecurity_enc.properties
</prop>
<propkey="passwordCallbackClass">
com.megaeyes.ipcamera.service.webservice.tools.PasswordHandler
</prop>
</props>
</property>
</bean>
<beanid="validateUserTokenHandler"
class="com.megaeyes.ipcamera.service.webservice.tools.WSS4JTokenHandler"/>
4、在SRPING的配置文件里面的那个properties,放置到classpath下面就可以了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=ipcamera
#私匙的名字
org.apache.ws.security.crypto.merlin.file=safedv_private.jks
5、在服务端的classpath里面要放置自己的私匙。关于这几个私匙的生成。后续会讲。以上5步服务端的配置就结束了。