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!
Comment From: sjohnr
@SunWooInOOP thanks for reaching out! This issue is structured as one or more questions that would be better suited to Stack Overflow. We prefer to use GitHub issues only for bugs and enhancements. Feel free to update this issue with a link to the re-posted question (so that other people can find it).
Having said that, it has been discussed before. However,
are there any plans to improve this in future releases to make it more flexible or efficient?
I don't see any issues in the issue tracker for this, so having an issue that folks can reference and potentially upvote as a requested feature is an important first step. Would you be able to open a new enhancement request with the details suggesting what you think would be helpful? Instead of structuring it as one or more questions around your particular use case, perhaps focus on general use cases for the feature and an overview of what you would expect to achieve.
In the meantime, I'm going to close this issue, but we can keep it as a reference for any new issues that are opened.