Spring Security: Authentifizierung mit einem datenbankgestützten UserDetailsService

1. Übersicht

In diesem Artikel wird gezeigt, wie Sie einen benutzerdefinierten datenbankgestützten UserDetailsService für die Authentifizierung mit Spring Security erstellen .

2. UserDetailsService

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

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

3. Der Benutzer Modell

Zum Speichern von Benutzern erstellen wir eine Benutzerentität , die einer Datenbanktabelle zugeordnet ist, mit den folgenden Attributen:

@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 mithilfe von Spring Data eine DAO- Klasse, indem wir die JpaRepository- Schnittstelle erweitern:

public interface UserRepository extends JpaRepository { User findByUsername(String username); }

5. Der UserDetailsService

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

Wir erstellen eine Klasse namens MyUserDetailsService , die die Methode loadUserByUsername () der Schnittstelle überschreibt .

Bei dieser Methode rufen wir das Benutzerobjekt mithilfe des DAO ab . Wenn es vorhanden ist, wickeln Sie es in ein MyUserPrincipal- Objekt ein, das UserDetails 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 die MyUserPrincipal- 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 unsere benutzerdefinierte UserDetailsService- Implementierung zu verwenden.

6.1. Anmerkungskonfiguration

Alles, was wir tun müssen, um unseren benutzerdefinierten UserDetailsService zu aktivieren, ist, ihn als Bean zu unserem Anwendungskontext hinzuzufügen.

Da wir unsere Klasse mit der Annotation @Service konfiguriert 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 im authenticationManager mit der AuthenticationManagerBuilder # userDetailsService- Methode
  • Legen Sie es als Eigenschaft in einer benutzerdefinierten authenticationProvider- Bean fest und fügen Sie diese dann mithilfe der AuthenticationManagerBuilder # authenticationProvider- Funktion ein

6.2. XML-Konfiguration

Andererseits müssen wir für die XML-Konfiguration eine Bean vom Typ MyUserDetailsService definieren und sie in die Authentifizierungsanbieter- Bean von Spring einfügen :

7. Andere datenbankgestützte Authentifizierungsoptionen

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

Wir müssen die AuthenticationManagerBuilder.jdbcAuthentication mit einer DataSource- Instanz konfigurieren . Wenn unsere Datenbank dem Spring-Benutzerschema folgt, passen die Standardkonfigurationen gut zu uns.

Wir haben in einem früheren Beitrag eine Grundkonfiguration mit diesem Ansatz gesehen.

Die aus dieser Konfiguration resultierende Entität JdbcUserDetailsManager implementiert auch den UserDetailsService .

Infolgedessen können wir den Schluss ziehen, dass diese Konfiguration einfacher zu implementieren ist, insbesondere wenn wir Spring Boot verwenden, das die DataSource 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 einen benutzerdefinierten Spring-basierten UserDetailsService erstellen, der von persistenten Daten unterstützt wird.

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