Username/Password Authentication
验证用户最常见的方法之一是验证用户名和密码。Spring Security 全面支持使用用户名和密码进行验证。
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.
您可以使用以下内容配置用户名和密码验证:
You can configure username and password authentication using the following:
-
Java
-
XML
-
Kotlin
@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);
}
}
<http>
<intercept-url pattern="/**" access="authenticated"/>
<form-login />
<http-basic />
<user-service>
<user name="user"
password="{noop}password"
authorities="ROLE_USER" />
</user-service>
</http>
import org.springframework.security.config.annotation.web.invoke
@Configuration
@EnableWebSecurity
class SecurityConfig {
@Bean
fun securityFilterChain(http: HttpSecurity): SecurityFilterChain {
http {
authorizeHttpRequests {
authorize(anyRequest, authenticated)
}
formLogin { }
httpBasic { }
}
return http.build()
}
@Bean
fun userDetailsService(): UserDetailsService {
val user = User.withDefaultPasswordEncoder()
.username("user")
.password("password")
.roles("USER")
.build()
return InMemoryUserDetailsManager(user)
}
}
前面的配置会使用 SecurityFilterChain`自动注册一个 in-memory `UserDetailsService
,使用默认 AuthenticationManager
注册 DaoAuthenticationProvider
,并启用 Form Login和 HTTP Basic身份验证。
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.
如欲了解用户名/密码验证的更多信息,请考虑以下用例:
To learn more about username/password authentication, consider the following use cases:
-
I want to learn how Form Login works
-
I want to manage users in memory
-
I want to manage users in a database
-
I want to manage users in LDAP
-
I want to publish-authentication-manager-bean for custom authentication
-
I want to customize-global-authentication-manager
Publish an AuthenticationManager
bean
一个相当普遍的需求是发布一个`AuthenticationManager`bean以允许自定义身份验证,比如`@Service`或 Spring MVC `@Controller`中的身份验证。例如,您可能想要通过 REST API 而不是使用Form Login来对用户进行身份验证。
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
:
You can publish such an AuthenticationManager
for custom authentication scenarios using the following configuration:
AuthenticationManager
bean for Custom Authentication-
Java
-
XML
-
Kotlin
@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();
}
}
<http>
<intercept-url pattern="/login" access="permitAll"/>
<intercept-url pattern="/**" access="authenticated"/>
<bean id="authenticationManager"
class="org.springframework.security.authentication.ProviderManager">
<constructor-arg>
<bean class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">
<property name="userDetailsService" ref="userDetailsService" />
<property name="passwordEncoder" ref="passwordEncoder" />
</bean>
</constructor-arg>
</bean>
<user-service id="userDetailsService">
<user name="user"
password="{noop}password"
authorities="ROLE_USER" />
</user-service>
<bean id="passwordEncoder"
class="org.springframework.security.crypto.factory.PasswordEncoderFactories" factory-method="createDelegatingPasswordEncoder"/>
</http>
import org.springframework.security.config.annotation.web.invoke
@Configuration
@EnableWebSecurity
class SecurityConfig {
@Bean
fun securityFilterChain(http: HttpSecurity): SecurityFilterChain {
http {
authorizeHttpRequests {
authorize("/login", permitAll)
authorize(anyRequest, authenticated)
}
}
return http.build()
}
@Bean
fun authenticationManager(
userDetailsService: UserDetailsService,
passwordEncoder: PasswordEncoder): AuthenticationManager {
val authenticationProvider = DaoAuthenticationProvider()
authenticationProvider.setUserDetailsService(userDetailsService)
authenticationProvider.setPasswordEncoder(passwordEncoder)
return ProviderManager(authenticationProvider)
}
@Bean
fun userDetailsService(): UserDetailsService {
val user = User.withDefaultPasswordEncoder()
.username("user")
.password("password")
.roles("USER")
.build()
return InMemoryUserDetailsManager(user)
}
@Bean
fun passwordEncoder(): PasswordEncoder {
return PasswordEncoderFactories.createDelegatingPasswordEncoder()
}
}
在先前配置就位后,您可以创建这样使用的 @RestController
AuthenticationManager
:
With the preceding configuration in place, you can create a @RestController
that uses the AuthenticationManager
as follows:
@RestController
for Authentication-
Java
-
Kotlin
@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) {
}
}
@RestController
class LoginController(val authenticationManager: AuthenticationManager) {
@PostMapping("/login")
fun login(@RequestBody loginRequest: LoginRequest): ResponseEntity<Void> {
val authenticationRequest =
UsernamePasswordAuthenticationToken.unauthenticated(
loginRequest.username, loginRequest.password)
val authenticationResponse =
authenticationManager.authenticate(authenticationRequest)
// ...
}
data class LoginRequest(val username: String, val password: String)
}
在本示例中,您有责任在需要时将经过身份验证的用户保存在 In this example, it is your responsibility to save the authenticated user in the |
Customize the AuthenticationManager
通常,Spring Security 已构建内部包含用于用户名/密码身份验证的 AuthenticationManager
的 DaoAuthenticationProvider
。在某些情况下,可能仍需要自定义 Spring Security 所使用的 AuthenticationManager
的实例。例如,您可能需要为缓存用户简单禁用 credential erasure。
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.
执行此操作的推荐方法是仅发布您自己的 AuthenticationManager
bean,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 for Spring Security-
Java
-
XML
-
Kotlin
@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();
}
}
<http>
<intercept-url pattern="/login" access="permitAll"/>
<intercept-url pattern="/**" access="authenticated"/>
<form-login />
<http-basic />
<bean id="authenticationManager"
class="org.springframework.security.authentication.ProviderManager">
<constructor-arg>
<bean class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">
<property name="userDetailsService" ref="userDetailsService" />
<property name="passwordEncoder" ref="passwordEncoder" />
</bean>
</constructor-arg>
</bean>
<user-service id="userDetailsService">
<user name="user"
password="{noop}password"
authorities="ROLE_USER" />
</user-service>
<bean id="passwordEncoder"
class="org.springframework.security.crypto.factory.PasswordEncoderFactories" factory-method="createDelegatingPasswordEncoder"/>
</http>
import org.springframework.security.config.annotation.web.invoke
@Configuration
@EnableWebSecurity
class SecurityConfig {
@Bean
fun securityFilterChain(http: HttpSecurity): SecurityFilterChain {
http {
authorizeHttpRequests {
authorize("/login", permitAll)
authorize(anyRequest, authenticated)
}
formLogin { }
httpBasic { }
}
return http.build()
}
@Bean
fun authenticationManager(
userDetailsService: UserDetailsService,
passwordEncoder: PasswordEncoder): AuthenticationManager {
val authenticationProvider = DaoAuthenticationProvider()
authenticationProvider.setUserDetailsService(userDetailsService)
authenticationProvider.setPasswordEncoder(passwordEncoder)
val providerManager = ProviderManager(authenticationProvider)
providerManager.eraseCredentialsAfterAuthentication = false
return providerManager
}
@Bean
fun userDetailsService(): UserDetailsService {
val user = User.withDefaultPasswordEncoder()
.username("user")
.password("password")
.roles("USER")
.build()
return InMemoryUserDetailsManager(user)
}
@Bean
fun passwordEncoder(): PasswordEncoder {
return PasswordEncoderFactories.createDelegatingPasswordEncoder()
}
}
或者,您可以利用这样一个事实:用于生成 Spring Security 全局 AuthenticationManager
的 AuthenticationManagerBuilder
作为 bean 发布。您可以这样配置生成器:
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:
AuthenticationManagerBuilder
-
Java
-
Kotlin
@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);
}
}
import org.springframework.security.config.annotation.web.invoke
@Configuration
@EnableWebSecurity
class SecurityConfig {
@Bean
fun securityFilterChain(http: HttpSecurity): SecurityFilterChain {
// ...
return http.build()
}
@Bean
fun userDetailsService(): UserDetailsService {
// Return a UserDetailsService that caches users
// ...
}
@Autowired
fun configure(builder: AuthenticationManagerBuilder) {
builder.eraseCredentials(false)
}
}