??? ??? ?? ??? ?? ??? ?? ??? ?? ?? ???? ?? Spring ?? ?? ??? ??
Jan 23, 2025 pm 12:07 PM??? ?? ??
Spring ?? ??? ?? ?? ??? ?? OAuth 2.1 ? OpenID Connect 1.0 ??? ????? ??? ????????. Spring Security? ?????? ???? OpenID Connect 1.0 ? OAuth2 ?? ?? ???? ???? ID ???? ???? ?? ???? ???? ??? ?? ??? ??? ?????.
?? ??
??? ????? ???? ??? ??????
???
Spring Security? ???? ??? ??? ??? ?? ? ??? ?? ????????. ?? Spring ?? ?????? ??? ?? ???? ?????.
Spring Security? ??? ??? ?? ? ?? ?? ???? ? ??????? ?????? ??? ??? ?? ?????.
Spring Security? ?? Spring Web MVC ?? Spring Boot? ?? ?????? ? ???? OAuth2 ? SAML? ?? ??? ?????. ???? ??? ? ???? ?????? ???? CSRF? ?? ???? ?? ??????? ??????? ?????.
?? ?? ??? ? ????.
? ??? ?? ??? ???? ?? ?????? ??? ??? ?????.
Spring Security ???? ??? ?? ?? ? ?? ?? ??? ???? ???.
- ??
- ??
- ??? ??
?? - ? ??? ???? ???. ?? ?? Spring Security ??? ??? ?????.
??
??? ????? ????? ????? ?? ??? ???? ???. ????? ?? ??? ??? ????? ???? ?????
???: "?? John Doe???. ? ??? ??? johndoe1985???."
?? ???: "??? ?????. ????? ??????"
???: "? ????? secureB@nk2023???."
?? ???: "?????, John Doe. ?? ??? ??? ????."
?? ??
?? ??????? ?? ????? ??? ? ????. ???? ????? ??????? ?? ??? ?? ??? ??? ?????.
??? ???? ???????? ???? ??? ????.
???: "? ??? ???? ?????…?."
?? ???: "????, ?? ??? ??? ???? ???…
???: "100? ??????? ???…? ?? ??"
?? ??? ??? ???????. ?? ? ??? ?? ??? ????
??? ??? ???? ??? ??????
?? Spring ? ??????? ?? ???, ? ??? ? ?? DispatcherServlet? ???? ?????. ?? ??? ???? HTTP ??(?: ????? ??)? ??? @Controller ?? @RestController? ????? ???? ????.
??? ??? ????. DispatcherServlet ???? ?? ??? ???? ?? ??? @Controller?? ?? ?? HTTP ?? ?? ??? ???? ?? ?? ????. ?????? ??? @Controller? ???? ?? ?? ? ??? ????? ???
???? Java ? ????? ??? ?? ??? ???? ?? ??? ? ????. ?, SecurityFilter? ???? ?? Tomcat(??? ????/?????? ??)? ???? ???? ?? HTTP ??? ???? ???? ?? ???? ??? ? ????.
SecurityFilter?? ?? 4?? ??? ????.
- ?? ??? ???? ??? ??/????? ???? ???. ?? ?? HTTP ??, ?? ??, ?? ?? ?? ???? ? ????.
- ?? ?? ??? ??????? ?? ??? ?? ?? ??? ??/???? ??? ???? ???.
- ??? ??? ??? ? ???? ??? URI? ???? ? ?? ??? ??? ???? ???.
- ??? ?? ??? ??? ?? ??? ??? ??? ? ????. ??? DispatcherServlet, ? @Controller? ?????.
????
???? ?? ??? ?? ?? ?? ?? ?? ?????.
?? HTTP ??? ???? ??? ??? ????.
- ?? LoginMethodFilter? ?????...
- ???? AuthenticationFilter? ?????...
- ?? ?? AuthorizationFilter? ?????...
- ??? ???? ?????.
? ??? FilterChain??? ???.
??(?? ?? ??)? ???? @RestController ?? @Controller? ?? ??? ???? ??? ??????? ?? ?? ? ?? ?? ??? ????? ??? ? ????.
Spring? DefaultSecurityFilterChain
Spring Security? ?????? ???? ? ??????? ????? ??? ???. ??? ?? ?? ???? ?????.
2020-02-25 10:24:27.875 INFO 11116 --- [ main] o.s.s.web.DefaultSecurityFilterChain : Creating filter chain: any request, [org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter@46320c9a, org.springframework.security.web.context.SecurityContextPersistenceFilter@4d98e41b, org.springframework.security.web.header.HeaderWriterFilter@52bd9a27, org.springframework.security.web.csrf.CsrfFilter@51c65a43, org.springframework.security.web.authentication.logout.LogoutFilter@124d26ba, org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter@61e86192, org.springframework.security.web.authentication.ui.DefaultLoginPageGeneratingFilter@10980560, org.springframework.security.web.authentication.ui.DefaultLogoutPageGeneratingFilter@32256e68, org.springframework.security.web.authentication.www.BasicAuthenticationFilter@52d0f583, org.springframework.security.web.savedrequest.RequestCacheAwareFilter@5696c927, org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter@5f025000, org.springframework.security.web.authentication.AnonymousAuthenticationFilter@5e7abaf7, org.springframework.security.web.session.SessionManagementFilter@681c0ae6, org.springframework.security.web.access.ExceptionTranslationFilter@15639d09, org.springframework.security.web.access.intercept.FilterSecurityInterceptor@4f7be6c8]|
? ?? ???? Spring Security? ?? ??? ??? ???? ?? ??? 15(!)?? ?? ?? ??? ?? ?? ??? ????? ?? ? ? ????.
HTTP ??? ???? @RestController? ???? ?? ???? 15?? ??? ?? ?????. ??? ??? ??? ??? ????? ??? ??? ??? ?? ?????.
Spring? FilterChain ????
??? ?? ??? ?? ??? ????? ?? ?? ??? ????? ??? ? ?? ?? ??? ?? ?????. ?? ?? ?? ? ?? ??? ?? Spring Security? ?? ??? ??? ? ????.
- BasicAuthenticationFilter: ???? ?? ?? HTTP ??? ???? ????, ???? ??? ??? ??? ????? ???? ????? ?????.
- UsernamePasswordAuthenticationFilter: ??? ??/???? ?? ????/POST ??? ???? ????, ???? ?? ??? ???? ????? ?????.
- DefaultLoginPageGeneratingFilter: ?? ??? ????? ?????? ?? ?? ??? ???? ?????. ? ??? Spring Security? ?????? ? ?? ??? ???? ?? ?????.
- DefaultLogoutPageGeneratingFilter: ?? ??? ????? ?????? ?? ?? ???? ???? ?????.
- FilterSecurityInterceptor: ??? ??? ?????.
??
?? - HTTP ??? ? Spring Security ??? ??????
Spring ?? ?? ??
?? - ?????? ? ??? ??? "??! ?? ?????!"?? ?? ????. ?
Spring Authorization Server ??? ???? ?? ?? ??? Spring Boot ?? ??????? ??? ????. start.spring.io? ???? ?? ????? ??? ? ????.
??? ??? ???? ??("org.springframework.boot:spring-boot-starter-oauth2-authorization-server")???
? ?? ??? ?? 2?? ? ??? ?????
2020-02-25 10:24:27.875 INFO 11116 --- [ main] o.s.s.web.DefaultSecurityFilterChain : Creating filter chain: any request, [org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter@46320c9a, org.springframework.security.web.context.SecurityContextPersistenceFilter@4d98e41b, org.springframework.security.web.header.HeaderWriterFilter@52bd9a27, org.springframework.security.web.csrf.CsrfFilter@51c65a43, org.springframework.security.web.authentication.logout.LogoutFilter@124d26ba, org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter@61e86192, org.springframework.security.web.authentication.ui.DefaultLoginPageGeneratingFilter@10980560, org.springframework.security.web.authentication.ui.DefaultLogoutPageGeneratingFilter@32256e68, org.springframework.security.web.authentication.www.BasicAuthenticationFilter@52d0f583, org.springframework.security.web.savedrequest.RequestCacheAwareFilter@5696c927, org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter@5f025000, org.springframework.security.web.authentication.AnonymousAuthenticationFilter@5e7abaf7, org.springframework.security.web.session.SessionManagementFilter@681c0ae6, org.springframework.security.web.access.ExceptionTranslationFilter@15639d09, org.springframework.security.web.access.intercept.FilterSecurityInterceptor@4f7be6c8]|Spring Security ?? ??
?? Spring Security ?/?? Spring Boot ???? Spring Security? ?????? ??? ??? ?? ???? ???? ????. @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") }(2) : ??? ?? Spring Security ?? ?????.
(3) : ??? ?? ??? ?? com.nimbusds.jose.jwk.source.JWKSource? ????.
(4) : ??? ??? ??? ????? ?? JwtDecoder? ???????.
(5) : Spring Authorization Server? ???? ?? AuthorizationServerSettings? ???????.
??????? ?? URL? ????? CORS? ??? ? ????
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]|
Cors??
? ???? CORS ??? ???? ? ?????. ? ??:
- addAllowedOrigin("http://localhost:3000/"): http://localhost:3000? ??? ?????. ?? ?????? ?? ???? ?? ?? ?? ?? ??? ?????. ??????? ?? ?? ????? ????.
- addAllowedMethod("*"): ?? HTTP ???(?: GET, POST, PUT, DELETE ?)? ?????.
- addAllowedHeader("*"): ??? ?? HTTP ??? ?????.
UrlBasedCorsConfigurationSource
- URL ??(?: /**)? ?? CORS ??? ???? ??????.
- registerCorsConfiguration("/", ??): ??? CORS ??(??)? ??????? ?? ?????(/)? ?????.
?, ??? ?? ???! ??? ??? ?? Spring Framework? ?????. ?? ??? ?? ??? ??? ?????.
?? ?????? ??? ?????.
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") }
??? ??? ? ?? ??
- clientId: ???? ???? ?? ???
- clientAuthenticationMethod : ?? ?? ??
- redirectUris ??? URL? ??
- authorizationGrantTypes ??_??
??? ???????
UserDetailsService? ??? ??, ???? ? ??? ??? ????? ???? ?? ?? ??? ???? ?? DaoAuthenticationProvider?? ?????. Spring Security? UserDetailsService? ????, JDBC ? ?? ??? ?????.
??? ?? UserDetailsService? Bean?? ???? ??? ?? ??? ??? ? ????.
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(); } }
??????? ???? Spring Authorization Server? ??? OIDC ? OAuth2 ??? ???? ???? ???. ??? ??? ????? ??? ??? InMemoryUserDetailsManager? ????? ?? ? ? ????. ??? ???? ????? ??????? ?? ???? ?? ???? ????? ???? ????.
??? ??? JdbcUserDetailsManager
JdbcUserDetailsManager? JDBC? ???? ??? ??????? ???? ??? ?? ??? ??? ???? Spring Security? ?????. ??? ??????? Spring Security? ???? ??? ???? ?? ?? ???? ?? ??? ? ?? ? ??????.
Spring ?? org/springframework/security/core/userdetails/jdbc/users.ddl?? ?? ??? ???
@Configuration public class CorsConfig { @Bean public UrlBasedCorsConfigurationSource corsConfigurationSource() { CorsConfiguration configuration = new CorsConfiguration(); configuration.addAllowedOrigin("http://localhost:3000/"); // Change to specific domains in production configuration.addAllowedMethod("*"); configuration.addAllowedHeader("*"); UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); source.registerCorsConfiguration("/**", configuration); return source; } }
InMemoryUserDetailsManager?? JdbcUserDetailsManager? ???? ? ??? ??? ??
2020-02-25 10:24:27.875 INFO 11116 --- [ main] o.s.s.web.DefaultSecurityFilterChain : Creating filter chain: any request, [org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter@46320c9a, org.springframework.security.web.context.SecurityContextPersistenceFilter@4d98e41b, org.springframework.security.web.header.HeaderWriterFilter@52bd9a27, org.springframework.security.web.csrf.CsrfFilter@51c65a43, org.springframework.security.web.authentication.logout.LogoutFilter@124d26ba, org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter@61e86192, org.springframework.security.web.authentication.ui.DefaultLoginPageGeneratingFilter@10980560, org.springframework.security.web.authentication.ui.DefaultLogoutPageGeneratingFilter@32256e68, org.springframework.security.web.authentication.www.BasicAuthenticationFilter@52d0f583, org.springframework.security.web.savedrequest.RequestCacheAwareFilter@5696c927, org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter@5f025000, org.springframework.security.web.authentication.AnonymousAuthenticationFilter@5e7abaf7, org.springframework.security.web.session.SessionManagementFilter@681c0ae6, org.springframework.security.web.access.ExceptionTranslationFilter@15639d09, org.springframework.security.web.access.intercept.FilterSecurityInterceptor@4f7be6c8]|
? ??? Spring Security? ?? ??? ???? ???? ??????? ??????. ??? ??? ??? ??? ??(?: ???? ??? ?? ?? ???? ???? ??) ??? ?? UserDetailsService? ???? ??? ???? ?????.
?? ???? ?? ??? ?? UserDetailsService
???? ?? CustomUserDetailsService? ??? ?????. AuthenticationProvider?? 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") }
?? ???
@Configuration @EnableWebSecurity public class SecurityConfig { private static final String[] ALLOW_LIST = {"/oauth2/token", "/userinfo"}; //This is primarily configured to handle OAuth2 and OpenID Connect specific endpoints. It sets up the security for the authorization server, handling token endpoints, client authentication, etc. @Bean (1) @Order(1) public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception { OAuth2AuthorizationServerConfigurer authorizationServerConfigurer = OAuth2AuthorizationServerConfigurer.authorizationServer(); http .cors(Customizer.withDefaults()) .authorizeHttpRequests(authz -> authz .requestMatchers(ALLOW_LIST).permitAll() .requestMatchers("/**", "/oauth2/jwks/").hasAuthority("SCOPE_keys.write") .anyRequest() .authenticated()) .securityMatchers(matchers -> matchers.requestMatchers(antMatcher("/oauth2/**"), authorizationServerConfigurer.getEndpointsMatcher())) .with(authorizationServerConfigurer, (authorizationServer) -> authorizationServer .oidc(Customizer.withDefaults())) // Enable OpenID Connect 1.0 // Redirect to the login page when not authenticated from the // authorization endpoint .exceptionHandling((exceptions) -> exceptions .defaultAuthenticationEntryPointFor( new LoginUrlAuthenticationEntryPoint("/login"), new MediaTypeRequestMatcher(MediaType.TEXT_HTML) )) // Accept access tokens for User Info and/or Client Registration .oauth2ResourceServer((oauth2) -> oauth2.jwt(Customizer.withDefaults())); return http.build(); } // This configuration is set up for general application security, handling standard web security features like form login for paths not specifically managed by the OAuth2 configuration. @Bean (2) @Order(2) public SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http) throws Exception { http .authorizeHttpRequests((authorize) -> authorize .requestMatchers("/login", "/error", "/main.css") .permitAll() .anyRequest() .authenticated() ) // Form login handles the redirect to the login page from the // authorization server filter chain .formLogin((login) -> login.loginPage("/login")); return http.build(); } @Bean (3) public JWKSource<SecurityContext> jwkSource() { KeyPair keyPair = generateRsaKey(); RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic(); RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate(); RSAKey rsaKey = new RSAKey.Builder(publicKey) .privateKey(privateKey) .keyID(UUID.randomUUID().toString()) .build(); JWKSet jwkSet = new JWKSet(rsaKey); return new ImmutableJWKSet<>(jwkSet); } private static KeyPair generateRsaKey() { KeyPair keyPair; try { KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA"); keyPairGenerator.initialize(2048); keyPair = keyPairGenerator.generateKeyPair(); } catch (Exception ex) { throw new IllegalStateException(ex); } return keyPair; } @Bean (4) public JwtDecoder jwtDecoder(JWKSource<SecurityContext> jwkSource) { return OAuth2AuthorizationServerConfiguration.jwtDecoder(jwkSource); } @Bean (5) public AuthorizationServerSettings authorizationServerSettings() { return AuthorizationServerSettings .builder() .build(); } }
???
@Configuration public class CorsConfig { @Bean public UrlBasedCorsConfigurationSource corsConfigurationSource() { CorsConfiguration configuration = new CorsConfiguration(); configuration.addAllowedOrigin("http://localhost:3000/"); // Change to specific domains in production configuration.addAllowedMethod("*"); configuration.addAllowedHeader("*"); UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); source.registerCorsConfiguration("/**", configuration); return source; } }
???
@Configuration public class Clients { @Bean public RegisteredClientRepository registeredClientRepository() { RegisteredClient oidcClient = RegisteredClient.withId(UUID.randomUUID().toString()) .clientId("stomble") .clientAuthenticationMethod(ClientAuthenticationMethod.NONE) .authorizationGrantTypes(types -> { types.add(AuthorizationGrantType.AUTHORIZATION_CODE); types.add(AuthorizationGrantType.REFRESH_TOKEN); }) .redirectUris(redirectUri -> { redirectUri.add("http://localhost:3000"); redirectUri.add("https://oauth.pstmn.io/v1/callback"); redirectUri.add("http://localhost:3000/signin-callback"); }) .postLogoutRedirectUri("http://localhost:3000") .scopes(score -> { score.add(OidcScopes.OPENID); score.add(OidcScopes.PROFILE); score.add(OidcScopes.EMAIL); }) .clientSettings(ClientSettings.builder() .requireAuthorizationConsent(false) .requireProofKey(true) .build()) .build(); return new InMemoryRegisteredClientRepository(oidcClient); } }
?? ???? ??? Spring Security?? ? ???? ????? ???? ???
.clientAuthentication(clientAuth -> clientAuth.authenticationProvider(authenticationProvider))
@Configuration public class UserConfig { @Bean public UserDetailsService userDetailsService(PasswordEncoder passwordEncoder) { UserDetails userDetailFirst = User.builder() .username("user1") .password(passwordEncoder.encode("password")) .roles("USER") .build(); UserDetails userDetailSecond = User.builder() .username("user2") .password(passwordEncoder.encode("password")) .roles("USER") .build(); return new InMemoryUserDetailsManager(List.of(userDetailFirst, userDetailSecond)); } } @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); }
??
???? ?? ??? ?? ? ?? ??? ??? ????.
- JdbcUserDetailsManager: ??????? Spring? ?? ???? ???? ?? ??? ?????.
- Custom UserDetailsService: ?? ?? ? ??? ??? ? ?? ???? ?????.
JdbcUserDetailsManager? ????? ??? ?? UserDetailsService? ????? ?????? ? ? ??????? ?? ??? ?????? ?? ?? ???? ?????.
? ??? ??? ??? ?? ??? ?? ??? ?? ??? ?? ?? ???? ?? Spring ?? ?? ??? ??? ?? ?????. ??? ??? PHP ??? ????? ?? ?? ??? ?????!

? AI ??

Undress AI Tool
??? ???? ??

Undresser.AI Undress
???? ?? ??? ??? ?? AI ?? ?

AI Clothes Remover
???? ?? ???? ??? AI ?????.

Clothoff.io
AI ? ???

Video Face Swap
??? ??? AI ?? ?? ??? ???? ?? ???? ??? ?? ????!

?? ??

??? ??

???++7.3.1
???? ?? ?? ?? ???

SublimeText3 ??? ??
??? ??, ???? ?? ????.

???? 13.0.1 ???
??? PHP ?? ?? ??

???? CS6
??? ? ?? ??

SublimeText3 Mac ??
? ??? ?? ?? ?????(SublimeText3)

??? ??











?? ?? ?? ??? ??? ?? ??? ??, ? ? ?? ? ??? ?????. 1. ??? ?? ???? ?? ???? ???-????, ? ??? ??? ??? ? ????, Hashmap? ???-??? ?? ??? ??? ???? ????. 2. NULL ? ?? ???? HashMap? ??? NULL ?? ?? ? ?? ???? ?? HashTable? NULL ?? ?? ???? ??? NullPointerException? ?????. 3. ????? ??? ????? ?? ??? ?? ?? ? ????? HashTable? ? ??? ?? ?? ??? ????. ?? ConcurrenTashMap? ???? ?? ????.

Java? ?? ??? ??? ?? ??? ??? ?? ??? ??? ?? ??? ?? ?? ??? ???? ??? ?? ???? ?????. 1. ??? ???? ??? ?? ?? ? ???? ?? ??? ???? ?? ?? ??? ? ????. 2. ???? ?? ??? ???? ??? ?? ???? ?? ?? ??? ???????. 3. ?? ???? ?? ?? ?? ? ???? ???? ?? NULL ?? ??? ? ????. 4. ?? ???? ??? ?? ?? ? ??? ?????? ?? ??? ??? ?? ?? ??? ????? ??? ??? ??? ??????? ?? ???? ??????.

staticmethodsininterfaceswereIntRectionSelffacesswithinteffaceswithinteffaceswithintintinjava8toallowutilityFunctionswithinterfaceitswithinteffaceswithinterfaceffaces

JIT ????? ??? ???, ??? ?? ? ???, ?? ?? ? ???? ? ? ?? ?? ??? ? ?? ??? ?? ??? ??????. 1. ??? ???? ?? ?? ??? ??? ?? ?? ???? ??? ?? ?????. 2. ??? ?? ? ??? ?? ?? ? ??? ???? ?? ?? ???; 3. ?? ??? ??? ?? ??? ???? ???? ???? ? ?? ?? ??? ?????. 4. ?? ??? ?? ??? ??? ???? ???? ?? ? ??? ???? ?? ??? ?????.

???? ??? ??? Java?? ??? ?? ???? ??? ?? ? ? ??? ??? ???? ? ?????. ?? ???? ??? ??, ??? ?? ??? ?? ?? ??? ??? ????? ???? ????? ?????. ?? ??? ??? ??, ????? ? ??? ????, ?? ??? ??? ?????? ? ?? ? ?? ?????.

injava, thefinalkeywordpreventsavariable'svalue'svalueffrombeingchangedafterassignment, butitsbehaviordiffersforprimitivesandobjectreences.forprimitivevariables, asinfinalintmax_speed = 100; wherereassoncesanerror.forobjectref

??? ??? ?? ?? ??? ????? ? ???? ????? ???? ?? ???? ?? ???? ?????. ?? ??? ??? ????. ?? ?? ?? ??? ???? ???? ?? ?? ??? ??? ?? ?? ??? ??? ?????. ?? ??? ??? ????. ?? ??? ?? ??? ?? ?? ??? ?? ?? ??? ???? NewClass ()? ??? ?? ???? ????. ?? ??? ?? ??? ???? ?? ??? ?? ? ? ??? ?? ?? ??? ????? ????? ?????. ?? ??, ?? ?????? ?????, ??? ? ?? ????? ??? ?? ?????. ???? ?? ?? ??? ???? ?? ???? ?? ? ??? ???? ?? ??? ?? ?????? ?????. ???? ???? ??? ??, ?? ?? ? ?? ??? ????, ?? ?? ???? ?????.

??? ? ?? ??? ???? : ????? ?? ?. 1. int? ???? ???? ?? ?? ?? ? ??? ???? ?????. 2. ?? ? ???? (int) myDouble ??? ?? ?? ??? ?????. ?? ??? ??? ?? ??? ?? ??, ?? ?? ?? ???? ?? ??? ?? ???? ?? ?????. ???? ? ??? ??? ????. ?? ??? ??? ??? ??? ??? ?? ??? ??? ? ??? ?? ???? ??? ??? ??? ??? ? ??? ?? ??? ?? ??? ?? ?? ? ? ????. ?? ?? ??? ?? ??? ??? ??? ??? ? ??????.
