-
Notifications
You must be signed in to change notification settings - Fork 6.1k
Description
Description:
Hi Spring Security Team,
I'm working on a project where I'm using Spring Security with Spring Cloud Config and Spring Cloud Bus to dynamically refresh security configurations.
Currently, I have a custom CORS configuration that can be dynamically refreshed using @RefreshScope, as shown below:
`@Component
@RefreshScope
@ConfigurationProperties(prefix = "cors")
public class CorsConfig {
private List<String> allowedOrigins;
private List<String> allowedMethods;
private List<String> allowedHeaders;
private boolean allowCredentials;
private List<String> exposedHeaders;
private long maxAge;
@Bean
@RefreshScope
public CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration corsConfig = new CorsConfiguration();
corsConfig.setAllowedOrigins(allowedOrigins);
corsConfig.setAllowedMethods(allowedMethods);
corsConfig.setAllowedHeaders(allowedHeaders);
corsConfig.setAllowCredentials(allowCredentials);
corsConfig.setExposedHeaders(exposedHeaders);
corsConfig.setMaxAge(maxAge);
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", corsConfig);
return source;
}
}`
As you can see, this configuration allows CORS settings to be dynamically refreshed. By using a proxy bean with @RefreshScope, I can update the CORS configuration without needing to restart the application or reload the entire Spring Security context.
Current Approach for Dynamic Security Configuration:
For dynamically updating the security rules in SecurityWebFilterChain, I currently use the following approach:
`@Bean
@RefreshScope
public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) {
http
.exceptionHandling()
.authenticationEntryPoint((exchange, ex) -> {
exchange.getResponse().getHeaders().add("X-Redirect", "login");
return writeErrorResponse(exchange.getResponse(), HttpStatus.FOUND, ex.getMessage());
})
.and()
.cors().configurationSource(corsConfig.corsConfigurationSource())
.and()
.csrf().disable()
.formLogin().disable();
ServerHttpSecurity.AuthorizeExchangeSpec authorizeExchange = http.authorizeExchange();
// Dynamic paths from a @RefreshScope bean
pathMatcherConfig.permitAllPaths().forEach(path ->
authorizeExchange.pathMatchers(path).permitAll()
);
pathMatcherConfig.userRolePaths().forEach(path ->
authorizeExchange.pathMatchers(path).hasAuthority("ROLE_USER")
);
pathMatcherConfig.adminRolePaths().forEach(path ->
authorizeExchange.pathMatchers(path).hasAuthority("ROLE_ADMIN")
);
return authorizeExchange
.anyExchange().authenticated()
.and()
.addFilterAt(authenticationWebFilter(), SecurityWebFiltersOrder.AUTHENTICATION)
.build();
}`
While this works for dynamically updating the CORS configuration, the ServerHttpSecurity object seems to use a builder pattern that stores configuration details internally. This differs from the more dynamic approach possible with CorsConfigurationSource.
Questions:
Is there a way to use a proxy bean or some dynamic mechanism in ServerHttpSecurity to allow more dynamic updates of the authorizeExchange paths, similar to how CorsConfigurationSource is dynamically referenced via a proxy bean?
If not, is the recommended approach to dynamically update authorization paths to re-create the entire SecurityWebFilterChain bean?
If re-creating the entire SecurityWebFilterChain is necessary for dynamic updates, are there any plans to improve this in future releases to make it more flexible or efficient?
I appreciate any guidance or suggestions you can provide on how to best manage dynamic security configurations with Spring Security.
Thank you!