


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.
SecurityFilter mempunyai kira-kira 4 tugasan
- Pertama, penapis perlu mengekstrak nama pengguna/kata laluan daripada permintaan. Ia boleh melalui Pengepala HTTP Pengesahan Asas, atau medan borang, atau kuki, dsb.
- Kemudian penapis perlu mengesahkan gabungan nama pengguna/kata laluan itu terhadap sesuatu, seperti pangkalan data.
- Penapis perlu menyemak, selepas pengesahan berjaya, bahawa pengguna dibenarkan untuk mengakses URI yang diminta.
- 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:
- Pertama, ia melalui LoginMethodFilter...
- Seterusnya, ia melalui Penapis Pengesahan...
- Kemudian, ia beralih ke Penapis Kebenaran...
- 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.
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.
- 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.
- UsernamePasswordAuthenticationFilter: Cuba mencari parameter permintaan nama pengguna/kata laluan/badan POST dan jika ditemui, cuba untuk mengesahkan pengguna dengan nilai tersebut.
- 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.
- DefaultLogoutPageGeneratingFilter: Menjana halaman log keluar untuk anda, jika anda tidak melumpuhkan ciri tersebut secara eksplisit.
- 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
- clientId: Pengecam unik untuk membenarkan akses
- clientAuthenticationMethod : Mentakrifkan kaedah Pengesahan
- redirectUris Membenarkan hanya URL yang ditakrifkan
- 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(); } } </securitycontext></securitycontext>
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(); } } </securitycontext></securitycontext>
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!

Artikel ini menganalisis empat kerangka JavaScript teratas (React, Angular, Vue, Svelte) pada tahun 2025, membandingkan prestasi, skalabilitas, dan prospek masa depan mereka. Walaupun semuanya kekal dominan kerana komuniti dan ekosistem yang kuat, popul mereka yang relatif

Artikel ini menangani kelemahan CVE-2022-1471 dalam Snakeyaml, kecacatan kritikal yang membolehkan pelaksanaan kod jauh. Ia memperincikan bagaimana peningkatan aplikasi boot musim bunga ke snakeyaml 1.33 atau lebih lama mengurangkan risiko ini, menekankan bahawa kemas kini ketergantungan

Artikel ini membincangkan pelaksanaan caching pelbagai peringkat di Java menggunakan kafein dan cache jambu untuk meningkatkan prestasi aplikasi. Ia meliputi persediaan, integrasi, dan faedah prestasi, bersama -sama dengan Pengurusan Dasar Konfigurasi dan Pengusiran PRA Terbaik

Kelas kelas Java melibatkan pemuatan, menghubungkan, dan memulakan kelas menggunakan sistem hierarki dengan bootstrap, lanjutan, dan pemuat kelas aplikasi. Model delegasi induk memastikan kelas teras dimuatkan dahulu, yang mempengaruhi LOA kelas tersuai

Node.js 20 dengan ketara meningkatkan prestasi melalui penambahbaikan enjin V8, terutamanya pengumpulan sampah yang lebih cepat dan I/O. Ciri -ciri baru termasuk sokongan webassembly yang lebih baik dan alat penyahpepijatan halus, meningkatkan produktiviti pemaju dan kelajuan aplikasi.

Iceberg, format meja terbuka untuk dataset analitik yang besar, meningkatkan prestasi data dan skalabiliti. Ia menangani batasan parket/orc melalui pengurusan metadata dalaman, membolehkan evolusi skema yang cekap, perjalanan masa, serentak w

Artikel ini meneroka mengintegrasikan pengaturcaraan berfungsi ke dalam Java menggunakan ekspresi Lambda, API Streams, rujukan kaedah, dan pilihan. Ia menyoroti faedah seperti kebolehbacaan dan kebolehkerjaan kod yang lebih baik melalui kesimpulan dan kebolehubahan

Artikel ini membincangkan menggunakan JPA untuk pemetaan objek-relasi dengan ciri-ciri canggih seperti caching dan pemuatan malas. Ia meliputi persediaan, pemetaan entiti, dan amalan terbaik untuk mengoptimumkan prestasi sambil menonjolkan potensi perangkap. [159 aksara]


Alat AI Hot

Undresser.AI Undress
Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover
Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool
Gambar buka pakaian secara percuma

Clothoff.io
Penyingkiran pakaian AI

AI Hentai Generator
Menjana ai hentai secara percuma.

Artikel Panas

Alat panas

Dreamweaver Mac版
Alat pembangunan web visual

SublimeText3 Linux versi baharu
SublimeText3 Linux versi terkini

SublimeText3 versi Cina
Versi Cina, sangat mudah digunakan

SublimeText3 versi Inggeris
Disyorkan: Versi Win, menyokong gesaan kod!

ZendStudio 13.5.1 Mac
Persekitaran pembangunan bersepadu PHP yang berkuasa
