转载是因为此文网站被墙了。
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")] } } } } }