2012-06-07 2 views
5

Versuchen zu verstehen, wie die OpenID-Authentifizierung mit Spring Security korrekt implementiert wird.Spring Security OpenID - UserDetailsService, AuthenticationUserDetailsService

public class OpenIDUserDetailsService implements 
    UserDetailsService, 
    AuthenticationUserDetailsService { 

    @Override 
    public UserDetails loadUserByUsername(String openId) throws 
    UsernameNotFoundException, DataAccessException { 

    // I either want user email here 
    // or immediately delegate the request to loadUserDetails 

    } 

    @Override 
    public UserDetails loadUserDetails(Authentication token) throws 
    UsernameNotFoundException { 

    // This never gets called if I throw from loadUserByUsername() 

    } 

    private MyCustomUserDetails registerUser(String openId, String email) { 
    ... 
    } 
} 

Ich denke über das Szenario nach, wenn der Benutzer noch nicht in meiner Anwendung registriert ist. Um den Benutzer zu registrieren, muss ich seine OpenID und E-Mail kennen.

Wenn OpenID-Anbieter den Benutzer zurück zu meiner Anwendung leitet, wird loadUserByUsername() aufgerufen, aber in diesem Fall bin ich nur über die OpenID des Benutzers bekannt. Also, ich werfe UsernameNotFoundException und dann loadUserDetails() wird nie aufgerufen, so kann ich nicht Benutzer registrieren.

Was ist die gemeinsame Lösung hier? Was passiert, wenn ich etwas wie FakePartialUserDetails von loadUserByUsername() zurückgebe und dann, wenn loadUserDetails() aufgerufen wird, registriere ich den Benutzer und dann die echte MyCustomUserDetails?

Ich verwende Spring Security 3.0.7.RELEASE

Antwort

1

Das ist lustig, aber schaffte es Spring Security 3.1.0.RELEASE durch Bewegung zu lösen.

Für das gleiche Szenario ist das Verhalten absolut unterschiedliche-loadUserByUsername() nicht statt genannt wird aufgerufen und loadUserDetails().

+4

Dies ist nicht korrekt. In 3.1 hat OpenIDAuthenticationProvider Setter für UserDetailsService und AuthenticationUserDetailsService und ruft entweder loadUserByUsername oder loadUserDetails auf, abhängig davon, welcher Setter verwendet wird. In 3.0.7 gab es keinen Setter für AuthenticationUserDetailsService und daher wurde immer loadUserByUsername verwendet. – Ritesh

0

löste ich die gleiche Situation von

AuthenticationUserDetailsService<OpenIDAuthenticationToken> 

in meinem UserDetailsService umzusetzen.

public class OpenIdUserDetailsService implements UserDetailsService, 
    AuthenticationUserDetailsService<OpenIDAuthenticationToken> { 

@Autowired(required = true) 
@Qualifier(value = "jdbcUserDetailsService") 
private UserDetailsService localUserDetailsService; 

/** 
* @return the localUserDetailsService 
*/ 
public UserDetailsService getLocalUserDetailsService() { 
    return localUserDetailsService; 
} 

/** 
* @param localUserDetailsService 
*   the localUserDetailsService to set 
*/ 
public void setLocalUserDetailsService(
     UserDetailsService localUserDetailsService) { 
    this.localUserDetailsService = localUserDetailsService; 
} 

@Override 
public UserDetails loadUserDetails(OpenIDAuthenticationToken token) 
     throws UsernameNotFoundException { 
    String email = getEmail(token); 
    return loadUserByUsername(email); 
} 

@Override 
public UserDetails loadUserByUsername(String username) 
     throws UsernameNotFoundException { 
    return localUserDetailsService.loadUserByUsername(username); 
} 

private String getEmail(OpenIDAuthenticationToken token) { 
    for (OpenIDAttribute attribute : token.getAttributes()) { 
     if (attribute.getName().equals("email")) { 
      return attribute.getValues().get(0); 
     } 
    } 
    return null; 
} 

} 

So stellen Sie sicher über Service als UserDetailsService zu verwenden, während openid-Form konfigurieren. Konfigurieren Sie außerdem den Attributaustausch für das Attribut "E-Mail" während der Konfiguration von openid. Die nach der erfolgreichen Authentifizierung zurückgegebene E-Mail kann dann von 'OpenIDAuthenticationToken' abgerufen werden, die schließlich als Parameter an die Funktion 'loadUserByUsername' übergeben wird.

Wenn Sie einen Benutzer mit dieser E-Mail registriert haben, ist die Authentifizierung abgeschlossen. Andernfalls können Sie dem Benutzer vorschlagen, sich bei dieser E-Mail-Adresse registrieren zu lassen oder die Anmeldefehlerseite anzuzeigen.

+0

Der tatsächliche Grund für OP wird von Ritesh beantwortet (Kommentar für akzeptierte Antwort!) – manikanta

Verwandte Themen