package-private #Configuration bean - spring

Where does it matter to use public access modifier on configuration class? Where can I narrow scope to package-private? I noticed that for example in class extending WebSecurityConfigurerAdapter e.g.
#Configuration
class SecurityConfigurationTest extends WebSecurityConfigurerAdapter {
#Override
public void configure(HttpSecurity httpSecurity)
...
it doesn't matter. So where does it matter?

Related

WebSecurity.ignoring() in ResourceServerConfigurerAdapter

I'm currently implementing oauth2 through Cognito for my Spring Boot API. As a part of configuring Spring Security, I set up my ResourceServerConfigurerAdapter with an override of configure(HttpSecurity http). However I also needed to use the configure(WebSecurity webSecurity) override in order to use WebSecurity.ignoring. Several of my endpoints need to be publicly accessible.
So this led to me having a WebSecurityConfigurerAdapter as well as my ResourceServerConfigurerAdapter. The problem arose with csrf though. The ResourceServerConfig is disabling csrf, but the WebSecurityConfig was apparently taking precedence and now all my endpoints require csrf. Overriding the configure(HttpSecurity) in the WebSecurityConfig to disable csrf fixes the issue but seems wrong to me. I'd like to not have to override and mess with HttpSecurity twice, and ResourceServerConfig doesn't have a webSecurity.ignoring option to my knowledge.
Here's my code for the two below
WebSecurityConfiguration
#Configuration
#EnableWebSecurity(debug = true)
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
#Override
public void configure(HttpSecurity http) throws Exception {
//Disabling this fixes the csrf issue.
http.csrf().disable();
}
#Override
public void configure(WebSecurity webSecurity) throws Exception {
webSecurity.ignoring().antMatchers("/api/auctions/**");
webSecurity.ignoring().antMatchers("/api/lots/**");
}
}
ResourceServerConfiguration
#EnableResourceServer
#EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfiguration extends ResourceServerConfigurerAdapter {
private final ResourceServerProperties resource;
public SecurityConfiguration(ResourceServerProperties resource) {
this.resource = resource;
}
#Override
public void configure(HttpSecurity http) throws Exception {
http.cors();
http.csrf().disable();
http.authorizeRequests().antMatchers("/**").permitAll().anyRequest().permitAll();
}
// Enabling Cognito Converter
#Bean
public TokenStore jwkTokenStore() {
return new JwkTokenStore(
Collections.singletonList(resource.getJwk().getKeySetUri()),
new CognitoAccessTokenConverter(),
null);
}
}
I mostly just want some guidance on what the best path on this is. I've done some digging online and there's conflicting and outdated answers, and everyone seems to be doing very different things with these configurations.

Couldn't access jpg file under resources/static folder

I couldn't access the image under the resources/static folder. I'm using Spring Boot version 2.112.
I also tried adding spring.resources.static-locations in the properties file but still can't access the .jpg file from the resources/static/image folder. Any reason why?
#Configuration
public class WebConfiguration extends WebMvcConfigurationSupport {
#Override
protected void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/**")
.addResourceLocations("classpath:/static/", "classpath:/image/");
}
Well, you may try https://stackoverflow.com/a/66361120/15215155. Most of time is about spring boot default security configuration.
Edit: Little edit here since it would be too much for comments.
Tackling the problem from another angle. Is there any specific feature you need from WebMvcConfigurationSupport?? If not, why not trying WebSecurityConfigurer for the resources handlers and WebSecurityConfigurerAdapter for the security config?.
#Configuration
#EnableWebMvc
public class MvcConfig implements WebMvcConfigurer {
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/css/**", "/js/**")
.addResourceLocations("classpath:/static/", "classpath:/resources/static/");
registry.addResourceHandler("/images/**").addResourceLocations("classpath:/static/images/");
}
}
#Configuration
#EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Override
public void configure(WebSecurity web) throws Exception {
web.ignoring()
.antMatchers("/resources/**");
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/css/**", "/js/**", "/image/**"").permitAll()
}
}

How do I configure a WebSecurityContext with filters that depend on other beans with Spring Security?

How do I configure a WebSecurityContext with filters that depend on other beans with Spring Security?
I am creating a plugin support for our authentication service, and that's what I am trying to do:
#Configuration
#EnableWebSecurity
#Order(1)
#ComponentScan(includeFilters = #ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = AuthPlugin.class))
public class AuthPluginSecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(final HttpSecurity http) throws Exception {
http.addFilterAfter(new AuthPluginFilter(), AbstractPreAuthenticatedProcessingFilter.class);
}
}
Now, my AuthPluginFilter will of course depend on other beans, the implementations of the plugin, for example.
But this wouldn't work, as configure is overwritten from WebSecurityConfigurerAdapter:
#Override
protected void configure(final HttpSecurity http, List<AuthPlugin> authPlugins) throws Exception {
http.addFilterAfter(new AuthPluginFilter(authPlugins), AbstractPreAuthenticatedProcessingFilter.class);
}
I can think of workarounds with #Autowired annotations at the fields. But I'd like to avoid this, if possible.
Is there a more beautiful, recommended way of doing this?
As you want the list of plugins, just inject them into your security config. Then use that list in the configure method to construct the filter.
#Configuration
#EnableWebSecurity
#Order(1)
#ComponentScan(includeFilters = #ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = AuthPlugin.class))
public class AuthPluginSecurityConfig extends WebSecurityConfigurerAdapter {
private final List<AuthPlugin> plugins;
public AuthPluginSecurityConfig(List<AuthPlugin> plugins) {
this.plugins=plugins;
}
#Override
protected void configure(final HttpSecurity http) throws Exception {
http.addFilterAfter(new AuthPluginFilter(this.plugins), AbstractPreAuthenticatedProcessingFilter.class);
}
}

Spring Security does not intercept requests

I have a legacy application in which I have added Spring Web MVC libraries in order to expose a new Rest API.
I am struggling integrating spring-security in order to intercept the incoming requests. I have set up a security configuration class
#EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth
.inMemoryAuthentication()
.withUser("user").password("password").roles("USER");
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable().authorizeRequests().anyRequest().authenticated().and().httpBasic();
}
}
and a security application initializer
public class SecurityWebApplicationInitializer extends
AbstractSecurityWebApplicationInitializer {
}
following relevant guides.
Using debugger I verified that during initializing my configuration class is loaded. My problem is that my requests are not intercepted as expected.
Since you're already using Spring MVC, go to your class that initializes your application. If you're using Java Config, it most likely extends AbstractAnnotationConfigDispatcherServletInitializer.
Add your SecurityConfig to its "root config classes":
public class MySpringMmvcInitializer extends
AbstractAnnotationConfigDispatcherServletInitializer {
...
#Override
protected abstract Class<?>[] getRootConfigClasses() {
return new Class[] { ..., SecurityConfig.class};
}
}
I think you forgot the #configuration annotation, try this
#Configuration
#EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
public void configure(AuthenticationManagerBuilder auth) throws Exception {
auth
.inMemoryAuthentication()
.withUser("user").password("password").roles("USER");
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable().authorizeRequests().anyRequest().authenticated().and().httpBasic();
}
}

#Value annotation return empty value in an AbstractAuthenticationProcessingFilter filter

I'm developing a springboot application with spring security.
I'm trying to make my custom authentication filter reading some properties from the application.properties file without success.
I've read this other question which is similar but within a different context (not related to spring security filters). The reason for the failure makes sense to me but I've tried the way suggested with the DelegatingFilterProxy but without success (to be fair, I didn't really get the meaning of the part added to the Application class). The other solution does not fit my case as I don't have any onStartup method to override.
Here is the code I'm using:
public class JWTAuthenticationFilter extends
AbstractAuthenticationProcessingFilter {
#Value("${app.jwtSecret}")
public String SECRET2;
Almost the same code, in a controller class, works fine:
#RestController
#RequestMapping("/api")
#CrossOrigin
#EnableAutoConfiguration
public class UsersController {
#Value("${app.jwtSecret}")
public String SECRET2;
But I can't make it work in the filter. I'm using springboot 2.0.3.
Any suggestion? Is the DelegatingFilterProxy the right approach in this situation? In that case, any example/article I could follow?
Thanks,
Michele.
UPDATE:
to fully answer to the first comment, the filter is called by the following class:
#EnableWebSecurity
public class WebSecurity extends WebSecurityConfigurerAdapter {
#Autowired
private LdapAuthenticationProvider ldapAuthenticationProvider;
#Override
protected void configure(HttpSecurity http) throws Exception {
http.cors().and().csrf().disable().authorizeRequests()
.antMatchers(HttpMethod.POST, "/api/secureLogin").permitAll()
.antMatchers(HttpMethod.GET, "/api").permitAll()
.antMatchers("/api/**").authenticated()
.and()
.addFilterBefore(new JWTAuthenticationFilter(authenticationManager()), UsernamePasswordAuthenticationFilter.class)
.addFilter(new JWTAuthorizationFilter(authenticationManager()))
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
}
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(ldapAuthenticationProvider);
}
#Bean
#Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
}
No need to use #Value in filter class:
public class JWTAuthenticationFilter extends
AbstractAuthenticationProcessingFilter {
private String secret;
//... setter for secret
But inject the secret in the config class:
#EnableWebSecurity
public class WebSecurity extends WebSecurityConfigurerAdapter {
#Value("${app.jwtSecret}")
public String secret;
//...
#Override
protected void configure(HttpSecurity http) throws Exception {
JWTAuthorizationFilter jwtFilter = new JWTAuthorizationFilter(authenticationManager());
//set secret
//...
}

Resources