Spring Security: Authentifizierung mit einem datenbankgestützten UserDetailsService

Spring Security: Authentifizierung mit einem datenbankgestützten UserDetailsService

1. Überblick

In diesem Artikel wird gezeigt, wie Sie benutzerdefinierte datenbankgestützteUserDetailsService für die Authentifizierung mit Spring Security erstellen.

2. UserDetailsService

DieUserDetailsService-Schnittstelle wird zum Abrufen benutzerbezogener Daten verwendet. Es gibt eine Methode namensloadUserByUsername(), die überschrieben werden kann, um den Prozess des Findens des Benutzers anzupassen.

Es wird vonDaoAuthenticationProvider verwendet, um Details über den Benutzer während der Authentifizierung zu laden.

3. DasUser-Modell

Zum Speichern von Benutzern erstellen wir eineUser-Entität, die einer Datenbanktabelle mit den folgenden Attributen zugeordnet ist:

@Entity
public class User {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @Column(nullable = false, unique = true)
    private String username;

    private String password;

    // standard getters and setters
}

4. Benutzer abrufen

Um einen Benutzer abzurufen, der einem Benutzernamen zugeordnet ist, erstellen wir eineDAO-Klasse mitSpring Data, indem wir dieJpaRepository-Schnittstelle erweitern:

public interface UserRepository extends JpaRepository {

    User findByUsername(String username);
}

5. DieUserDetailsService

Um unseren eigenen Benutzerdienst bereitzustellen, müssen wir dieUserDetailsService-Schnittstelle implementieren.

Wir erstellen eine Klasse namensMyUserDetailsService, die die MethodeloadUserByUsername() der Schnittstelle überschreibt.

Bei dieser Methode rufen wir dasUser-Objekt mitDAO ab. Wenn es vorhanden ist, wickeln Sie es in einMyUserPrincipal-Objekt ein, dasUserDetails implementiert, und geben es zurück:

@Service
public class MyUserDetailsService implements UserDetailsService {

    @Autowired
    private UserRepository userRepository;

    @Override
    public UserDetails loadUserByUsername(String username) {
        User user = userRepository.findByUsername(username);
        if (user == null) {
            throw new UsernameNotFoundException(username);
        }
        return new MyUserPrincipal(user);
    }
}

Definieren wir dieMyUserPrincipal-Klasse wie folgt:

public class MyUserPrincipal implements UserDetails {
    private User user;

    public MyUserPrincipal(User user) {
        this.user = user;
    }
    //...
}

6. Federkonfiguration

Wir werden beide Arten von Spring-Konfigurationen demonstrieren: XML- und annotationsbasiert, die erforderlich sind, um die Implementierung unserer benutzerdefiniertenUserDetailsServicezu verwenden.

6.1. Anmerkungskonfiguration

Alles, was wir tun müssen, um unsere benutzerdefiniertenUserDetailsService is zu aktivieren, fügen Sie sie als Bean zu unserem Anwendungskontext hinzu.

Da wir unsere Klasse mit der Annotation@Servicekonfiguriert haben, erkennt die Anwendung diese automatisch während des Komponentenscans und erstellt aus dieser Klasse eine Bean. Daher müssen wir hier nichts weiter tun.

Alternativ können wir:

  • Konfigurieren Sie es inauthenticationManager mit der MethodeAuthenticationManagerBuilder#userDetailsService

  • Legen Sie es als Eigenschaft in einer benutzerdefiniertenauthenticationProvider-Bean fest und fügen Sie diese dann mit derAuthenticationManagerBuilder# authenticationProvider-Funktion ein

6.2. XML-Konfiguration

Andererseits müssen wir für die XML-Konfiguration eine Bean mit dem TypMyUserDetailsService definieren und sie in dieauthentication-provider-Bohne von Spring einfügen:




    
        
        
    



    

7. Andere datenbankgestützte Authentifizierungsoptionen

AuthenticationManagerBuilder bietet eine weitere Methode zum Konfigurieren der JDBC-basierten Authentifizierung in unserer Anwendung.

Wir müssenAuthenticationManagerBuilder.jdbcAuthentication mit einerDataSource-Instanz konfigurieren. Wenn unsere Datenbank denSpring User Schema folgt, passen die Standardkonfigurationen gut zu uns.

Wir haben eine Grundkonfiguration mit diesem Ansatz ina previous post gesehen.

DieJdbcUserDetailsManager -Sentität, die sich aus dieser Konfiguration ergibt, implementiert denUserDetailsService -Stoo.

Infolgedessen können wir den Schluss ziehen, dass diese Konfiguration einfacher zu implementieren ist, insbesondere wenn wir Spring Boot verwenden, das dieDataSource automatisch für uns konfiguriert.

Wenn wir ohnehin ein höheres Maß an Flexibilität benötigen und genau anpassen müssen, wie die Anwendung die Benutzerdetails abruft, entscheiden wir uns für den Ansatz, den wir in diesem Lernprogramm verfolgt haben.

8. Fazit

Zusammenfassend haben wir in diesem Artikel gezeigt, wie Sie benutzerdefinierte Spring-basierteUserDetailsServiceerstellen, die von persistenten Daten unterstützt werden.

Die Implementierung befindet sich inthe GitHub project - dies ist ein Maven-basiertes Projekt, daher sollte es einfach zu importieren und auszuführen sein.