mirror of
https://github.com/spring-projects/spring-security.git
synced 2025-02-28 18:39:06 +00:00
Merge branch '6.2.x' into 6.3.x
Closes gh-15808
This commit is contained in:
commit
a939c100fc
@ -17,7 +17,7 @@ Java::
|
|||||||
[source,java,role="primary"]
|
[source,java,role="primary"]
|
||||||
----
|
----
|
||||||
@Bean
|
@Bean
|
||||||
CorsConfigurationSource corsConfigurationSource() {
|
UrlBasedCorsConfigurationSource corsConfigurationSource() {
|
||||||
CorsConfiguration configuration = new CorsConfiguration();
|
CorsConfiguration configuration = new CorsConfiguration();
|
||||||
configuration.setAllowedOrigins(Arrays.asList("https://example.com"));
|
configuration.setAllowedOrigins(Arrays.asList("https://example.com"));
|
||||||
configuration.setAllowedMethods(Arrays.asList("GET","POST"));
|
configuration.setAllowedMethods(Arrays.asList("GET","POST"));
|
||||||
@ -32,7 +32,7 @@ Kotlin::
|
|||||||
[source,kotlin,role="secondary"]
|
[source,kotlin,role="secondary"]
|
||||||
----
|
----
|
||||||
@Bean
|
@Bean
|
||||||
fun corsConfigurationSource(): CorsConfigurationSource {
|
fun corsConfigurationSource(): UrlBasedCorsConfigurationSource {
|
||||||
val configuration = CorsConfiguration()
|
val configuration = CorsConfiguration()
|
||||||
configuration.allowedOrigins = listOf("https://example.com")
|
configuration.allowedOrigins = listOf("https://example.com")
|
||||||
configuration.allowedMethods = listOf("GET", "POST")
|
configuration.allowedMethods = listOf("GET", "POST")
|
||||||
|
@ -326,156 +326,7 @@ Normally, Spring Security builds an `AuthenticationManager` internally composed
|
|||||||
In certain cases, it may still be desired to customize the instance of `AuthenticationManager` used by Spring Security.
|
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.
|
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.
|
To do this, 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 publish an `AuthenticationManager` using the following configuration:
|
|
||||||
|
|
||||||
.Publish `AuthenticationManager` bean for Spring Security
|
|
||||||
[tabs]
|
|
||||||
=====
|
|
||||||
Java::
|
|
||||||
+
|
|
||||||
[source,java,role="primary"]
|
|
||||||
----
|
|
||||||
@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();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
----
|
|
||||||
|
|
||||||
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
|
|
||||||
@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()
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
----
|
|
||||||
=====
|
|
||||||
|
|
||||||
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:
|
You can configure the builder as follows:
|
||||||
|
|
||||||
.Configure global `AuthenticationManagerBuilder`
|
.Configure global `AuthenticationManagerBuilder`
|
||||||
@ -539,3 +390,142 @@ class SecurityConfig {
|
|||||||
}
|
}
|
||||||
----
|
----
|
||||||
=====
|
=====
|
||||||
|
|
||||||
|
Alternatively, you may configure a local `AuthenticationManager` to override the global one.
|
||||||
|
|
||||||
|
.Configure local `AuthenticationManager` for Spring Security
|
||||||
|
[tabs]
|
||||||
|
=====
|
||||||
|
Java::
|
||||||
|
+
|
||||||
|
[source,java,role="primary"]
|
||||||
|
----
|
||||||
|
@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())
|
||||||
|
.authenticationManager(authenticationManager());
|
||||||
|
|
||||||
|
return http.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
private AuthenticationManager authenticationManager() {
|
||||||
|
DaoAuthenticationProvider authenticationProvider = new DaoAuthenticationProvider();
|
||||||
|
authenticationProvider.setUserDetailsService(userDetailsService());
|
||||||
|
authenticationProvider.setPasswordEncoder(passwordEncoder());
|
||||||
|
|
||||||
|
ProviderManager providerManager = new ProviderManager(authenticationProvider);
|
||||||
|
providerManager.setEraseCredentialsAfterAuthentication(false);
|
||||||
|
|
||||||
|
return providerManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
private UserDetailsService userDetailsService() {
|
||||||
|
UserDetails userDetails = User.withDefaultPasswordEncoder()
|
||||||
|
.username("user")
|
||||||
|
.password("password")
|
||||||
|
.roles("USER")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
return new InMemoryUserDetailsManager(userDetails);
|
||||||
|
}
|
||||||
|
|
||||||
|
private PasswordEncoder passwordEncoder() {
|
||||||
|
return PasswordEncoderFactories.createDelegatingPasswordEncoder();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
----
|
||||||
|
|
||||||
|
XML::
|
||||||
|
+
|
||||||
|
[source,xml,role="secondary"]
|
||||||
|
----
|
||||||
|
<http authentication-manager-ref="authenticationManager">
|
||||||
|
<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
|
||||||
|
@EnableWebSecurity
|
||||||
|
class SecurityConfig {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
fun securityFilterChain(http: HttpSecurity): SecurityFilterChain {
|
||||||
|
http {
|
||||||
|
authorizeHttpRequests {
|
||||||
|
authorize(anyRequest, authenticated)
|
||||||
|
}
|
||||||
|
formLogin { }
|
||||||
|
httpBasic { }
|
||||||
|
authenticationManager = authenticationManager()
|
||||||
|
}
|
||||||
|
|
||||||
|
return http.build()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
fun authenticationManager(): AuthenticationManager {
|
||||||
|
val authenticationProvider = DaoAuthenticationProvider()
|
||||||
|
authenticationProvider.setUserDetailsService(userDetailsService())
|
||||||
|
authenticationProvider.setPasswordEncoder(passwordEncoder())
|
||||||
|
|
||||||
|
val providerManager = ProviderManager(authenticationProvider)
|
||||||
|
providerManager.eraseCredentialsAfterAuthentication = false
|
||||||
|
|
||||||
|
return providerManager
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun userDetailsService(): UserDetailsService {
|
||||||
|
val user = User.withDefaultPasswordEncoder()
|
||||||
|
.username("user")
|
||||||
|
.password("password")
|
||||||
|
.roles("USER")
|
||||||
|
.build()
|
||||||
|
|
||||||
|
return InMemoryUserDetailsManager(user)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun passwordEncoder(): PasswordEncoder {
|
||||||
|
return PasswordEncoderFactories.createDelegatingPasswordEncoder()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
----
|
||||||
|
=====
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@ Java::
|
|||||||
[source,java,role="primary"]
|
[source,java,role="primary"]
|
||||||
----
|
----
|
||||||
@Bean
|
@Bean
|
||||||
CorsConfigurationSource corsConfigurationSource() {
|
UrlBasedCorsConfigurationSource corsConfigurationSource() {
|
||||||
CorsConfiguration configuration = new CorsConfiguration();
|
CorsConfiguration configuration = new CorsConfiguration();
|
||||||
configuration.setAllowedOrigins(Arrays.asList("https://example.com"));
|
configuration.setAllowedOrigins(Arrays.asList("https://example.com"));
|
||||||
configuration.setAllowedMethods(Arrays.asList("GET","POST"));
|
configuration.setAllowedMethods(Arrays.asList("GET","POST"));
|
||||||
@ -31,7 +31,7 @@ Kotlin::
|
|||||||
[source,kotlin,role="secondary"]
|
[source,kotlin,role="secondary"]
|
||||||
----
|
----
|
||||||
@Bean
|
@Bean
|
||||||
fun corsConfigurationSource(): CorsConfigurationSource {
|
fun corsConfigurationSource(): UrlBasedCorsConfigurationSource {
|
||||||
val configuration = CorsConfiguration()
|
val configuration = CorsConfiguration()
|
||||||
configuration.allowedOrigins = listOf("https://example.com")
|
configuration.allowedOrigins = listOf("https://example.com")
|
||||||
configuration.allowedMethods = listOf("GET", "POST")
|
configuration.allowedMethods = listOf("GET", "POST")
|
||||||
@ -147,7 +147,7 @@ public class WebSecurityConfig {
|
|||||||
return http.build();
|
return http.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
CorsConfigurationSource apiConfigurationSource() {
|
UrlBasedCorsConfigurationSource apiConfigurationSource() {
|
||||||
CorsConfiguration configuration = new CorsConfiguration();
|
CorsConfiguration configuration = new CorsConfiguration();
|
||||||
configuration.setAllowedOrigins(Arrays.asList("https://api.example.com"));
|
configuration.setAllowedOrigins(Arrays.asList("https://api.example.com"));
|
||||||
configuration.setAllowedMethods(Arrays.asList("GET","POST"));
|
configuration.setAllowedMethods(Arrays.asList("GET","POST"));
|
||||||
@ -156,7 +156,7 @@ public class WebSecurityConfig {
|
|||||||
return source;
|
return source;
|
||||||
}
|
}
|
||||||
|
|
||||||
CorsConfigurationSource myWebsiteConfigurationSource() {
|
UrlBasedCorsConfigurationSource myWebsiteConfigurationSource() {
|
||||||
CorsConfiguration configuration = new CorsConfiguration();
|
CorsConfiguration configuration = new CorsConfiguration();
|
||||||
configuration.setAllowedOrigins(Arrays.asList("https://example.com"));
|
configuration.setAllowedOrigins(Arrays.asList("https://example.com"));
|
||||||
configuration.setAllowedMethods(Arrays.asList("GET","POST"));
|
configuration.setAllowedMethods(Arrays.asList("GET","POST"));
|
||||||
@ -173,7 +173,7 @@ Kotlin::
|
|||||||
[source,kotlin,role="secondary"]
|
[source,kotlin,role="secondary"]
|
||||||
----
|
----
|
||||||
@Bean
|
@Bean
|
||||||
fun corsConfigurationSource(): CorsConfigurationSource {
|
fun corsConfigurationSource(): UrlBasedCorsConfigurationSource {
|
||||||
val configuration = CorsConfiguration()
|
val configuration = CorsConfiguration()
|
||||||
configuration.allowedOrigins = listOf("https://example.com")
|
configuration.allowedOrigins = listOf("https://example.com")
|
||||||
configuration.allowedMethods = listOf("GET", "POST")
|
configuration.allowedMethods = listOf("GET", "POST")
|
||||||
|
Loading…
x
Reference in New Issue
Block a user