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

Rumah Java javaTutorial Keselamatan musim bunga pelayan Kebenaran Spring dengan perkhidmatan butiran pengguna tersuai untuk pengesahan dipacu data yang fleksibel

Keselamatan musim bunga pelayan Kebenaran Spring dengan perkhidmatan butiran pengguna tersuai untuk pengesahan dipacu data yang fleksibel

Jan 23, 2025 pm 12:07 PM

Pelayan Kebenaran Spring

Spring Authorization Server ialah rangka kerja yang direka untuk melaksanakan spesifikasi OAuth 2.1 dan OpenID Connect 1.0, bersama-sama dengan piawaian lain yang berkaitan. Dibina pada Spring Security, ia menawarkan asas yang selamat, ringan dan boleh disesuaikan untuk mencipta Penyedia Identiti yang mematuhi penyelesaian OpenID Connect 1.0 dan Pelayan Kebenaran OAuth2.

Senarai Ciri

Apakah Spring Security dan bagaimana ia berfungsi?

jawapan ringkas
Spring Security ialah rangka kerja pengesahan dan kawalan akses yang berkuasa dan boleh disesuaikan. Ia adalah standard de-facto untuk mendapatkan aplikasi berasaskan Spring.

Pada asasnya, Spring Security pada asasnya ialah koleksi penapis servlet yang direka untuk meningkatkan aplikasi web anda dengan ciri pengesahan dan kebenaran yang mantap.

Spring Security juga bercantum dengan baik dengan rangka kerja seperti Spring Web MVC atau Spring Boot, menyokong standard seperti OAuth2 dan SAML. Ia menjana antara muka log masuk dan log keluar secara automatik serta melindungi aplikasi anda daripada kelemahan keselamatan biasa seperti CSRF.

Nah, itu tidak begitu membantu, bukan?

Mari kita mendalami keselamatan web untuk memahami perkara penting aliran kerja keselamatannya.

Untuk menjadi pakar Keselamatan Musim Bunga, anda mesti memahami tiga konsep teras ini dahulu:

  • Pengesahan
  • Keizinan
  • Penapis Servlet

Nota - Jangan memintas bahagian ini; ia meletakkan asas untuk semua fungsi Keselamatan Musim Bunga.

Pengesahan

Anda perlu mengakses akaun bank anda dalam talian untuk menyemak baki anda atau membuat transaksi. Biasanya ini dilakukan menggunakan Nama Pengguna dan Kata Laluan

Pengguna: "Saya John Doe. Nama pengguna saya ialah: johndoe1985."
Sistem Bank: "Sila sahkan identiti anda. Apakah kata laluan anda?"
Pengguna: "Kata laluan saya ialah: secureB@nk2023."
Sistem Bank: "Selamat datang, John Doe. Berikut ialah gambaran keseluruhan akaun anda."

Keizinan

Untuk aplikasi asas, pengesahan sahaja mungkin memadai: Setelah pengguna log masuk, mereka diberikan akses kepada semua kawasan aplikasi.

Walau bagaimanapun, dalam kebanyakan aplikasi, terdapat kebenaran atau peranan yang dimainkan.

Pengguna: "Biar saya bermain dengan transaksi itu …?."
Sistem Bank: "Sekejap, saya perlu menyemak kebenaran anda dahulu...?..ya Encik John Doe, anda mempunyai tahap pelepasan yang betul. Selamat mencuba."
Pengguna: "Saya akan pindahkan 1J ha ha ha …? Gurau-gurau"

Penapis Servlet

Sekarang, mari kita terokai Penapis Servlet. Bagaimanakah ia berkaitan dengan pengesahan dan kebenaran?

Mengapa menggunakan Penapis Servlet?
Setiap aplikasi web Spring berkisar pada satu servlet: DispatcherServlet yang boleh dipercayai. Peranan utamanya ialah untuk menghalakan permintaan HTTP yang masuk (seperti dari penyemak imbas) kepada @Controller atau @RestController yang sesuai untuk pengendalian.

Inilah tawarannya: DispatcherServlet sendiri tidak mempunyai sebarang ciri keselamatan terbina dalam dan anda mungkin tidak mahu mengendalikan pengepala Pengesahan Asas HTTP mentah terus dalam @Controllers anda. Sebaik-baiknya, pengesahan dan kebenaran harus diurus sebelum permintaan sampai kepada @Controllers anda

Nasib baik, dalam persekitaran web Java, anda boleh mencapai ini dengan meletakkan penapis sebelum servlet. Ini bermakna anda boleh mempertimbangkan untuk mencipta SecurityFilter dan menyediakannya dalam Tomcat (bekas servlet/pelayan aplikasi) anda untuk memintas dan memproses setiap permintaan HTTP yang masuk sebelum ia mencapai servlet anda.

Security context

SecurityFilter mempunyai kira-kira 4 tugasan

  1. Pertama, penapis perlu mengekstrak nama pengguna/kata laluan daripada permintaan. Ia boleh melalui Pengepala HTTP Pengesahan Asas, atau medan borang, atau kuki, dsb.
  2. Kemudian penapis perlu mengesahkan gabungan nama pengguna/kata laluan itu terhadap sesuatu, seperti pangkalan data.
  3. Penapis perlu menyemak, selepas pengesahan berjaya, bahawa pengguna dibenarkan untuk mengakses URI yang diminta.
  4. Jika permintaan itu kekal dalam semua pemeriksaan ini, maka penapis boleh l dan permintaan itu dihantar ke DispatcherServlet anda, iaitu @Controllers anda.

Rantai Penapis

Secara praktiknya, kami akan memecahkan satu penapis kepada beberapa, yang kemudiannya akan anda pautkan bersama.

Begini cara permintaan HTTP masuk akan dihantar:

  1. Pertama, ia melalui LoginMethodFilter...
  2. Seterusnya, ia melalui Penapis Pengesahan...
  3. Kemudian, ia beralih ke Penapis Kebenaran...
  4. Dan akhirnya, ia mencapai servlet anda.

Persediaan ini dikenali sebagai Rantaian Penapis.

Dengan menggunakan penapis (atau rangkaian penapis), anda boleh mengurus semua cabaran pengesahan dan kebenaran dalam aplikasi anda dengan berkesan tanpa mengubah pelaksanaan teras @RestControllers atau @Controllers anda.

DefaultSecurityFilterChain Spring

Bayangkan anda telah mengkonfigurasi Spring Security dengan betul dan memulakan aplikasi web anda. Anda akan melihat mesej log yang kelihatan seperti ini:

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

Memperluas satu baris itu mendedahkan bahawa Spring Security bukan sahaja menambah satu penapis—ia menyediakan keseluruhan rantai penapis dengan 15 (!) penapis berbeza.

Apabila permintaan HTTP tiba, ia melalui setiap satu daripada 15 penapis ini dalam urutan sebelum akhirnya mencapai @RestControllers anda. Susunan penapis ini adalah penting, kerana permintaan diproses dari bahagian atas rantai ke bahagian bawah.

security chain

Menganalisis Rantaian Penapis Spring

Menyelami butiran setiap penapis dalam rantai akan membawa kita terlalu jauh, tetapi berikut ialah penjelasan untuk beberapa penapis utama. Untuk pemahaman yang lebih mendalam tentang yang lain, anda boleh menerokai kod sumber Spring Security.

  1. Penapis Pengesahan Asas: Cuba untuk mencari Pengepala HTTP Pengesahan Asas pada permintaan dan jika ditemui, cuba untuk mengesahkan pengguna dengan nama pengguna dan kata laluan pengepala itu.
  2. UsernamePasswordAuthenticationFilter: Cuba mencari parameter permintaan nama pengguna/kata laluan/badan POST dan jika ditemui, cuba untuk mengesahkan pengguna dengan nilai tersebut.
  3. DefaultLoginPageGeneratingFilter: Menjana halaman log masuk untuk anda, jika anda tidak melumpuhkan ciri tersebut secara eksplisit. Penapis INI adalah sebab anda mendapat halaman log masuk lalai apabila mendayakan Spring Security.
  4. DefaultLogoutPageGeneratingFilter: Menjana halaman log keluar untuk anda, jika anda tidak melumpuhkan ciri tersebut secara eksplisit.
  5. FilterSecurityInterceptor: Adakah kebenaran anda.

bergurau

Soalan - Mengapa permintaan HTTP putus dengan penapis Spring Security?
Jawapan - Kerana setiap kali ia cuba mendekat, penapis berkata, "Tunggu! Biar saya periksa awak dulu!" ?

Ya rehat ........ Wah, tunggu... itu terlalu banyak cakap keselamatan untuk sekali gus!

Sediakan pelayan Keizinan Spring

Cara paling mudah untuk mula menggunakan Spring Authorization Server adalah dengan mencipta aplikasi berasaskan Spring Boot. Anda boleh menggunakan start.spring.io untuk menjana projek asas.

Satu-satunya kebergantungan yang diperlukan ialah pelaksanaan("org.springframework.boot:spring-boot-starter-oauth2-authorization-server")

Kami akan menambah dua lagi untuk melakukan lebih banyak tindakan

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

Cara mengkonfigurasi Spring Security

Dengan versi Spring Security dan/atau Spring Boot terkini, cara untuk mengkonfigurasi Spring Security adalah dengan mempunyai kelas yang: Dianotasi dengan @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) : Rantaian penapis Spring Security untuk Titik Akhir Protokol.
(2) : Rantaian penapis Spring Security untuk pengesahan.
(3) : Contoh com.nimbusds.jose.jwk.source.JWKSource untuk menandatangani token akses.
(4) : Contoh JwtDecoder untuk menyahkod token akses bertandatangan.
(5) : Satu contoh AuthorizationServerSettings untuk mengkonfigurasi Spring Authorization Server.

Mari konfigurasikan CORS untuk membenarkan URL tertentu ke aplikasi kami

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
Kelas ini digunakan untuk menentukan peraturan CORS. Dalam kes ini:

  • addAllowedOrigin("http://localhost:3000/"): Membenarkan permintaan daripada http://localhost:3000. Ini berguna untuk pembangunan tempatan apabila bahagian hadapan anda dijalankan pada port yang berbeza. Dalam pengeluaran, gantikan ini dengan domain sebenar anda.
  • addAllowedMethod("*"): Membenarkan semua kaedah HTTP (cth., GET, POST, PUT, DELETE, dll.).
  • addAllowedHeader("*"): Membenarkan semua pengepala HTTP dalam permintaan.

UrlBasedCorsConfigurationSource

  • Kelas yang memetakan corak URL (seperti /**) kepada konfigurasi CORS tertentu.
  • registerCorsConfiguration("/", konfigurasi): Menggunakan peraturan CORS yang ditetapkan (konfigurasi) pada semua titik akhir (/) dalam aplikasi.

Wah, banyak konfigurasi! Tetapi itulah keajaiban Rangka Kerja Musim Bunga—ia mengendalikan semua beban berat di belakang tabir.

Sudah tiba masanya untuk mengkonfigurasi Pelanggan

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

Beberapa perkara yang telah kami lakukan di atas

  1. clientId: Pengecam unik untuk membenarkan akses
  2. clientAuthenticationMethod : Mentakrifkan kaedah Pengesahan
  3. redirectUris Membenarkan hanya URL yang ditakrifkan
  4. authorizationGrantTypes authorization_code

UserDetailsService

UserDetailsService digunakan oleh DaoAuthenticationProvider untuk mendapatkan nama pengguna, kata laluan dan atribut lain untuk mengesahkan dengan nama pengguna dan kata laluan. Spring Security menyediakan pelaksanaan dalam memori, JDBC dan caching bagi UserDetailsService.

Anda boleh menentukan pengesahan tersuai dengan mendedahkan UserDetailsService tersuai sebagai kacang.

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

}

Setelah kami melancarkan aplikasi, persediaan OIDC dan OAuth2 kami dengan Pelayan Kebenaran Spring harus berfungsi dengan betul. Walau bagaimanapun, anda akan perasan kami telah menggunakan InMemoryUserDetailsManager, yang sesuai untuk tunjuk cara atau prototaip. Tetapi untuk persekitaran pengeluaran, ia tidak digalakkan kerana semua data hilang apabila aplikasi dimulakan semula.

JdbcUserDetailsManager dalam Keselamatan Musim Bunga

JdbcUserDetailsManager ialah ciri dalam Spring Security yang menggunakan JDBC untuk mengendalikan kelayakan dan peranan pengguna dengan menyambung ke pangkalan data hubungan. Ia sesuai apabila aplikasi anda boleh berfungsi dengan skema standard untuk jadual pengguna yang dijangkakan oleh Spring Security.

Skema yang tersedia daripada 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;
    }
}

Satu-satunya pelarasan diperlukan untuk beralih daripada InMemoryUserDetailsManager kepada JdbcUserDetailsManager

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

Konfigurasi ini berkesan untuk aplikasi yang melekat pada skema jadual standard Spring Security. Tetapi, jika anda perlu menyesuaikan (seperti menggunakan e-mel untuk log masuk dan bukannya nama pengguna), melaksanakan UserDetailsService tersuai menawarkan kebolehsuaian yang diperlukan.

Custom UserDetailsService dengan Entiti Pelanggan

Mari tambahkan CustomUserDetailsService tersuai kepada pembekal. Dalam AuthenticationProvider tetapkan perkhidmatan tersuai menggunakan setUserDetailsService

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

Perkhidmatan tersuai

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

}

Repositori

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

Entiti

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

Dalam penapis keselamatan kita perlu memberitahu keselamatan musim bunga untuk menggunakan perkhidmatan ini

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

Kesimpulan

Di sini, anda mempunyai dua pilihan yang mantap untuk mengendalikan pengesahan:

  • JdbcUserDetailsManager: Pilihan yang mudah jika aplikasi anda sejajar dengan skema lalai Spring.
  • Perkhidmatan Butiran Pengguna Tersuai: Menyediakan fleksibiliti untuk mengurus medan dan peranan khas.

Tidak kira jika anda memilih JdbcUserDetailsManager atau memutuskan untuk melaksanakan UserDetailsService tersuai, kedua-duanya akan melengkapkan aplikasi anda dengan sistem pengesahan yang disokong pangkalan data berskala.

Atas ialah kandungan terperinci Keselamatan musim bunga pelayan Kebenaran Spring dengan perkhidmatan butiran pengguna tersuai untuk pengesahan dipacu data yang fleksibel. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn

Alat AI Hot

Undress AI Tool

Undress AI Tool

Gambar buka pakaian secara percuma

Undresser.AI Undress

Undresser.AI Undress

Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover

AI Clothes Remover

Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Clothoff.io

Clothoff.io

Penyingkiran pakaian AI

Video Face Swap

Video Face Swap

Tukar muka dalam mana-mana video dengan mudah menggunakan alat tukar muka AI percuma kami!

Alat panas

Notepad++7.3.1

Notepad++7.3.1

Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina

SublimeText3 versi Cina

Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1

Hantar Studio 13.0.1

Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6

Dreamweaver CS6

Alat pembangunan web visual

SublimeText3 versi Mac

SublimeText3 versi Mac

Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Perbezaan antara hashmap dan hashtable? Perbezaan antara hashmap dan hashtable? Jun 24, 2025 pm 09:41 PM

Perbezaan antara hashmap dan hashtable terutamanya dicerminkan dalam keselamatan benang, sokongan nilai null dan prestasi. 1. Dari segi keselamatan benang, hashtable adalah benang selamat, dan kaedahnya kebanyakannya kaedah segerak, sementara hashmap tidak melakukan pemprosesan penyegerakan, yang bukan benang-selamat; 2. Dari segi sokongan nilai null, hashmap membolehkan satu kunci null dan nilai null berbilang, manakala hashtable tidak membenarkan kekunci atau nilai null, jika tidak, nullPointerException akan dibuang; 3. Dari segi prestasi, hashmap lebih cekap kerana tidak ada mekanisme penyegerakan, dan Hashtable mempunyai prestasi penguncian yang rendah untuk setiap operasi. Adalah disyorkan untuk menggunakan ConcurrentHashMap sebaliknya.

Mengapa kita memerlukan kelas pembalut? Mengapa kita memerlukan kelas pembalut? Jun 28, 2025 am 01:01 AM

Java menggunakan kelas pembalut kerana jenis data asas tidak dapat mengambil bahagian secara langsung dalam operasi berorientasikan objek, dan bentuk objek sering diperlukan dalam keperluan sebenar; 1. Kelas koleksi hanya boleh menyimpan objek, seperti senarai menggunakan tinju automatik untuk menyimpan nilai berangka; 2. Generik tidak menyokong jenis asas, dan kelas pembungkusan mesti digunakan sebagai parameter jenis; 3. Kelas pembungkusan boleh mewakili nilai null untuk membezakan data yang tidak tersendiri atau hilang; 4. Kelas pembungkusan menyediakan kaedah praktikal seperti penukaran rentetan untuk memudahkan parsing dan pemprosesan data, jadi dalam senario di mana ciri -ciri ini diperlukan, kelas pembungkusan sangat diperlukan.

Apakah kaedah statik dalam antara muka? Apakah kaedah statik dalam antara muka? Jun 24, 2025 pm 10:57 PM

Staticmethodsininterfaceswereintroducedinjava8toallowutilityfunctionswithintheintheinterfaceitself.beforjava8, SuchfunctionsRequiredseparateHelpereHelperes, LeadingTodisorgaganizedCode.Now, staticmethodethreeKeybeeMeKeBeReSes, staticmethodeDethreeKeybeeMeKeBeReSes, staticmethodethreeKeybeeMeKeKeBeReSes, staticmethodeDethreeKeybeeMeKeKeBeReKeNey

Bagaimanakah pengkompil JIT mengoptimumkan kod? Bagaimanakah pengkompil JIT mengoptimumkan kod? Jun 24, 2025 pm 10:45 PM

Penyusun JIT mengoptimumkan kod melalui empat kaedah: kaedah dalam talian, pengesanan tempat panas dan penyusunan, spekulasi jenis dan devirtualisasi, dan penghapusan operasi yang berlebihan. 1. Kaedah sebaris mengurangkan panggilan overhead dan memasukkan kaedah kecil yang sering dipanggil terus ke dalam panggilan; 2. Pengesanan tempat panas dan pelaksanaan kod frekuensi tinggi dan mengoptimumkannya untuk menjimatkan sumber; 3. Jenis spekulasi mengumpul maklumat jenis runtime untuk mencapai panggilan devirtualisasi, meningkatkan kecekapan; 4. Operasi berlebihan menghapuskan pengiraan dan pemeriksaan yang tidak berguna berdasarkan penghapusan data operasi, meningkatkan prestasi.

Apakah blok inisialisasi contoh? Apakah blok inisialisasi contoh? Jun 25, 2025 pm 12:21 PM

Blok permulaan contoh digunakan dalam Java untuk menjalankan logik inisialisasi apabila membuat objek, yang dilaksanakan sebelum pembina. Ia sesuai untuk senario di mana beberapa pembina berkongsi kod inisialisasi, permulaan medan kompleks, atau senario permulaan kelas tanpa nama. Tidak seperti blok inisialisasi statik, ia dilaksanakan setiap kali ia ditegaskan, manakala blok permulaan statik hanya dijalankan sekali apabila kelas dimuatkan.

Apakah kata kunci `akhir` untuk pembolehubah? Apakah kata kunci `akhir` untuk pembolehubah? Jun 24, 2025 pm 07:29 PM

Injava, thefinalkeywordpreventsavariable'svaluefrombeingchangedafterassignment, butitsbehaviordiffersforprimitivesandobjectreferences.forprimitiveVariables, finalmakesthevalueconstant, asinfinalintmax_speed = 100;

Apakah corak kilang? Apakah corak kilang? Jun 24, 2025 pm 11:29 PM

Mod kilang digunakan untuk merangkum logik penciptaan objek, menjadikan kod lebih fleksibel, mudah dikekalkan, dan ditambah longgar. Jawapan teras adalah: dengan mengurus logik penciptaan objek secara berpusat, menyembunyikan butiran pelaksanaan, dan menyokong penciptaan pelbagai objek yang berkaitan. Keterangan khusus adalah seperti berikut: Mod Kilang menyerahkan penciptaan objek ke kelas kilang khas atau kaedah untuk diproses, mengelakkan penggunaan Newclass () secara langsung; Ia sesuai untuk senario di mana pelbagai jenis objek yang berkaitan dicipta, logik penciptaan boleh berubah, dan butiran pelaksanaan perlu disembunyikan; Sebagai contoh, dalam pemproses pembayaran, jalur, paypal dan contoh lain dicipta melalui kilang -kilang; Pelaksanaannya termasuk objek yang dikembalikan oleh kelas kilang berdasarkan parameter input, dan semua objek menyedari antara muka yang sama; Varian biasa termasuk kilang -kilang mudah, kaedah kilang dan kilang abstrak, yang sesuai untuk kerumitan yang berbeza.

Apakah jenis pemutus? Apakah jenis pemutus? Jun 24, 2025 pm 11:09 PM

Terdapat dua jenis penukaran: tersirat dan eksplisit. 1. Penukaran tersirat berlaku secara automatik, seperti menukar int untuk berganda; 2. Penukaran eksplisit memerlukan operasi manual, seperti menggunakan (int) mydouble. Kes di mana penukaran jenis diperlukan termasuk memproses input pengguna, operasi matematik, atau lulus pelbagai jenis nilai antara fungsi. Isu-isu yang perlu diperhatikan adalah: Mengubah nombor terapung ke dalam bilangan bulat akan memotong bahagian pecahan, mengubah jenis besar menjadi jenis kecil boleh menyebabkan kehilangan data, dan beberapa bahasa tidak membenarkan penukaran langsung jenis tertentu. Pemahaman yang betul tentang peraturan penukaran bahasa membantu mengelakkan kesilapan.

See all articles