原文url:http://axixmiqui.wordpress.com/2008/03/11/adventures-in-grails-ws-security-part-2/
Integrating acegi
It turned out that initial integration of acegi with xfire + WSS was even easier than hooking up WSS for xfire in Grails. Though I can’t claim much original work here. In his blog Propagating Acegi’s Security Context in a WSS UsernameToken SOAP Header via XFire using wss4j Michael Vorbuger provides everything necessary to get it working.
To get it running I added the three classes from Michael’s code acegi-ws-security-xfire-example to the appropriate packages in src/java/ in my Grails app.
ch.vorburger.acegiwss.server.PasswordHandler
ch.vorburger.acegiwss.server.ForgivingWSS4jInHandler
ch.vorburger.acegiwss.server.ValidateUserTokenHandler
and changed the inhandlers to use these classes in XfireGrailsPlugin.groovy
.
"xfire.passHandler"(ch.vorburger.acegiwss.server.PasswordHandler) { bean -> } "xfire.DOMhandler"(org.codehaus.xfire.util.dom.DOMInHandler) { bean -> } "xfire.WSS4JHandler"(ch.vorburger.acegiwss.server.ForgivingWSS4jInHandler) { properties = ["passwordCallbackRef":ref("xfire.passHandler"), "action":"UsernameToken"] } "xfire.ValidateUserTokenHandler"(ch.vorburger.acegiwss.server.ValidateUserTokenHandler) {}
That makes the SecurityContext avaliable in the service. To see it work I paraphrased Michael’s example in the test service.
import org.acegisecurity.Authentication import org.acegisecurity.context.SecurityContextHolder class TestService { static expose=['xfire'] boolean transactional = true String serviceMethod() { Authentication auth = SecurityContextHolder.getContext().getAuthentication(); if (auth == null || auth.getName() == null || auth.getName().length() == 0) { // In a real service, this would be a proper SOAP Fault, NOT an IllegalArgumentException throw new IllegalArgumentException(NOAUTH_FAULT_TEXT); } return "You did it ${auth.getName()}!!!" } }
Thats it!