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

ホームページ Java &#&チュートリアル 柔軟なデータ駆動(dòng)型認(rèn)証のためのカスタム ユーザー詳細(xì)サービスを備えた Spring Authorization サーバー Spring セキュリティ

柔軟なデータ駆動(dòng)型認(rèn)証のためのカスタム ユーザー詳細(xì)サービスを備えた Spring Authorization サーバー Spring セキュリティ

Jan 23, 2025 pm 12:07 PM

Spring認(rèn)可サーバー

Spring Authorization Server は、OAuth 2.1 および OpenID Connect 1.0 仕様、およびその他の関連標(biāo)準(zhǔn)を?qū)g裝するように設(shè)計(jì)されたフレームワークです。 Spring Security 上に構(gòu)築されており、OpenID Connect 1.0 および OAuth2 Authorization Server ソリューションに準(zhǔn)拠した ID プロバイダーを作成するための、安全かつ軽量でカスタマイズ可能な基盤を提供します。

機(jī)能リスト

Spring Security とは何ですか?またどのように機(jī)能しますか?

短い答え
Spring Security は、強(qiáng)力で高度にカスタマイズ可能な認(rèn)証およびアクセス制御フレームワークです。これは、Spring ベースのアプリケーションを保護(hù)するための事実上の標(biāo)準(zhǔn)です。

Spring Security の本質(zhì)は、本質(zhì)的に、堅(jiān)牢な認(rèn)証および認(rèn)可機(jī)能で Web アプリケーションを強(qiáng)化するように設(shè)計(jì)されたサーブレット フィルターのコレクションです。

Spring Security は、Spring Web MVC や Spring Boot などのフレームワークともうまく連攜し、OAuth2 や SAML などの標(biāo)準(zhǔn)をサポートします。ログインおよびログアウト インターフェイスを自動(dòng)的に生成し、CSRF などの一般的なセキュリティ脆弱性からアプリケーションを保護(hù)します。

まあ、それはあまり役に立ちませんね?

Web セキュリティを詳しく調(diào)べて、セキュリティ ワークフローの本質(zhì)を理解しましょう。

Spring Security のエキスパートになるには、まず次の 3 つの中心的な概念を理解する必要があります。

  • 認(rèn)証
  • 承認(rèn)
  • サーブレットフィルター

- このセクションを無(wú)視しないでください。これは、すべての Spring Security 機(jī)能の基礎(chǔ)を築きます。

認(rèn)証

殘高を確認(rèn)したり取引を行ったりするには、オンラインで銀行口座にアクセスする必要があります。通常、これはユーザー名とパスワード

を使用して行われます。

ユーザー: 「私は John Doe です。ユーザー名は johndoe1985 です?!?br> 銀行のシステム: 「本人確認(rèn)を行ってください。パスワードは何ですか?」
ユーザー: 「私のパスワードは: secureB@nk2023 です?!?br> 銀行のシステム: 「ようこそ、John Doe。これがあなたの口座概要です?!?/p>

認(rèn)可

基本的なアプリケーションの場(chǎng)合、認(rèn)証だけで十分な場(chǎng)合があります。ユーザーがログインすると、アプリケーションのすべての領(lǐng)域へのアクセスが許可されます。

ただし、ほとんどのアプリケーションでは、権限またはロールが有効になっています。

ユーザー: 「そのトランザクションで遊ばせてください…。」
銀行のシステム: 「ちょっと待って、最初にあなたの許可を確認(rèn)する必要があります… ..はい、ジョン?ドゥさん、あなたは正しい許可レベルを持っています。楽しんでください?!?br> ユーザー: 「100萬(wàn)送金します、ははは… 冗談です」

サーブレットフィルター

それでは、サーブレット フィルターを見(jiàn)てみましょう。それらは認(rèn)証と認(rèn)可にどのように関係しますか?

サーブレット フィルターを使用する理由
すべての Spring Web アプリケーションは、信頼できる DispatcherServlet という単一のサーブレットを中心に展開(kāi)します。その主な役割は、受信 HTTP リクエスト (ブラウザからのリクエストなど) を処理のために適切な @Controller または @RestController にルーティングすることです。

これが対処法です。DispatcherServlet 自體にはセキュリティ機(jī)能が組み込まれていないため、生の HTTP Basic Auth ヘッダーを @Controller で直接処理したくないでしょう。理想的には、認(rèn)証と認(rèn)可は、リクエストが @Controllers

に到達(dá)する前に処理されるべきです。

幸いなことに、Java Web 環(huán)境では、サーブレットの前にフィルターを配置することでこれを?qū)g現(xiàn)できます。これは、SecurityFilter を作成し、Tomcat (サーブレット コンテナ/アプリケーション サーバー) に設(shè)定して、サーブレットに到達(dá)する前にすべての受信 HTTP リクエストをインターセプトして処理することを検討できることを意味します。

Security context

SecurityFilter にはおよそ 4 つのタスクがあります

  1. まず、フィルターはリクエストからユーザー名/パスワードを抽出する必要があります。これは、Basic Auth HTTP ヘッダー、フォーム フィールド、Cookie などを介して行われる可能性があります。
  2. 次に、フィルターはそのユーザー名とパスワードの組み合わせをデータベースなどの何かと照合して検証する必要があります。
  3. フィルターは、認(rèn)証が成功した後、ユーザーが要求された URI へのアクセスを許可されていることを確認(rèn)する必要があります。
  4. リクエストがこれらすべてのチェックを通過(guò)した場(chǎng)合、フィルターは リクエストは DispatcherServlet、つまり @Controllers に送信されます。

フィルターチェーン

実際には、1 つのフィルターをいくつかに分割し、それらをリンクします。

受信 HTTP リクエストがどのように送信されるかを次に示します:

  1. まず、LoginMethodFilter を通過(guò)します...
  2. 次に、AuthenticationFilter を通過(guò)します...
  3. その後、AuthorizationFilter に移動(dòng)します...
  4. そして最後に、サーブレットに到達(dá)します。

このセットアップはフィルターチェーンとして知られています。

フィルター (またはフィルターのチェーン) を使用すると、@RestControllers または @Controllers のコア実裝を変更することなく、アプリケーション內(nèi)のすべての認(rèn)証および認(rèn)可の課題を効果的に管理できます。

Spring の DefaultSecurityFilterChain

Spring Security を適切に構(gòu)成し、Web アプリケーションを開(kāi)始したと想像してください。次のようなログ メッセージが表示されます:

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]|

その 1 行を展開(kāi)すると、Spring Security が 1 つのフィルターを追加するだけではなく、15 (!) の異なるフィルターを含むフィルター チェーン全體をセットアップしていることがわかります。

HTTP リクエストが到著すると、最終的に @RestControllers に到達(dá)する前に、これらの 15 の各フィルターを順?lè)送ㄟ^(guò)します。リクエストはチェーンの先頭から最後まで処理されるため、これらのフィルターの順序は重要です。

security chain

Spring の FilterChain を分析する

チェーン內(nèi)のすべてのフィルターの詳細(xì)を掘り下げると行き過(guò)ぎてしまいますが、ここではいくつかの主要なフィルターについて説明します。他のものをより深く理解するには、Spring Security のソース コードを調(diào)べてください。

  1. BasicAuthenticationFilter: リクエストで Basic Auth HTTP ヘッダーの検索を試み、見(jiàn)つかった場(chǎng)合は、ヘッダーのユーザー名とパスワードを使用してユーザーの認(rèn)証を試みます。
  2. UsernamePasswordAuthenticationFilter: ユーザー名/パスワードのリクエスト パラメーター/POST 本體の検索を試み、見(jiàn)つかった場(chǎng)合は、それらの値を使用してユーザーの認(rèn)証を試みます。
  3. DefaultLoginPageGeneratingFilter: 機(jī)能を明示的に無(wú)効にしない場(chǎng)合、ログイン ページを生成します。このフィルターは、Spring Security を有効にするときにデフォルトのログイン ページが表示される理由です。
  4. DefaultLogoutPageGeneratingFilter: ログアウト ページを生成します (その機(jī)能を明示的に無(wú)効にしない場(chǎng)合)。
  5. FilterSecurityInterceptor: 承認(rèn)を行います。

ジョーク

質(zhì)問(wèn) - HTTP リクエストが Spring Security フィルターで分割されたのはなぜですか?
答え - だって、近づこうとするたびにフィルターが「ちょっと待って!まず様子を見(jiàn)させてよ!」って言ってたから ?

はい、休憩....おっと、ちょっと待って...一度にしてはセキュリティの話が多すぎました!

Spring認(rèn)可サーバーのセットアップ

Spring Authorization Server の使用を開(kāi)始する最も簡(jiǎn)単な方法は、Spring Boot ベースのアプリケーションを作成することです。 start.spring.io を使用して基本プロジェクトを生成できます。

必要な依存関係は、implementation("org.springframework.boot:spring-boot-starter-oauth2-authorization-server") だけです

さらにアクションを?qū)g行するために、さらに 2 つを追加します

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]|

Spring Security の構(gòu)成方法

最新の Spring Security および/または Spring Boot バージョンでは、Spring Security を構(gòu)成するには、次のクラスを使用します。 @EnableWebSecurity のアノテーションが付けられています。

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) : プロトコル エンドポイントの Spring Security フィルター チェーン。
(2) : 認(rèn)証用の Spring Security フィルター チェーン。
(3) : アクセス トークンに署名するための com.nimbusds.jose.jwk.source.JWKSource のインスタンス。
(4) : 署名されたアクセス トークンをデコードするための JwtDecoder のインスタンス。
(5) : Spring Authorization Server を構(gòu)成するための AuthorizationServerSettings のインスタンス。

アプリケーションへの特定の URL を許可するように CORS を構(gòu)成してみましょう

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
このクラスは、CORS ルールを定義するために使用されます。この場(chǎng)合:

  • addAllowedOrigin("http://localhost:3000/"): http://localhost:3000 からのリクエストを許可します。これは、フロントエンドが別のポートで実行されている場(chǎng)合のローカル開(kāi)発に役立ちます。運(yùn)用環(huán)境では、これを?qū)g際のドメインに置き換えます。
  • addAllowedMethod("*"): すべての HTTP メソッド (GET、POST、PUT、DELETE など) を許可します。
  • addAllowedHeader("*"): リクエスト內(nèi)のすべての HTTP ヘッダーを許可します。

UrlBasedCorsConfigurationSource

  • URL パターン (/** など) を特定の CORS 構(gòu)成にマップするクラス。
  • registerCorsConfiguration("/",configuration): 定義された CORS ルール (構(gòu)成) をアプリケーション內(nèi)のすべてのエンドポイント (/) に適用します。

わあ、たくさんの設(shè)定がありますね!しかし、それが Spring Framework の魔法です。舞臺(tái)裏ですべての重労働を処理します。

クライアントを構(gòu)成する時(shí)が來(lái)ました

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. clientId: アクセスを許可する一意の識(shí)別子
  2. clientAuthenticationMethod : 認(rèn)証方法の定義
  3. redirectUris 定義された URL のみを許可します
  4. authorizationGrantTypes authorization_code

ユーザー詳細(xì)サービス

UserDetailsS??ervice は、ユーザー名、パスワード、およびユーザー名とパスワードで認(rèn)証するためのその他の屬性を取得するために DaoAuthenticationProvider によって使用されます。 Spring Security は、UserDetailsS??ervice のインメモリ、JDBC、およびキャッシュ実裝を提供します。

カスタム UserDetailsS??ervice を Bean として公開(kāi)することで、カスタム認(rèn)証を定義できます。

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

}

アプリケーションを起動(dòng)すると、Spring Authorization Server を使用した OIDC および OAuth2 セットアップが正しく機(jī)能するはずです。ただし、デモやプロトタイピングには適した InMemoryUserDetailsManager を採(cǎi)用していることに気づくでしょう。ただし、運(yùn)用環(huán)境では、アプリケーションの再起動(dòng)時(shí)にすべてのデータが消えるため、これはお?jiǎng)幛幛扦蓼护蟆?/p>

Spring SecurityのJdbcUserDetailsManager

JdbcUserDetailsManager は、JDBC を使用してリレーショナル データベースに接続することでユーザーの資格情報(bào)とロールを処理する Spring Security 內(nèi)の機(jī)能です。アプリケーションが Spring Security が期待するユーザー テーブルの標(biāo)準(zhǔn)スキーマを操作できる場(chǎng)合に理想的です。

Spring security org/springframework/security/core/userdetails/jdbc/users.ddl から入手可能なスキーマ

@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;
    }
}

InMemoryUserDetailsManager から JdbcUserDetailsManager に移行するために必要な唯一の調(diào)整

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]|

この構(gòu)成は、Spring Security の標(biāo)準(zhǔn)テーブル スキーマに準(zhǔn)拠するアプリケーションに効果的です。ただし、カスタマイズする必要がある場(chǎng)合 (ユーザー名の代わりにログインに電子メールを使用するなど)、カスタム UserDetailsS??ervice を?qū)g裝すると、必要な適応性が得られます。

Customer エンティティを使用したカスタム UserDetailsS??ervice

カスタム CustomUserDetailsS??ervice をプロバイダーに追加しましょう。 AuthenticationProvider で、setUserDetailsS??ervice
を使用してカスタム サービスを設(shè)定します。

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")
}

カスタムサービス

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

}

リポジトリ

@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;
    }
}

エンティティ

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

セキュリティフィルターで、Spring Security にこのサービスを使用するように指示する必要があります

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

結(jié)論

ここでは、認(rèn)証を処理するための 2 つの強(qiáng)力な選択肢があります。

  • JdbcUserDetailsManager: アプリケーションが Spring のデフォルト スキーマに準(zhǔn)拠している場(chǎng)合の簡(jiǎn)単なオプションです。
  • Custom UserDetailsS??ervice: 特別なフィールドとロールを管理する柔軟性を提供します。

JdbcUserDetailsManager を選択するか、カスタム UserDetailsS??ervice を?qū)g裝することに決定するかに関係なく、どちらもアプリケーションにスケーラブルなデータベース サポートの認(rèn)証システムを裝備します。

以上が柔軟なデータ駆動(dòng)型認(rèn)証のためのカスタム ユーザー詳細(xì)サービスを備えた Spring Authorization サーバー Spring セキュリティの詳細(xì)內(nèi)容です。詳細(xì)については、PHP 中國(guó)語(yǔ) Web サイトの他の関連記事を參照してください。

このウェブサイトの聲明
この記事の內(nèi)容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰屬します。このサイトは、それに相當(dāng)する法的責(zé)任を負(fù)いません。盜作または侵害の疑いのあるコンテンツを見(jiàn)つけた場(chǎng)合は、admin@php.cn までご連絡(luò)ください。

ホットAIツール

Undress AI Tool

Undress AI Tool

脫衣畫像を無(wú)料で

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード寫真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

寫真から衣服を削除するオンライン AI ツール。

Clothoff.io

Clothoff.io

AI衣類リムーバー

Video Face Swap

Video Face Swap

完全無(wú)料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡(jiǎn)単に交換できます。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無(wú)料のコードエディター

SublimeText3 中國(guó)語(yǔ)版

SublimeText3 中國(guó)語(yǔ)版

中國(guó)語(yǔ)版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強(qiáng)力な PHP 統(tǒng)合開(kāi)発環(huán)境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開(kāi)発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

ハッシュマップとハッシュテーブルの違いは? ハッシュマップとハッシュテーブルの違いは? Jun 24, 2025 pm 09:41 PM

ハッシュマップとハッシュテーブルの違いは、主にスレッドの安全性、ヌル価値のサポート、パフォーマンスに反映されます。 1.スレッドの安全性の観點(diǎn)から、ハッシュテーブルはスレッドセーフであり、その方法はほとんど同期メソッドであり、ハッシュマップはスレッドセーフではない同期処理を?qū)g行しません。 2。ヌル値のサポートに関しては、ハッシュマップは1つのnullキーと複數(shù)のヌル値を許可しますが、ハッシュテーブルはnullキーや値を許可しません。 3.パフォーマンスの観點(diǎn)から、ハッシュマップは同期メカニズムがないため、より効率的です。ハッシュテーブルは、各操作のロックパフォーマンスが低いです。代わりにconcurrenthashmapを使用することをお?jiǎng)幛幛筏蓼埂?/p>

なぜラッパークラスが必要なのですか? なぜラッパークラスが必要なのですか? Jun 28, 2025 am 01:01 AM

Javaは、基本的なデータ型がオブジェクト指向の操作に直接參加できないため、ラッパークラスを使用し、実際のニーズでオブジェクトフォームが必要になることが多いためです。 1.コレクションクラスは、リストが自動(dòng)ボクシングを使用して數(shù)値を保存するなど、オブジェクトのみを保存できます。 2。ジェネリックは基本的なタイプをサポートしておらず、パッケージングクラスはタイプパラメーターとして使用する必要があります。 3.パッケージングクラスは、null値を表して、データまたは欠落データを區(qū)別できます。 4.パッケージングクラスは、データの解析と処理を容易にするための文字列変換などの実用的な方法を提供するため、これらの特性が必要なシナリオでは、パッケージングクラスは不可欠です。

インターフェイスの靜的メソッドとは何ですか? インターフェイスの靜的メソッドとは何ですか? Jun 24, 2025 pm 10:57 PM

StaticMethodsinInterfaceswereIntroducatedinjava8toalowutilityは、interfaceitself.beforejava8、そのような導(dǎo)入のために導(dǎo)入されたコード、rediveTodisorgedCode.now、statecmethodssprovidreebenefits:1)彼らの可能性のある測(cè)定di

JITコンパイラはどのようにコードを最適化しますか? JITコンパイラはどのようにコードを最適化しますか? Jun 24, 2025 pm 10:45 PM

JITコンパイラは、メソッドインライン、ホットスポット検出とコンピレーション、タイプの投機(jī)と偏見(jiàn)、冗長(zhǎng)操作の排除の4つの方法を通じてコードを最適化します。 1。メソッドインラインで呼び出しのオーバーヘッドを減らし、頻繁に小さな方法と呼ばれる挿入をコールに直接直接挿入します。 2。ホットスポットの検出と高周波コードの実行とそれを中央に最適化して、リソースを節(jié)約します。 3。タイプ投機(jī)は、敬v的な呼び出しを達(dá)成するためにランタイムタイプ情報(bào)を収集し、効率を向上させます。 4.冗長(zhǎng)操作は、運(yùn)用データの削除に基づいて役に立たない計(jì)算と検査を排除し、パフォーマンスを向上させます。

インスタンスイニシャルイザーブロックとは何ですか? インスタンスイニシャルイザーブロックとは何ですか? Jun 25, 2025 pm 12:21 PM

インスタンス初期化ブロックは、Javaで使用され、コンストラクターの前に実行されるオブジェクトを作成するときに初期化ロジックを?qū)g行します。複數(shù)のコンストラクターが初期化コード、複雑なフィールド初期化、または匿名のクラス初期化シナリオを共有するシナリオに適しています。靜的初期化ブロックとは異なり、インスタンス化されるたびに実行されますが、靜的初期化ブロックはクラスがロードされたときに1回のみ実行されます。

変數(shù)の「ファイナル」キーワードは何ですか? 変數(shù)の「ファイナル」キーワードは何ですか? Jun 24, 2025 pm 07:29 PM

Injava、thefinalkeywordpreventsavariaibleのValue frombeingededafterassignment、ButiTsbehiviordiffersforprimitivesandobjectReferences

工場(chǎng)のパターンとは何ですか? 工場(chǎng)のパターンとは何ですか? Jun 24, 2025 pm 11:29 PM

ファクトリーモードは、オブジェクトの作成ロジックをカプセル化するために使用され、コードをより柔軟でメンテナンスしやすく、ゆるく結(jié)合します。コアの答えは、オブジェクトの作成ロジックを一元的に管理し、実裝の詳細(xì)を隠し、複數(shù)の関連オブジェクトの作成をサポートすることです。特定の説明は次のとおりです。工場(chǎng)モードは、NewClass()の使用を直接回避し、処理のための特別な工場(chǎng)クラスまたは方法にオブジェクトの作成を手渡します。複數(shù)のタイプの関連オブジェクトが作成され、作成ロジックが変更され、実裝の詳細(xì)を非表示にする必要があるシナリオに適しています。たとえば、支払いプロセッサでは、Stripe、PayPal、その他のインスタンスが工場(chǎng)を通じて作成されます。その実裝には、入力パラメーターに基づいて工場(chǎng)クラスによって返されるオブジェクトが含まれ、すべてのオブジェクトは共通のインターフェイスを?qū)g現(xiàn)します。一般的なバリアントには、単純な工場(chǎng)、工場(chǎng)法、抽象的な工場(chǎng)が含まれます。これらは異なる複雑さに適しています。

タイプキャストとは何ですか? タイプキャストとは何ですか? Jun 24, 2025 pm 11:09 PM

変換には、暗黙的で明示的な変換には2つのタイプがあります。 1.暗黙的な変換は、INTを2倍に変換するなど、自動(dòng)的に発生します。 2。明示的な変換には、(int)mydoubleの使用など、手動(dòng)操作が必要です。タイプ変換が必要な場(chǎng)合には、ユーザー入力の処理、數(shù)學(xué)操作、または関數(shù)間のさまざまなタイプの値の渡されます。注意する必要がある問(wèn)題は次のとおりです。浮動(dòng)小數(shù)點(diǎn)數(shù)を整數(shù)に変換すると、分?jǐn)?shù)部分が切り捨てられ、大きなタイプを小さなタイプに変えるとデータの損失につながる可能性があり、一部の言語(yǔ)では特定のタイプの直接変換ができません。言語(yǔ)変換ルールを適切に理解することは、エラーを回避するのに役立ちます。

See all articles