| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541 | [[servlet-authentication-unpwd]]= Username/Password Authentication:page-section-summary-toc: 1:figures: images/servlet/authentication/unpwd:icondir: images/iconsOne 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:.Simple Username/Password Example[tabs]=====Java::+[source,java,role="primary"]----@Configuration@EnableWebSecuritypublic 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);	}}----XML::+[source,xml,role="secondary"]----<http>	<intercept-url pattern="/**" access="authenticated"/>	<form-login />	<http-basic />	<user-service>		<user name="user"			password="{noop}password"			authorities="ROLE_USER" />	</user-service></http>----Kotlin::+[source,kotlin,role="secondary"]----import org.springframework.security.config.annotation.web.invoke@Configuration@EnableWebSecurityclass 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)	}}----=====The preceding configuration automatically registers an xref:servlet/authentication/passwords/in-memory.adoc[in-memory `UserDetailsService`] with the `SecurityFilterChain`, registers the xref:servlet/authentication/passwords/dao-authentication-provider.adoc[`DaoAuthenticationProvider`] with the default xref:servlet/authentication/architecture.adoc#servlet-authentication-authenticationmanager[`AuthenticationManager`], and enables xref:servlet/authentication/passwords/form.adoc[Form Login] and xref:servlet/authentication/passwords/basic.adoc[HTTP Basic] authentication.To learn more about username/password authentication, consider the following use cases:* I want to xref:servlet/authentication/passwords/form.adoc[learn how Form Login works]* I want to xref:servlet/authentication/passwords/basic.adoc[learn how HTTP Basic authentication works]* I want to xref:servlet/authentication/passwords/dao-authentication-provider.adoc[learn how `DaoAuthenticationProvider` works]* I want to xref:servlet/authentication/passwords/in-memory.adoc[manage users in memory]* I want to xref:servlet/authentication/passwords/jdbc.adoc[manage users in a database]* I want to xref:servlet/authentication/passwords/ldap.adoc#servlet-authentication-ldap-authentication[manage users in LDAP]* I want to <<publish-authentication-manager-bean,publish an `AuthenticationManager` bean>> for custom authentication* I want to <<customize-global-authentication-manager,customize the global `AuthenticationManager`>>[[publish-authentication-manager-bean]]== Publish an `AuthenticationManager` beanA 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 xref:servlet/authentication/passwords/form.adoc[Form Login].You can publish such an `AuthenticationManager` for custom authentication scenarios using the following configuration:.Publish `AuthenticationManager` bean for Custom Authentication[tabs]=====Java::+[source,java,role="primary"]----@Configuration@EnableWebSecuritypublic 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();	}}----XML::+[source,xml,role="secondary"]----<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>----Kotlin::+[source,kotlin,role="secondary"]----import org.springframework.security.config.annotation.web.invoke@Configuration@EnableWebSecurityclass 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()	}}----=====With the preceding configuration in place, you can create a `@RestController` that uses the `AuthenticationManager` as follows:.Create a `@RestController` for Authentication[tabs]=====Java::+[source,java,role="primary"]----@RestControllerpublic 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) {	}}----Kotlin::+[source,kotlin,role="secondary"]----@RestControllerclass 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)}----=====[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 xref:servlet/authentication/persistence.adoc#httpsecuritycontextrepository[`HttpSessionSecurityContextRepository`].====[[customize-global-authentication-manager]]== 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 xref:servlet/authentication/architecture.adoc#servlet-authentication-providermanager-erasing-credentials[credential erasure] for cached users.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:.Publish `AuthenticationManager` bean for Spring Security[tabs]=====Java::+[source,java,role="primary"]----@Configuration@EnableWebSecuritypublic 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();	}}----XML::+[source,xml,role="secondary"]----<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>----Kotlin::+[source,kotlin,role="secondary"]----import org.springframework.security.config.annotation.web.invoke@Configuration@EnableWebSecurityclass 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()	}}----=====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:.Configure global `AuthenticationManagerBuilder`[tabs]=====Java::+[source,java,role="primary"]----@Configuration@EnableWebSecuritypublic 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);	}}----Kotlin::+[source,kotlin,role="secondary"]----import org.springframework.security.config.annotation.web.invoke@Configuration@EnableWebSecurityclass 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)	}}----=====
 |