原文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!