转载是因为此文网站被墙了。
The next step in rewriting the application was to secure the web services with WS-Security. In this post I get a grails version of the xfire wss example of User Token Authentication up and running. To do this I use (of course) the grails xfire plugin.
After creating a grails project and installing the xfire plugin, the first thing to do is to configure the inHandlers:
to do this add the following to the doWithSpring
closure in XfireGrailsPlugin.groovy
"xfire.passHandler"(org.codehaus.xfire.demo.PasswordHandler) { bean ->
}
"xfire.DOMhandler"(org.codehaus.xfire.util.dom.DOMInHandler) { bean ->
}
"xfire.WSS4JHandler"(org.codehaus.xfire.security.wss4j.WSS4JInHandler) {
properties = ["passwordCallbackRef":ref("xfire.passHandler"),
"action":"UsernameToken"]
}
"xfire.ValidateUserTokenHandler"(org.codehaus.xfire.demo.ValidateUserTokenHandler) {
}
ValidateUserTokenHandler
and PasswordHandler
are part of the example code distributed with xfire. I just copied them into the correct package in src/java/
in this simple grails app. And then add the inHandlers
to the org.grails.xfire.ServiceBean
inHandlers = [ref("xfire.DOMhandler"),
ref("xfire.WSS4JHandler"),
ref("xfire.ValidateUserTokenHandler")]
doWithSpring
at the end of this post. Now any service you expose with xfire will require (and print) a username and password in a WSS UsernameToken header. The simple service I used to test this is:
class TestService {
static expose=['xfire']
boolean transactional = true
String serviceMethod() {
return "You did it!!!"
}
}
I use
soapUI to test, here is the request it generated:
1 | foo |
2 | bar |
3 | 2008-03-01T19:49:03.627Z |
This is obviously not a perfect solution. You may not want to secure all the web services in your project or at least not all in the same way. After I finish with this project I will have a more general solution to contribute to the grails xfire plugin.But first, I need to do something with the user credentials I am now receiving. Next up, integrating with acegi through the grails acegi plugin…
Full doWithSpring listing:
def doWithSpring = {
"xfire.serviceRegistry"(org.codehaus.xfire.service.DefaultServiceRegistry) { bean->
bean.getBeanDefinition().setSingleton(true)
}
"xfire.transportManager"(org.codehaus.xfire.transport.DefaultTransportManager){ bean->
bean.getBeanDefinition().setSingleton(true)
bean.getBeanDefinition().setInitMethodName("initialize")
bean.getBeanDefinition().setDestroyMethodName("dispose")
}
"xfire"(org.codehaus.xfire.DefaultXFire,
ref("xfire.serviceRegistry"),
ref("xfire.transportManager")) { bean ->
bean.getBeanDefinition().setSingleton(true)
}
"xfire.typeMappingRegistry"(org.codehaus.xfire.aegis.type.DefaultTypeMappingRegistry){ bean ->
bean.getBeanDefinition().setSingleton(true)
bean.getBeanDefinition().setInitMethodName("createDefaultMappings");
}
"xfire.aegisBindingProvider"(org.codehaus.xfire.aegis.AegisBindingProvider,
ref("xfire.typeMappingRegistry")) { bean ->
bean.getBeanDefinition().setSingleton(true)
}
"xfire.serviceFactory"(org.codehaus.xfire.service.binding.ObjectServiceFactory,
ref("xfire.transportManager"), ref("xfire.aegisBindingProvider")) { bean ->
bean.getBeanDefinition().setSingleton(true)
}
"xfire.servletController"(org.codehaus.xfire.transport.http.XFireServletController,
ref("xfire")) { bean ->
bean.getBeanDefinition().setSingleton(true)
}
"grails.xfire"(org.grails.xfire.ServiceFactoryBean, "grails.xfire") { bean ->
bean.getBeanDefinition().setInitMethodName("initialize")
transportManager = ref("xfire.transportManager")
grailsApplication = ref("grailsApplication", true)
}
"xfire.passHandler"(org.codehaus.xfire.demo.PasswordHandler) { bean ->
}
"xfire.DOMhandler"(org.codehaus.xfire.util.dom.DOMInHandler) { bean ->
}
"xfire.WSS4JHandler"(org.codehaus.xfire.security.wss4j.WSS4JInHandler) {
properties = ["passwordCallbackRef":ref("xfire.passHandler"),
"action":"UsernameToken Timestamp"]
}
"xfire.ValidateUserTokenHandler"(org.codehaus.xfire.demo.ValidateUserTokenHandler) {}
if(application.serviceClasses) {
application.serviceClasses.each { service ->
def serviceClass = service.getClazz()
def exposeList = GrailsClassUtils.getStaticPropertyValue(serviceClass, 'expose')
if(exposeList!=null && exposeList.contains('xfire')) {
def sName = service.propertyName.replaceFirst("Service","XFire")
//
"${sName}"(org.grails.xfire.ServiceBean){
//
xfire = ref("xfire")
//
serviceBean = ref("${service.propertyName}")
//
serviceClass = service.getClazz()
//
serviceFactory = ref("grails.xfire")
inHandlers = [ref("xfire.DOMhandler"),
ref("xfire.WSS4JHandler"),
ref("xfire.ValidateUserTokenHandler")]
}
}
}
}
}