Authentication - Username/Password Authentication
Username/Password Authentication
One of the most common ways to authenticate a user is by validating a username and password. Spring Security provides comprehensive support for authenticating with a username and password.
对用户进行身份验证的最常见方法之一是验证用户名和密码。Spring Security 为使用用户名和密码进行身份验证提供了全面的支持。
You can configure username and password authentication using the following:
您可以使用以下方法配置用户名和密码身份验证:
Simple Username/Password Example
@Configuration @EnableWebSecurity public class SecurityConfig { @Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { http .authorizeHttpRequests((authorize) -> authorize .anyRequest().authenticated() ) .httpBasic(Customizer.withDefaults()) .formLogin(Customizer.withDefaults()); return http.build(); } @Bean public UserDetailsService userDetailsService() { UserDetails userDetails = User.withDefaultPasswordEncoder() .username("user") .password("password") .roles("USER") .build(); return new InMemoryUserDetailsManager(userDetails); } }
The preceding configuration automatically registers an in-memory UserDetailsService with the SecurityFilterChain, registers the DaoAuthenticationProvider with the default AuthenticationManager, and enables Form Login and HTTP Basic authentication.
上述配置会自动将内存中的 UserDetailsService 注册到 SecurityFilterChain,将 DaoAuthenticationProvider 注册到默认的 AuthenticationManager,并启用表单登录和 HTTP 基本身份验证。
To learn more about username/password authentication, consider the following use cases:
-
I want to learn how Form Login works 我想了解表单登录的工作原理
-
I want to learn how HTTP Basic authentication works 我想了解 HTTP 基本身份验证的工作原理
-
I want to learn how
DaoAuthenticationProviderworks 我想了解DaoAuthenticationProvider是如何工作的 -
I want to manage users in memory 我想管理内存中的用户
-
I want to manage users in a database 我想管理数据库中的用户
-
I want to manage users in LDAP 我想在 LDAP 中管理用户
-
I want to publish an
AuthenticationManagerbean for custom authentication 我想发布用于自定义身份验证的 AuthenticationManager bean -
I want to customize the global
AuthenticationManager我想自定义全局 AuthenticationManager
Publish an AuthenticationManager bean
A fairly common requirement is publishing an AuthenticationManager bean to allow for custom authentication, such as in a @Service or Spring MVC @Controller. For example, you may want to authenticate users via a REST API instead of using Form Login.
一个相当常见的要求是发布 AuthenticationManager bean 以允许自定义身份验证,例如在 @Service 或 Spring MVC @Controller中。例如,您可能希望通过 REST API 对用户进行身份验证,而不是使用表单登录。
You can publish such an AuthenticationManager for custom authentication scenarios using the following configuration:
您可以使用以下配置为自定义身份验证方案发布此类 AuthenticationManager:
Publish AuthenticationManager bean for Custom Authentication
@Configuration @EnableWebSecurity public class SecurityConfig { @Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { http .authorizeHttpRequests((authorize) -> authorize .requestMatchers("/login").permitAll() .anyRequest().authenticated() ); return http.build(); } @Bean public AuthenticationManager authenticationManager( UserDetailsService userDetailsService, PasswordEncoder passwordEncoder) { DaoAuthenticationProvider authenticationProvider = new DaoAuthenticationProvider(); authenticationProvider.setUserDetailsService(userDetailsService); authenticationProvider.setPasswordEncoder(passwordEncoder); return new ProviderManager(authenticationProvider); } @Bean public UserDetailsService userDetailsService() { UserDetails userDetails = User.withDefaultPasswordEncoder() .username("user") .password("password") .roles("USER") .build(); return new InMemoryUserDetailsManager(userDetails); } @Bean public PasswordEncoder passwordEncoder() { return PasswordEncoderFactories.createDelegatingPasswordEncoder(); } }
With the preceding configuration in place, you can create a @RestController that uses the AuthenticationManager as follows:
完成上述配置后,您可以创建使用 AuthenticationManager 的@RestController,如下所示:
Create a @RestController for Authentication
@RestController public class LoginController { private final AuthenticationManager authenticationManager; public LoginController(AuthenticationManager authenticationManager) { this.authenticationManager = authenticationManager; } @PostMapping("/login") public ResponseEntity<Void> login(@RequestBody LoginRequest loginRequest) { Authentication authenticationRequest = UsernamePasswordAuthenticationToken.unauthenticated(loginRequest.username(), loginRequest.password()); Authentication authenticationResponse = this.authenticationManager.authenticate(authenticationRequest); // ... } public record LoginRequest(String username, String password) { } }
【Note】
In this example, it is your responsibility to save the authenticated user in the SecurityContextRepository if needed. For example, if using the HttpSession to persist the SecurityContext between requests, you can use HttpSessionSecurityContextRepository.
在此示例中,如果需要,您负责将经过身份验证的用户保存在 SecurityContextRepository 中。例如,如果使用 HttpSession 在请求之间保留 SecurityContext,则可以使用 HttpSessionSecurityContextRepository。
Customize the AuthenticationManager
Normally, Spring Security builds an AuthenticationManager internally composed of a DaoAuthenticationProvider for username/password authentication. In certain cases, it may still be desired to customize the instance of AuthenticationManager used by Spring Security. For example, you may need to simply disable credential erasure for cached users.
通常,Spring Security在内部构建了一个AuthenticationManager,该Manager由DaoAuthenticationProvider组成,用于用户名/密码身份验证。在某些情况下,可能仍需要自定义 Spring Security 使用的 AuthenticationManager 实例。例如,您可能只需为缓存用户禁用凭据擦除。
The recommended way to do this is to simply publish your own AuthenticationManager bean, and Spring Security will use it. You can publish an AuthenticationManager using the following configuration:
推荐的方法是简单地发布您自己的 AuthenticationManager bean,Spring Security 将使用它。您可以使用以下配置发布 AuthenticationManager:
Publish AuthenticationManager bean for Spring Security
@Configuration @EnableWebSecurity public class SecurityConfig { @Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { http .authorizeHttpRequests((authorize) -> authorize .requestMatchers("/login").permitAll() .anyRequest().authenticated() ) .httpBasic(Customizer.withDefaults()) .formLogin(Customizer.withDefaults()); return http.build(); } @Bean public AuthenticationManager authenticationManager( UserDetailsService userDetailsService, PasswordEncoder passwordEncoder) { DaoAuthenticationProvider authenticationProvider = new DaoAuthenticationProvider(); authenticationProvider.setUserDetailsService(userDetailsService); authenticationProvider.setPasswordEncoder(passwordEncoder); ProviderManager providerManager = new ProviderManager(authenticationProvider); providerManager.setEraseCredentialsAfterAuthentication(false); return providerManager; } @Bean public UserDetailsService userDetailsService() { UserDetails userDetails = User.withDefaultPasswordEncoder() .username("user") .password("password") .roles("USER") .build(); return new InMemoryUserDetailsManager(userDetails); } @Bean public PasswordEncoder passwordEncoder() { return PasswordEncoderFactories.createDelegatingPasswordEncoder(); } }
Alternatively, you can take advantage of the fact that the AuthenticationManagerBuilder used to build Spring Security’s global AuthenticationManager is published as a bean. You can configure the builder as follows:
或者,您可以利用这样一个事实,即用于构建 Spring Security 的全局 AuthenticationManager 的 AuthenticationManagerBuilder 是作为 Bean 发布的。您可以按如下方式配置构建器:
Configure global AuthenticationManagerBuilder
@Configuration @EnableWebSecurity public class SecurityConfig { @Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { // ... return http.build(); } @Bean public UserDetailsService userDetailsService() { // Return a UserDetailsService that caches users // ... } @Autowired public void configure(AuthenticationManagerBuilder builder) { builder.eraseCredentials(false); } }
Section Summary

浙公网安备 33010602011771号