Der Spring Authorization Server ist ein Framework zur Implementierung der OAuth 2.1- und OpenID Connect 1.0-Spezifikationen sowie anderer verwandter Standards. Es basiert auf Spring Security und bietet eine sichere, leichte und anpassbare Grundlage für die Erstellung von Identitätsanbietern, die mit OpenID Connect 1.0- und OAuth2-Autorisierungsserver-Lösungen kompatibel sind.
Funktionsliste
kurze Antwort
Spring Security ist ein leistungsstarkes und hochgradig anpassbares Authentifizierungs- und Zugriffskontroll-Framework. Es ist der De-facto-Standard für die Sicherung von Spring-basierten Anwendungen.
Im Kern ist Spring Security im Wesentlichen eine Sammlung von Servlet-Filtern, die Ihre Webanwendung mit robusten Authentifizierungs- und Autorisierungsfunktionen erweitern sollen.
Spring Security lässt sich auch gut mit Frameworks wie Spring Web MVC oder Spring Boot kombinieren und unterstützt Standards wie OAuth2 und SAML. Es generiert automatisch Anmelde- und Abmeldeschnittstellen und schützt Ihre Anwendung vor häufigen Sicherheitslücken wie CSRF.
Nun, das ist nicht sehr hilfreich, oder?
Lassen Sie uns tiefer in die Websicherheit eintauchen, um die Grundlagen ihres Sicherheitsworkflows zu verstehen.
Um ein Spring Security-Experte zu werden, müssen Sie zunächst diese drei Kernkonzepte verstehen:
Hinweis - Überspringen Sie diesen Abschnitt nicht; Es legt den Grundstein für alle Funktionalitäten von Spring Security.
Sie müssen online auf Ihr Bankkonto zugreifen, um Ihren Kontostand zu überprüfen oder eine Transaktion durchzuführen. Normalerweise erfolgt dies mit Benutzername und Passwort
Benutzer: „Ich bin John Doe. Mein Benutzername ist: johndoe1985.“
System der Bank: „Bitte überprüfen Sie Ihre Identität. Wie lautet Ihr Passwort?“
Benutzer: „Mein Passwort lautet: secureB@nk2023.“
System der Bank: „Willkommen, John Doe. Hier ist Ihre Kontoübersicht.“
Für Basisanwendungen kann allein die Authentifizierung ausreichen: Sobald sich ein Benutzer anmeldet, erhält er Zugriff auf alle Bereiche der Anwendung.
In den meisten Anwendungen spielen jedoch Berechtigungen oder Rollen eine Rolle.
Benutzer: „Lass mich mit dieser Transaktion spielen ….“
System der Bank: „Eine Sekunde, ich muss zuerst Ihre Berechtigungen überprüfen …..Ja, Herr John Doe, Sie haben die richtige Freigabestufe. Viel Spaß.“
Benutzer: „Ich überweise 1 Mio. ha ha ha … Scherz, Scherz“
Lassen Sie uns nun Servlet-Filter erkunden. In welcher Beziehung stehen sie zur Authentifizierung und Autorisierung?
Warum Servlet-Filter verwenden?
Jede Spring-Webanwendung dreht sich um ein einziges Servlet: das vertrauenswürdige DispatcherServlet. Seine Hauptaufgabe besteht darin, eingehende HTTP-Anfragen (z. B. von einem Browser) zur Verarbeitung an den entsprechenden @Controller oder @RestController weiterzuleiten.
Hier ist der Deal: Das DispatcherServlet selbst verfügt über keine integrierten Sicherheitsfunktionen, und Sie möchten wahrscheinlich keine rohen HTTP Basic Auth-Header direkt in Ihren @Controllern verarbeiten. Im Idealfall sollte die Authentifizierung und Autorisierung erledigt sein, bevor eine Anfrage überhaupt Ihre @Controller erreicht
Glücklicherweise können Sie dies in der Java-Webumgebung erreichen, indem Sie Filter vor Servlets platzieren. Dies bedeutet, dass Sie erwägen könnten, einen SecurityFilter zu erstellen und ihn in Ihrem Tomcat (Servlet-Container/Anwendungsserver) einzurichten, um jede eingehende HTTP-Anfrage abzufangen und zu verarbeiten, bevor sie Ihr Servlet erreicht.
Ein SecurityFilter hat ungefähr 4 Aufgaben
In der Praxis würden wir einen einzelnen Filter in mehrere aufteilen, die Sie dann miteinander verknüpfen würden.
So würde eine eingehende HTTP-Anfrage weitergeleitet werden:
Dieses Setup wird als FilterChain bezeichnet.
Durch die Verwendung eines Filters (oder einer Filterkette) können Sie alle Authentifizierungs- und Autorisierungsherausforderungen in Ihrer Anwendung effektiv verwalten, ohne die Kernimplementierung Ihrer @RestControllers oder @Controllers zu ändern.
Stellen Sie sich vor, Sie haben Spring Security richtig konfiguriert und Ihre Webanwendung gestartet. Sie werden eine Protokollmeldung bemerken, die so aussieht:
2020-02-25 10:24:27.875 INFO 11116 --- [ main] o.s.s.web.DefaultSecurityFilterChain : Creating filter chain: any request, [org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter@46320c9a, org.springframework.security.web.context.SecurityContextPersistenceFilter@4d98e41b, org.springframework.security.web.header.HeaderWriterFilter@52bd9a27, org.springframework.security.web.csrf.CsrfFilter@51c65a43, org.springframework.security.web.authentication.logout.LogoutFilter@124d26ba, org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter@61e86192, org.springframework.security.web.authentication.ui.DefaultLoginPageGeneratingFilter@10980560, org.springframework.security.web.authentication.ui.DefaultLogoutPageGeneratingFilter@32256e68, org.springframework.security.web.authentication.www.BasicAuthenticationFilter@52d0f583, org.springframework.security.web.savedrequest.RequestCacheAwareFilter@5696c927, org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter@5f025000, org.springframework.security.web.authentication.AnonymousAuthenticationFilter@5e7abaf7, org.springframework.security.web.session.SessionManagementFilter@681c0ae6, org.springframework.security.web.access.ExceptionTranslationFilter@15639d09, org.springframework.security.web.access.intercept.FilterSecurityInterceptor@4f7be6c8]|
Das Erweitern dieser einzelnen Zeile zeigt, dass Spring Security nicht nur einen Filter hinzufügt, sondern eine ganze Filterkette mit 15 (!) verschiedenen Filtern einrichtet.
Wenn eine HTTP-Anfrage eintrifft, durchläuft sie nacheinander jeden dieser 15 Filter, bevor sie schließlich Ihre @RestControllers erreicht. Die Reihenfolge dieser Filter ist entscheidend, da die Anfrage von oben nach unten in der Kette verarbeitet wird.
Es würde zu weit führen, auf die Details jedes Filters in der Kette einzugehen, aber hier finden Sie Erklärungen für einige wichtige Filter. Für ein tieferes Verständnis der anderen können Sie den Quellcode von Spring Security erkunden.
Frage - Warum brach die HTTP-Anfrage mit dem Spring Security-Filter zusammen?
Antwort - Denn jedes Mal, wenn es versuchte, näher zu kommen, sagte der Filter: „Warte! Lass mich dich zuerst überprüfen!“ ?Ja Pause ........ Whoa, warte... das war viel zu viel Sicherheitsgerede für einen einzigen Versuch!
Der einfachste Weg, mit der Verwendung von Spring Authorization Server zu beginnen, ist die Erstellung einer Spring Boot-basierten Anwendung. Sie können start.spring.io verwenden, um ein Basisprojekt zu generieren.
Die einzige erforderliche Abhängigkeit ist die Implementierung("org.springframework.boot:spring-boot-starter-oauth2-authorization-server")
Wir werden zwei weitere hinzufügen, um mehr Action zu machen
2020-02-25 10:24:27.875 INFO 11116 --- [ main] o.s.s.web.DefaultSecurityFilterChain : Creating filter chain: any request, [org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter@46320c9a, org.springframework.security.web.context.SecurityContextPersistenceFilter@4d98e41b, org.springframework.security.web.header.HeaderWriterFilter@52bd9a27, org.springframework.security.web.csrf.CsrfFilter@51c65a43, org.springframework.security.web.authentication.logout.LogoutFilter@124d26ba, org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter@61e86192, org.springframework.security.web.authentication.ui.DefaultLoginPageGeneratingFilter@10980560, org.springframework.security.web.authentication.ui.DefaultLogoutPageGeneratingFilter@32256e68, org.springframework.security.web.authentication.www.BasicAuthenticationFilter@52d0f583, org.springframework.security.web.savedrequest.RequestCacheAwareFilter@5696c927, org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter@5f025000, org.springframework.security.web.authentication.AnonymousAuthenticationFilter@5e7abaf7, org.springframework.security.web.session.SessionManagementFilter@681c0ae6, org.springframework.security.web.access.ExceptionTranslationFilter@15639d09, org.springframework.security.web.access.intercept.FilterSecurityInterceptor@4f7be6c8]|
So konfigurieren Sie Spring Security
Mit den neuesten Spring Security- und/oder Spring Boot-Versionen können Sie Spring Security über eine Klasse konfigurieren, die: mit @EnableWebSecurity annotiert ist.
dependencies { implementation("org.springframework.boot:spring-boot-starter-oauth2-authorization-server") implementation("org.springframework.boot:spring-boot-starter-webflux") implementation("org.springframework.boot:spring-boot-starter-validation") }
(1) : Eine Spring Security-Filterkette für die Protokollendpunkte.
(2): Eine Spring Security-Filterkette zur Authentifizierung.
(3): Eine Instanz von com.nimbusds.jose.jwk.source.JWKSource zum Signieren von Zugriffstokens.
(4): Eine Instanz von JwtDecoder zum Dekodieren signierter Zugriffstoken.
(5): Eine Instanz von AuthorizationServerSettings zum Konfigurieren von Spring Authorization Server.
Lasst uns CORS so konfigurieren, dass bestimmte URLs zu unserer Anwendung zugelassen werden
2020-02-25 10:24:27.875 INFO 11116 --- [ main] o.s.s.web.DefaultSecurityFilterChain : Creating filter chain: any request, [org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter@46320c9a, org.springframework.security.web.context.SecurityContextPersistenceFilter@4d98e41b, org.springframework.security.web.header.HeaderWriterFilter@52bd9a27, org.springframework.security.web.csrf.CsrfFilter@51c65a43, org.springframework.security.web.authentication.logout.LogoutFilter@124d26ba, org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter@61e86192, org.springframework.security.web.authentication.ui.DefaultLoginPageGeneratingFilter@10980560, org.springframework.security.web.authentication.ui.DefaultLogoutPageGeneratingFilter@32256e68, org.springframework.security.web.authentication.www.BasicAuthenticationFilter@52d0f583, org.springframework.security.web.savedrequest.RequestCacheAwareFilter@5696c927, org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter@5f025000, org.springframework.security.web.authentication.AnonymousAuthenticationFilter@5e7abaf7, org.springframework.security.web.session.SessionManagementFilter@681c0ae6, org.springframework.security.web.access.ExceptionTranslationFilter@15639d09, org.springframework.security.web.access.intercept.FilterSecurityInterceptor@4f7be6c8]|
CorsConfiguration
Diese Klasse wird zum Definieren der CORS-Regeln verwendet. In diesem Fall:
UrlBasedCorsConfigurationSource
Wow, das ist eine Menge Konfiguration! Aber das ist die Magie des Spring Frameworks – es übernimmt die ganze schwere Arbeit hinter den Kulissen.
dependencies { implementation("org.springframework.boot:spring-boot-starter-oauth2-authorization-server") implementation("org.springframework.boot:spring-boot-starter-webflux") implementation("org.springframework.boot:spring-boot-starter-validation") }
Einige Dinge, die wir oben getan haben
UserDetailsService wird von DaoAuthenticationProvider zum Abrufen eines Benutzernamens, eines Passworts und anderer Attribute für die Authentifizierung mit einem Benutzernamen und einem Passwort verwendet. Spring Security bietet In-Memory-, JDBC- und Caching-Implementierungen von UserDetailsService.
Sie können eine benutzerdefinierte Authentifizierung definieren, indem Sie einen benutzerdefinierten UserDetailsService als Bean verfügbar machen.
@Configuration @EnableWebSecurity public class SecurityConfig { private static final String[] ALLOW_LIST = {"/oauth2/token", "/userinfo"}; //This is primarily configured to handle OAuth2 and OpenID Connect specific endpoints. It sets up the security for the authorization server, handling token endpoints, client authentication, etc. @Bean (1) @Order(1) public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception { OAuth2AuthorizationServerConfigurer authorizationServerConfigurer = OAuth2AuthorizationServerConfigurer.authorizationServer(); http .cors(Customizer.withDefaults()) .authorizeHttpRequests(authz -> authz .requestMatchers(ALLOW_LIST).permitAll() .requestMatchers("/**", "/oauth2/jwks/").hasAuthority("SCOPE_keys.write") .anyRequest() .authenticated()) .securityMatchers(matchers -> matchers.requestMatchers(antMatcher("/oauth2/**"), authorizationServerConfigurer.getEndpointsMatcher())) .with(authorizationServerConfigurer, (authorizationServer) -> authorizationServer .oidc(Customizer.withDefaults())) // Enable OpenID Connect 1.0 // Redirect to the login page when not authenticated from the // authorization endpoint .exceptionHandling((exceptions) -> exceptions .defaultAuthenticationEntryPointFor( new LoginUrlAuthenticationEntryPoint("/login"), new MediaTypeRequestMatcher(MediaType.TEXT_HTML) )) // Accept access tokens for User Info and/or Client Registration .oauth2ResourceServer((oauth2) -> oauth2.jwt(Customizer.withDefaults())); return http.build(); } // This configuration is set up for general application security, handling standard web security features like form login for paths not specifically managed by the OAuth2 configuration. @Bean (2) @Order(2) public SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http) throws Exception { http .authorizeHttpRequests((authorize) -> authorize .requestMatchers("/login", "/error", "/main.css") .permitAll() .anyRequest() .authenticated() ) // Form login handles the redirect to the login page from the // authorization server filter chain .formLogin((login) -> login.loginPage("/login")); return http.build(); } @Bean (3) public JWKSource<SecurityContext> jwkSource() { KeyPair keyPair = generateRsaKey(); RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic(); RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate(); RSAKey rsaKey = new RSAKey.Builder(publicKey) .privateKey(privateKey) .keyID(UUID.randomUUID().toString()) .build(); JWKSet jwkSet = new JWKSet(rsaKey); return new ImmutableJWKSet<>(jwkSet); } private static KeyPair generateRsaKey() { KeyPair keyPair; try { KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA"); keyPairGenerator.initialize(2048); keyPair = keyPairGenerator.generateKeyPair(); } catch (Exception ex) { throw new IllegalStateException(ex); } return keyPair; } @Bean (4) public JwtDecoder jwtDecoder(JWKSource<SecurityContext> jwkSource) { return OAuth2AuthorizationServerConfiguration.jwtDecoder(jwkSource); } @Bean (5) public AuthorizationServerSettings authorizationServerSettings() { return AuthorizationServerSettings .builder() .build(); } }
Sobald wir die Anwendung starten, sollte unser OIDC- und OAuth2-Setup mit Spring Authorization Server ordnungsgemäß funktionieren. Sie werden jedoch feststellen, dass wir InMemoryUserDetailsManager verwendet haben, der sich gut für Demos oder Prototyping eignet. Für eine Produktionsumgebung ist dies jedoch nicht ratsam, da alle Daten beim Neustart der Anwendung verschwinden.
JdbcUserDetailsManager ist eine Funktion in Spring Security, die JDBC verwendet, um Benutzeranmeldeinformationen und -rollen durch Herstellen einer Verbindung zu einer relationalen Datenbank zu verwalten. Ideal ist es, wenn Ihre Anwendung mit dem Standardschema für Benutzertabellen arbeiten kann, das Spring Security erwartet.
Das Schema, das unter Spring security org/springframework/security/core/userdetails/jdbc/users.ddl verfügbar ist
@Configuration public class CorsConfig { @Bean public UrlBasedCorsConfigurationSource corsConfigurationSource() { CorsConfiguration configuration = new CorsConfiguration(); configuration.addAllowedOrigin("http://localhost:3000/"); // Change to specific domains in production configuration.addAllowedMethod("*"); configuration.addAllowedHeader("*"); UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); source.registerCorsConfiguration("/**", configuration); return source; } }
Die einzige Anpassung, die für den Übergang von InMemoryUserDetailsManager zu JdbcUserDetailsManager erforderlich ist
2020-02-25 10:24:27.875 INFO 11116 --- [ main] o.s.s.web.DefaultSecurityFilterChain : Creating filter chain: any request, [org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter@46320c9a, org.springframework.security.web.context.SecurityContextPersistenceFilter@4d98e41b, org.springframework.security.web.header.HeaderWriterFilter@52bd9a27, org.springframework.security.web.csrf.CsrfFilter@51c65a43, org.springframework.security.web.authentication.logout.LogoutFilter@124d26ba, org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter@61e86192, org.springframework.security.web.authentication.ui.DefaultLoginPageGeneratingFilter@10980560, org.springframework.security.web.authentication.ui.DefaultLogoutPageGeneratingFilter@32256e68, org.springframework.security.web.authentication.www.BasicAuthenticationFilter@52d0f583, org.springframework.security.web.savedrequest.RequestCacheAwareFilter@5696c927, org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter@5f025000, org.springframework.security.web.authentication.AnonymousAuthenticationFilter@5e7abaf7, org.springframework.security.web.session.SessionManagementFilter@681c0ae6, org.springframework.security.web.access.ExceptionTranslationFilter@15639d09, org.springframework.security.web.access.intercept.FilterSecurityInterceptor@4f7be6c8]|
Diese Konfiguration ist effektiv für Anwendungen, die sich an das Standardtabellenschema von Spring Security halten. Wenn Sie jedoch Anpassungen vornehmen müssen (z. B. die Verwendung einer E-Mail-Adresse anstelle eines Benutzernamens für die Anmeldung), bietet die Implementierung eines benutzerdefinierten UserDetailsService die erforderliche Anpassungsfähigkeit.
Fügen wir dem Anbieter einen benutzerdefinierten CustomUserDetailsService hinzu. Legen Sie im AuthenticationProvider den benutzerdefinierten Dienst mit setUserDetailsService
fest
dependencies { implementation("org.springframework.boot:spring-boot-starter-oauth2-authorization-server") implementation("org.springframework.boot:spring-boot-starter-webflux") implementation("org.springframework.boot:spring-boot-starter-validation") }
Kundenspezifischer Service
@Configuration @EnableWebSecurity public class SecurityConfig { private static final String[] ALLOW_LIST = {"/oauth2/token", "/userinfo"}; //This is primarily configured to handle OAuth2 and OpenID Connect specific endpoints. It sets up the security for the authorization server, handling token endpoints, client authentication, etc. @Bean (1) @Order(1) public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception { OAuth2AuthorizationServerConfigurer authorizationServerConfigurer = OAuth2AuthorizationServerConfigurer.authorizationServer(); http .cors(Customizer.withDefaults()) .authorizeHttpRequests(authz -> authz .requestMatchers(ALLOW_LIST).permitAll() .requestMatchers("/**", "/oauth2/jwks/").hasAuthority("SCOPE_keys.write") .anyRequest() .authenticated()) .securityMatchers(matchers -> matchers.requestMatchers(antMatcher("/oauth2/**"), authorizationServerConfigurer.getEndpointsMatcher())) .with(authorizationServerConfigurer, (authorizationServer) -> authorizationServer .oidc(Customizer.withDefaults())) // Enable OpenID Connect 1.0 // Redirect to the login page when not authenticated from the // authorization endpoint .exceptionHandling((exceptions) -> exceptions .defaultAuthenticationEntryPointFor( new LoginUrlAuthenticationEntryPoint("/login"), new MediaTypeRequestMatcher(MediaType.TEXT_HTML) )) // Accept access tokens for User Info and/or Client Registration .oauth2ResourceServer((oauth2) -> oauth2.jwt(Customizer.withDefaults())); return http.build(); } // This configuration is set up for general application security, handling standard web security features like form login for paths not specifically managed by the OAuth2 configuration. @Bean (2) @Order(2) public SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http) throws Exception { http .authorizeHttpRequests((authorize) -> authorize .requestMatchers("/login", "/error", "/main.css") .permitAll() .anyRequest() .authenticated() ) // Form login handles the redirect to the login page from the // authorization server filter chain .formLogin((login) -> login.loginPage("/login")); return http.build(); } @Bean (3) public JWKSource<SecurityContext> jwkSource() { KeyPair keyPair = generateRsaKey(); RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic(); RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate(); RSAKey rsaKey = new RSAKey.Builder(publicKey) .privateKey(privateKey) .keyID(UUID.randomUUID().toString()) .build(); JWKSet jwkSet = new JWKSet(rsaKey); return new ImmutableJWKSet<>(jwkSet); } private static KeyPair generateRsaKey() { KeyPair keyPair; try { KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA"); keyPairGenerator.initialize(2048); keyPair = keyPairGenerator.generateKeyPair(); } catch (Exception ex) { throw new IllegalStateException(ex); } return keyPair; } @Bean (4) public JwtDecoder jwtDecoder(JWKSource<SecurityContext> jwkSource) { return OAuth2AuthorizationServerConfiguration.jwtDecoder(jwkSource); } @Bean (5) public AuthorizationServerSettings authorizationServerSettings() { return AuthorizationServerSettings .builder() .build(); } }
Repository
@Configuration public class CorsConfig { @Bean public UrlBasedCorsConfigurationSource corsConfigurationSource() { CorsConfiguration configuration = new CorsConfiguration(); configuration.addAllowedOrigin("http://localhost:3000/"); // Change to specific domains in production configuration.addAllowedMethod("*"); configuration.addAllowedHeader("*"); UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); source.registerCorsConfiguration("/**", configuration); return source; } }
Entität
@Configuration public class Clients { @Bean public RegisteredClientRepository registeredClientRepository() { RegisteredClient oidcClient = RegisteredClient.withId(UUID.randomUUID().toString()) .clientId("stomble") .clientAuthenticationMethod(ClientAuthenticationMethod.NONE) .authorizationGrantTypes(types -> { types.add(AuthorizationGrantType.AUTHORIZATION_CODE); types.add(AuthorizationGrantType.REFRESH_TOKEN); }) .redirectUris(redirectUri -> { redirectUri.add("http://localhost:3000"); redirectUri.add("https://oauth.pstmn.io/v1/callback"); redirectUri.add("http://localhost:3000/signin-callback"); }) .postLogoutRedirectUri("http://localhost:3000") .scopes(score -> { score.add(OidcScopes.OPENID); score.add(OidcScopes.PROFILE); score.add(OidcScopes.EMAIL); }) .clientSettings(ClientSettings.builder() .requireAuthorizationConsent(false) .requireProofKey(true) .build()) .build(); return new InMemoryRegisteredClientRepository(oidcClient); } }
Im Sicherheitsfilter müssen wir Spring Security anweisen, diesen Dienst zu nutzen
.clientAuthentication(clientAuth -> clientAuth.authenticationProvider(authenticationProvider))
@Configuration public class UserConfig { @Bean public UserDetailsService userDetailsService(PasswordEncoder passwordEncoder) { UserDetails userDetailFirst = User.builder() .username("user1") .password(passwordEncoder.encode("password")) .roles("USER") .build(); UserDetails userDetailSecond = User.builder() .username("user2") .password(passwordEncoder.encode("password")) .roles("USER") .build(); return new InMemoryUserDetailsManager(List.of(userDetailFirst, userDetailSecond)); } } @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); }
Hier haben Sie zwei robuste Möglichkeiten für die Handhabung der Authentifizierung:
Ganz gleich, ob Sie sich für JdbcUserDetailsManager entscheiden oder sich für die Implementierung eines benutzerdefinierten UserDetailsService entscheiden, beides stattet Ihre Anwendung mit einem skalierbaren, datenbankgestützten Authentifizierungssystem aus.
Das obige ist der detaillierte Inhalt vonSpring-Autorisierungsserver-Spring-Sicherheit mit benutzerdefiniertem Benutzerdetaildienst für flexible datengesteuerte Authentifizierung. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!