


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!

Javaremainsagoodlanguageduetoitscontinuousevolutionandrobustecosystem.1)

Javaisgreatduetoitsplatformindantrect, robustoopsupport, extensivelibraries, andstrongcommunity.1) platformindependenceviajvmallowscodetorunonvariousplatforms.2)

Lima ciri utama Java adalah polimorfisme, ekspresi lambda, streamsapi, generik dan pengendalian pengecualian. 1. Polimorfisme membolehkan objek kelas yang berbeza digunakan sebagai objek kelas asas biasa. 2. Ekspresi Lambda menjadikan kod lebih ringkas, terutama sesuai untuk mengendalikan koleksi dan aliran. 3.StreamsAPI dengan cekap memproses set data yang besar dan menyokong operasi deklaratif. 4. Generik menyediakan jenis keselamatan dan kebolehgunaan semula, dan kesilapan jenis ditangkap semasa penyusunan. 5. Pengendalian Pengecualian membantu mengendalikan kesilapan dengan elegan dan menulis perisian yang boleh dipercayai.

Java'stopfeaturessignificantelyedhanceitsperformanceAndscalability.1) Objek-OrientedPrincipleslikePolymorphismenableFlexiBleyDscalableCode.2)

Komponen teras JVM termasuk ClassLoader, Runtimedataarea dan ExecutionEngine. 1) Pemuat kelas bertanggungjawab untuk memuatkan, menghubungkan dan memulakan kelas dan antara muka. 2) Runtimedataarea mengandungi Methodarea, Heap, Stack, Pcregister dan Nativemethodstacks. 3) ExecutionEngine terdiri daripada penterjemah, Jitcompiler dan GarbageCollector, yang bertanggungjawab untuk pelaksanaan dan pengoptimuman bytecode.

Java'sSafetyandSecurityArebolsteredby: 1) Strongtyping, whichPreventStype-RelatedErrors; 2) AutomaticMemoryManagementViagriageGecollection, reducingMemory-RelatedVulnerabilities;

JavaoffersSeveralkeyfeaturesthatenHanceCodingsKills: 1) Objek-OrientedProgrammingallowSmodelingReal-Worldentities, exemplifiedBypolymorphism.2) ExceptleHandlingProvidesRobusRrormAragement.3)

TheJvmisacrucialComponentthatrunsjavacodeByTranslatingitintomachine-specificinstructions, impak, keselamatan, andporability.1) theclassloaderloads, pautan, andinitializesclasses.2)


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

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

Artikel Panas

Alat panas

Hantar Studio 13.0.1
Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver Mac版
Alat pembangunan web visual

MantisBT
Mantis ialah alat pengesan kecacatan berasaskan web yang mudah digunakan yang direka untuk membantu dalam pengesanan kecacatan produk. Ia memerlukan PHP, MySQL dan pelayan web. Lihat perkhidmatan demo dan pengehosan kami.

SublimeText3 versi Cina
Versi Cina, sangat mudah digunakan

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