Hi we are building custom spring security library
we need to pass {"/v1","/v2"} paths through @EnableMySpringSecurity(excludePaths = {"/v1","/v2"})
which is present in the main project to library websecurity so we can ignore those endpoints from security
@EnableMySpringSecurity(excludePaths = {"/v1","/v2"})
@EnableWebMvc
public class WebAppConfiguration extends BaseWebAppConfiguration {
Websecurity Configuration from custom JAR
@EnableWebSecurity(debug = true)
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
public static class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
public void configure(WebSecurity web){
web.ignoring().antMatchers(excludePaths );
How to pass values that are passed from @EnableMYSpringSecurity to the webSecuirty web.ignoring.antMatchers
our annotation configuration
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface EnableMySpringSecurity {
String[] excludePaths() default {};
}
I have tried ApplicationStartupListener but problem with this is, it is initialized after websecuirty configuration
public class ApplicationStartupListener implements
ApplicationListener<ContextRefreshedEvent> {
private ApplicationContext context;
private EnableMySSAnnotationProcessor processor;
public ApplicationStartupListener(ApplicationContext context,
EnableMySSAnnotationProcessor processor) {
this.context = context;
this.processor = processor;
}
@Override
public void onApplicationEvent(ContextRefreshedEvent contextRefreshedEvent) {
Optional<EnableMySpringSecurity> annotation =
context.getBeansWithAnnotation(EnableMySpringSecurity.class).keySet().stream()
.map(key -> context.findAnnotationOnBean(key, EnableMySpringSecurity.class))
.findFirst();
annotation.ifPresent(enableMySpringSecurity-> processor.process(enableMySpringSecurity));
}
}
One way you can do this is with the @Import
annotation:
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Import(MyWebSecurityConfiguration.class)
@EnableWebSecurity
public @interface EnableMyWebSecurity {
String[] paths() default [];
}
and then the ImportAware
interface:
@Configuration
public class MyWebSecurityConfiguration implements ImportAware {
private String[] paths;
@Bean
WebSecurityCustomizer paths() {
return (web) -> web.ignoring().antMatchers(paths);
}
@Override
public void setImportMetadata(AnnotationMetadata importMetadata) {
EnableMyWebSecurity annotation = importMetadata
.getAnnotations().get(EnableMyWebSecurity.class).synthesize();
this.paths = annotations.paths();
}
}
Note, by the way, that when you exclude paths, Spring Security cannot add security headers as part of the response. If you want those endpoints to be protected by Spring Security, but public, then consider instead:
@Configuration
public class MyWebSecurityConfiguration implements ImportAware {
private String[] paths;
@Bean
@Order(1)
SecurityFilterChain paths(HttpSecurity http) {
http
.requestMatchers((requests) -> requests.antMatchers(paths))
.authorizeRequests((authorize) -> authorize
.anyRequest().permitAll()
);
return http.build();
}
@Override
public void setImportMetadata(AnnotationMetadata importMetadata) {
EnableMyWebSecurity annotation = importMetadata
.getAnnotations().get(EnableMyWebSecurity.class).synthesize();
this.paths = annotations.paths();
}
}
The benefit of the second approach is that Spring Security won't require authentication, but will add secure response headers.