2013-07-03 7 views
6

Entweder ich etwas fehlt, oder das ist, wie es funktioniert ...
nämlich implementiert ich UserDetailsService und Unter eingestuft (AppUser unten) Feder Utility-Klasse User, (das implementiert UserDetails). Wenn es darauf ankommt, es geht ungefähr so:Spring-Sicherheit gibt String als Principal statt UserDetails bei fehlgeschlagener Anmeldung zurück?

@Override 
public UserDetails loadUserByUsername(String username) 
throws UsernameNotFoundException { 
    // try loading user by its name 
    SystemUser user = null; 
    try { 
     user = this.sysUserService.getByUsername(username); 
     if(user == null) 
      throw new UsernameNotFoundException("User not found!"); 
    } 
    catch(Exception e) { 
     throw new DataRetrievalFailureException(
       "Could not load user with username: " + username); 
    } 
    // load user rights, and create UserDetails instance 
    UserDetails res = new AppUser(user, getUserAuthorities(user)); 

    return res; 
} 

Dann habe ich versuchte Konto Verriegelung mit diesem Ansatz zu implementieren:

public class LoginFailureEventListenter implements 
ApplicationListener<AuthenticationFailureBadCredentialsEvent> { 

// rest omitted for brevity 

@Override 
public void onApplicationEvent(AuthenticationFailureBadCredentialsEvent event) { 
    // ... 

    SystemUser user = ((AppUser)event.getAuthentication().getPrincipal()).getSystemUser(); 
    // cast exception - how is it possible to obtain String 
    // instead of UserDetails object here ? 
    // ... 
} 
} 

Allerdings lief ich in java.lang.ClassCastException beim Versuch, die Hauptaufgabe von der bekommen übergebenes Ereignisargument (Hauptobjekt war vom Typ String). Ich meine, OK - ich kann nur meine SystemUser von Benutzernamen erneut laden, um das Problem zu lösen, aber ich habe dies nicht erwartet ...
Ich denke, dass sogar die Quelldokumentationen UserDetails Instanz für dieses Szenario zurückgeben soll.
Gedanken?

Antwort

5

Da es sich um einen Authentifizierungsfehler handelt, ist das Objekt Authentication im Ereignis das Objekt, das an die gesendet wurde (und die zurückgewiesen wurde).

In einem typischen Szenario wäre dies eine UsernamePasswordAuthenticationToken, wobei die "Principal" -Eigenschaft der gesendete Benutzername ist.

Die AuthenticationManager unterstützt viele verschiedene Authentifizierungsmechanismen und aus ihrer Sicht gibt es keine Garantie, dass ein UserDetailsService sogar in die Authentifizierung einbezogen ist. Es weiß nur, dass das Authentifizierungstoken nicht akzeptiert wurde (es gab eine Ausnahme) und es veröffentlicht das Ereignis entsprechend.

Alternative Optionen sind die Anpassung der AuthenticationProvider in Verwendung oder ein AuthenticationFailureHandler (wenn Sie Form-Login zum Beispiel verwenden) und die zusätzliche Arbeit dort tun.

+0

Also ist das eigentlich so, wie es sein soll ...? Ich benutze bereits 'AuthenticationSuccessHandler' für das Zurücksetzen des Zählers, kann nicht sagen, ob dies der richtige Ansatz ist, es ist mir nicht eingefallen, es mit' AuthenticationFailureHandler' zu versuchen. – Less

+0

Ja, so soll es sein. Das Ereignis sagt "Dies ist die Authentifizierungsanforderung, die fehlgeschlagen ist" und die Authentifizierungsanforderung enthält nur eine Zeichenfolge-ID für den Benutzer. –

Verwandte Themen