国产av日韩一区二区三区精品,成人性爱视频在线观看,国产,欧美,日韩,一区,www.成色av久久成人,2222eeee成人天堂

Heim Java javaLernprogramm Spring-Autorisierungsserver-Spring-Sicherheit mit benutzerdefiniertem Benutzerdetaildienst für flexible datengesteuerte Authentifizierung

Spring-Autorisierungsserver-Spring-Sicherheit mit benutzerdefiniertem Benutzerdetaildienst für flexible datengesteuerte Authentifizierung

Jan 23, 2025 pm 12:07 PM

Spring-Autorisierungsserver

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

Was ist Spring Security und wie funktioniert es?

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:

  • Authentifizierung
  • Autorisierung
  • Servlet-Filter

Hinweis - überspringen Sie diesen Abschnitt nicht; Es legt den Grundstein für alle Funktionalit?ten von Spring Security.

Authentifizierung

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.“

Genehmigung

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“

Servlet-Filter

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.

Security context

Ein SecurityFilter hat ungef?hr 4 Aufgaben

  1. Zuerst muss der Filter einen Benutzernamen/ein Passwort aus der Anfrage extrahieren. Dies kann über einen Basic Auth-HTTP-Header, Formularfelder, ein Cookie usw. erfolgen.
  2. Dann muss der Filter diese Kombination aus Benutzername und Passwort anhand einer Datenbank validieren.
  3. Der Filter muss nach erfolgreicher Authentifizierung prüfen, ob der Benutzer berechtigt ist, auf den angeforderten URI zuzugreifen.
  4. Wenn die Anfrage alle diese Prüfungen übersteht, kann der Filter l Und die Anfrage wird an Ihr DispatcherServlet weitergeleitet, d. h. an Ihre @Controller.

FilterChains

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:

  1. Zuerst durchl?uft es einen LoginMethodFilter...
  2. Als n?chstes durchl?uft es einen AuthenticationFilter...
  3. Dann wird es zu einem AuthorizationFilter verschoben...
  4. Und schlie?lich erreicht es Ihr Servlet.

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.

Springs DefaultSecurityFilterChain

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.

security chain

Analyse der FilterChain von Spring

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.

  1. BasicAuthenticationFilter: Versucht, einen Basic Auth-HTTP-Header in der Anfrage zu finden, und versucht, wenn er gefunden wird, den Benutzer mit dem Benutzernamen und dem Passwort des Headers zu authentifizieren.
  2. UsernamePasswordAuthenticationFilter: Versucht, einen Benutzernamen/Passwort-Anforderungsparameter/POST-Text zu finden und, falls gefunden, versucht, den Benutzer mit diesen Werten zu authentifizieren.
  3. DefaultLoginPageGeneratingFilter: Erstellt eine Anmeldeseite für Sie, wenn Sie diese Funktion nicht explizit deaktivieren. DIESER Filter ist der Grund, warum Sie beim Aktivieren von Spring Security eine Standard-Anmeldeseite erhalten.
  4. DefaultLogoutPageGeneratingFilter: Erstellt eine Abmeldeseite für Sie, wenn Sie diese Funktion nicht explizit deaktivieren.
  5. FilterSecurityInterceptor: Erfüllt Ihre Autorisierung.

Witz

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!

Richten Sie den Spring-Autorisierungsserver ein

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:

  • addAllowedOrigin("http://localhost:3000/"): Erm?glicht Anfragen von http://localhost:3000. Dies ist nützlich für die lokale Entwicklung, wenn Ihr Frontend auf einem anderen Port l?uft. Ersetzen Sie dies in der Produktion durch Ihre tats?chlichen Dom?nen.
  • addAllowedMethod("*"): Erm?glicht alle HTTP-Methoden (z. B. GET, POST, PUT, DELETE usw.).
  • addAllowedHeader("*"): Erlaubt alle HTTP-Header in Anfragen.

UrlBasedCorsConfigurationSource

  • Eine Klasse, die URL-Muster (wie /**) bestimmten CORS-Konfigurationen zuordnet.
  • registerCorsConfiguration("/", Konfiguration): Wendet die definierten CORS-Regeln (Konfiguration) auf alle Endpunkte (/) in der Anwendung an.

Wow, das ist eine Menge Konfiguration! Aber das ist die Magie des Spring Frameworks – es übernimmt die ganze schwere Arbeit hinter den Kulissen.

Es ist Zeit, die Clients zu konfigurieren

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

  1. clientId: Eine eindeutige Kennung, um den Zugriff zu erm?glichen
  2. clientAuthenticationMethod: Definieren der Authentifizierungsmethode
  3. redirectUris Nur die definierten URLs zulassen
  4. authorizationGrantTypesauthorization_code

UserDetailsService

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.

InMemoryUserDetailsManager

@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 in Spring Security

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.

Benutzerdefinierter UserDetailsService mit einer Kundenentit?t

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();
}

Abschluss

Hier haben Sie zwei robuste M?glichkeiten für die Handhabung der Authentifizierung:

  • JdbcUserDetailsManager: Eine unkomplizierte Option, wenn Ihre Anwendung mit dem Standardschema von Spring übereinstimmt.
  • Benutzerdefinierter UserDetailsService: Bietet die Flexibilit?t, spezielle Felder und Rollen zu verwalten.

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!

Erkl?rung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn

Hei?e KI -Werkzeuge

Undress AI Tool

Undress AI Tool

Ausziehbilder kostenlos

Undresser.AI Undress

Undresser.AI Undress

KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover

AI Clothes Remover

Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Clothoff.io

Clothoff.io

KI-Kleiderentferner

Video Face Swap

Video Face Swap

Tauschen Sie Gesichter in jedem Video mühelos mit unserem v?llig kostenlosen KI-Gesichtstausch-Tool aus!

Hei?e Werkzeuge

Notepad++7.3.1

Notepad++7.3.1

Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version

SublimeText3 chinesische Version

Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1

Senden Sie Studio 13.0.1

Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6

Dreamweaver CS6

Visuelle Webentwicklungstools

SublimeText3 Mac-Version

SublimeText3 Mac-Version

Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

Unterschied zwischen Hashmap und Hashtable? Unterschied zwischen Hashmap und Hashtable? Jun 24, 2025 pm 09:41 PM

Der Unterschied zwischen HashMap und Hashtable spiegelt sich haupts?chlich in der Gewindesicherheit, der Nullwertunterstützung und der Leistung wider. 1. In Bezug auf die Gewindesicherheit ist Hashtable Thread-Safe, und seine Methoden sind haupts?chlich Synchronmethoden, w?hrend HashMap keine Synchronisationsverarbeitung durchführt, die nicht mit Thread-Safe ist. 2. In Bezug auf die Nullwertunterstützung erm?glicht HashMap einen Nullschlüssel und mehrere Nullwerte, w?hrend Hashtable keine Nullschlüssel oder -Werte zul?sst, sonst wird eine Nullpointerexception geworfen. 3. In Bezug auf die Leistung ist HashMap effizienter, da kein Synchronisationsmechanismus vorhanden ist und Hashtable für jeden Vorgang eine niedrige Verriegelungsleistung aufweist. Es wird empfohlen, stattdessen eine Concurrenthashmap zu verwenden.

Warum brauchen wir Wrapper -Klassen? Warum brauchen wir Wrapper -Klassen? Jun 28, 2025 am 01:01 AM

Java verwendet Wrapper-Klassen, da grundlegende Datentypen nicht direkt an objektorientierten Operationen teilnehmen k?nnen und Objektformen h?ufig in den tats?chlichen Bedürfnissen erforderlich sind. 1. Sammelklassen k?nnen nur Objekte speichern, z. B. Listen verwenden automatische Boxen, um numerische Werte zu speichern. 2. Generika unterstützen keine Grundtypen, und Verpackungsklassen müssen als Typparameter verwendet werden. 3.. Verpackungsklassen k?nnen Nullwerte darstellen, um nicht festgelegte oder fehlende Daten zu unterscheiden. 4. Verpackungsklassen bieten praktische Methoden wie String -Conversion, um die Analyse und Verarbeitung von Daten zu erleichtern. In Szenarien, in denen diese Eigenschaften ben?tigt werden, sind Verpackungsklassen unverzichtbar.

Was sind statische Methoden in Schnittstellen? Was sind statische Methoden in Schnittstellen? Jun 24, 2025 pm 10:57 PM

StaticMethodsinInterfaces -reisEtroducucuedInjava8toalloytilityFunctionSwitHinTheInterfaceItEp.beejava8, solche Funktionen, dieseparatehelperklassen, führendemTodisorganizedCode.Now, StaticMetheSprovidreefits: 1) theeneNableable -theenableaby

Wie optimiert JIT Compiler den Code? Wie optimiert JIT Compiler den Code? Jun 24, 2025 pm 10:45 PM

Der JIT -Compiler optimiert den Code durch vier Methoden: Methode Inline, Hotspot -Erkennung und -vergleich, Typespekulation und Devirtualisation sowie die Eliminierung des redundanten Betriebs. 1. Methode Inline reduziert den Anrufaufwand und fügt h?ufig kleine Methoden direkt in den Anruf ein. 2. Erkennung und Hochfrequenzcodeausführung und zentral optimieren, um Ressourcen zu sparen. 3. Typ Spekulation sammelt Informationen zum Laufzeittyp, um Devirtualisation -Anrufe zu erzielen und die Effizienz zu verbessern. 4. Redundante Operationen beseitigen nutzlose Berechnungen und Inspektionen basierend auf den Betriebsdaten, wodurch die Leistung verbessert wird.

Was ist ein Instanz -Initialisiererblock? Was ist ein Instanz -Initialisiererblock? Jun 25, 2025 pm 12:21 PM

Instanzinitialisierungsbl?cke werden in Java verwendet, um die Initialisierungslogik beim Erstellen von Objekten auszuführen, die vor dem Konstruktor ausgeführt werden. Es ist für Szenarien geeignet, in denen mehrere Konstruktoren Initialisierungscode, komplexe Feldinitialisierung oder anonyme Szenarien der Klasseninitialisierung teilen. Im Gegensatz zu statischen Initialisierungsbl?cken wird es jedes Mal ausgeführt, wenn es instanziiert wird, w?hrend statische Initialisierungsbl?cke nur einmal ausgeführt werden, wenn die Klasse geladen wird.

Was ist das 'Final' -Styword für Variablen? Was ist das 'Final' -Styword für Variablen? Jun 24, 2025 pm 07:29 PM

InvaVa, theFinalKeywordPreventsAvariable von ValueFromBeingumedAfterasssignment, ButitsBehaviordiffersForprimitive und ANSPRIMITIVEVARIABLE, FinalMakesthevalueconstant, AsinfinalIntmax_speed = 100; WhirerastsignmentcausaSesSaSesSaSesSaSaSesSaSesSaSaSesSaSaSesSaSesSesirror

Was ist das Fabrikmuster? Was ist das Fabrikmuster? Jun 24, 2025 pm 11:29 PM

Der Werksmodus wird verwendet, um die Logik der Objekterstellung zusammenzufassen, wodurch der Code flexibler, einfach zu pflegen und locker gekoppelt ist. Die Kernantwort lautet: Durch zentrales Verwalten von Logik der Objekterstellung, das Ausblenden von Implementierungsdetails und die Unterstützung der Erstellung mehrerer verwandter Objekte. Die spezifische Beschreibung lautet wie folgt: Der Fabrikmodus gibt Objekterstellung an eine spezielle Fabrikklasse oder -methode zur Verarbeitung und vermeidet die Verwendung von NewClass () direkt; Es ist für Szenarien geeignet, in denen mehrere Arten von verwandten Objekten erstellt werden, die Erstellungslogik sich ?ndern und Implementierungsdetails versteckt werden müssen. Zum Beispiel werden im Zahlungsabwickler Stripe, PayPal und andere Instanzen durch Fabriken erstellt. Die Implementierung umfasst das von der Fabrikklasse zurückgegebene Objekt basierend auf Eingabeparametern, und alle Objekte erkennen eine gemeinsame Schnittstelle. Gemeinsame Varianten umfassen einfache Fabriken, Fabrikmethoden und abstrakte Fabriken, die für unterschiedliche Komplexit?ten geeignet sind.

Was ist Typ Casting? Was ist Typ Casting? Jun 24, 2025 pm 11:09 PM

Es gibt zwei Arten von Konvertierung: implizit und explizit. 1. Die implizite Umwandlung erfolgt automatisch, wie z. B. das Konvertieren in INT in Doppel; 2. Explizite Konvertierung erfordert einen manuellen Betrieb, z. B. die Verwendung (int) MyDouble. Ein Fall, in dem die Typ -Konvertierung erforderlich ist, umfasst die Verarbeitung von Benutzereingaben, mathematische Operationen oder das übergeben verschiedener Werte zwischen Funktionen. Probleme, die beachtet werden müssen, sind: Umdrehung von Gleitpunktzahlen in Ganzzahlen wird der fraktionale Teil abschneiden, gro?e Typen in kleine Typen zu einem Datenverlust führen, und einige Sprachen erm?glichen keine direkte Konvertierung bestimmter Typen. Ein ordnungsgem??es Verst?ndnis der Regeln der Sprachkonvertierung hilft, Fehler zu vermeiden.

See all articles