Sollte es nötig sein, dass Acegi-Plugin z.B. für eine eigene SSO-Authentifzierung zu erweitern, ist das eigentlich recht einfach zu realisieren, um z.B. Nutzerdaten aus dem Request-Header zu lesen.
Eine Möglichkeit der Implementierung ist diese hier:
Der beste Platz für die eigenen Klassen sollte ein eigenes Package innerhalb der src/groovy bzw. src/java Ordner inenrhalb des Plugins sein.
Ein AuthenticationProcessingFilter, in welchem die folgenden Methoden für die eigenen Bedürfnisse implementiert werden müssen:
public Authentication attemptAuthentication(HttpServletRequest request) protected String obtainUsername(HttpServletRequest request) protected String obtainPassword(HttpServletRequest request)
Als nächstes benötigen wir ein AuthenticationToken, welches die Daten zur Authentifizierung für unsere Grails-Anwendung enthalten soll. Dieses Token muss die folgenden Interfaces implementieren:
Serializable Principal Authentication
implementieren, welcher die eigentliche Authentifizierung durchführt, in dem innerhalb des Tokens das FLAG isAuthenticated auf TRUE gesetzt wird. | Die AuthenticationProvider-Klasse enthält die folgenden Methoden:
public Authentication authenticate(Authentication authentication) public boolean supports(Class arg0)
Die Method supports(Class arg0) sollte TRUE liefern, sofern es sich um eine Instanz des eigenen Tokens handelt.
Nun haben wir die Grundvoraussetzung für eine eigene Authentifizierungsmethode. Um die eigenen Funktionen nutzen zu können, müssen AuthenticationProvider und AuthenticationProcessingFilter in der Klasse AcegiGrailsPlugin konfiguriert werden.
Das AuthenticationToken wird dann im AuthenticationProcessingFilter zusammengebaut und an den AuthenticationManager weitergeleitet.
Am besten lässt sich das vielleicht an einem Beispiel erklären ....
AuthenticationToken
public class FooAuthenticationToken extends AbstractAuthenticationToken { private Object principal; @Deprecated public FooAuthenticationToken(Object principal) { this.principal = principal; } @Override public FooAuthenticationToken(Object principal, GrantedAuthority[] authorities) { super(authorities); this.principal = principal; } @Override public Object getCredentials() { return null; } @Override public Object getPrincipal() { return this.principal; } }
AuthenticationProcessingFilter
public class FooAuthenticationProcessingFilter extends AuthenticationProcessingFilter { @Override public Authentication attemptAuthentication(HttpServletRequest request) throws AuthenticationException{ FooAuthenticationToken token = new FooAuthenticationToken(obtainUsername(request)) return this.getAuthenticationManager().authenticate(token) } }
AuthenticationProvider
public class FooAuthenticationProvider implements AuthenticationProvider, InitializingBean, MessageSourceAware { @Override public Authentication authenticate(Authentication authentication) throws AuthenticationException { UserDetails user = retrieveUser(authentication.getName(), (FooAuthenticationToken) authentication); Object principalToReturn = user; if (forcePrincipalAsString) { principalToReturn = user.getUsername(); } return createSuccessAuthentication(principalToReturn, authentication, user); } @Override public boolean supports(Class arg0) { return (FooAuthenticationToken.class.isAssignableFrom(arg0)); } }