Spring Security latest version securityFilterChain configuration - java

I'm trying to apply latest version of spring configuration. I want to permit all to the h2-console but the application still wants me to authorise.
#Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests()
.shouldFilterAllDispatcherTypes(false)
.requestMatchers("/api/v1/auth/**").permitAll()
.requestMatchers("/h2-console/**").permitAll()
.and()
.authorizeHttpRequests()
.anyRequest().authenticated()
.and()
.httpBasic()
.and()
.csrf().disable()
.headers().frameOptions().disable();
return http.build();
}
I've tried to even change the url of h2-console but it didn't help. The behaviour is weird because .requestMatchers("/api/v1/auth/**").permitAll() works fine.

Please re-write the code like this and try again.
#Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
return http
.csrf().disable()
.authorizeRequests()
.antMatchers("/h2-console/**").permitAll()
.anyRequest().authenticated()
.and()
.httpBasic()
.and()
.build();
}

To permit different paths you should use:
http
.authorizeHttpRequests()
.antMatchers("/api/v1/auth/**", "/h2-console/**").permitAll()
.and()
...
Keep in Mind: The purpose of requestMatchers() is to specify which requests the spring security configuration will be applied to.

Related

Spring Security CORS

I have tried to create endpoints and access those of them that don't need a role, but my Spring Security configuration wouldn't allow me to use it because of CORS.
#Override
protected void configure(HttpSecurity http) throws Exception {
http.
csrf().disable()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeRequests()
.antMatchers("/").permitAll()
.antMatchers("/login").permitAll()
.antMatchers("/logout").permitAll()
.antMatchers("/register").permitAll()
.antMatchers("/getChecks").hasAuthority(Permission.USERS_READ.getPermission())
.antMatchers("/addCheck").hasAuthority(Permission.USERS_ADD_DOTES.getPermission())
.anyRequest()
.authenticated()
.and()
.apply(jwtConfigurer);
}
Should I add some additional configuration in SecurityConfig.java?
I want to access the endpoint.
Try adding cors().and() to the configuration before csrf().disable()

Problem with configuring multiple HttpSecurity instances [duplicate]

This question already has answers here:
Spring Security : Multiple HTTP Config not working
(2 answers)
Closed 6 months ago.
I have problem with configuring multiple httpSecurities.
I have some api routes that are protected with JWT tokens.
I want my swagger-ui/index.html route to be protected with basic auth.
I want those API routes to still be protected with JWT token even after user is authenticated with basic auth.
I followed this documetation to create multiple SecurityFilterChains
My problem is whichever FilterChain has #Order(1) works and other FilterChain is completely ignored.
(if filterChain has order 1, routes for products and orders are protected, but swagger-ui/index.html is not protected with basic auth)
Here is my implementation.
#Bean
#Order(1)
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.authenticationProvider(authenticationProvider());
http
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS);
http
.cors()
.and()
.csrf().disable();
http
.authorizeRequests()
.antMatchers(HttpMethod.GET, "/api/products").hasRole("ADMIN")
.antMatchers(HttpMethod.PUT, "/api/orders").hasRole("ADMIN")
.antMatchers("/api/**").permitAll();
http
.addFilter(new JWTAuthenticationFilter(secret, authenticationManager(authConfig)));
http
.addFilterBefore(new JWTAuthorizationFilter(secret), UsernamePasswordAuthenticationFilter.class);
return http.build();
}
#Bean
public SecurityFilterChain swaggerFilterChain(HttpSecurity http) throws Exception {
http
.authenticationProvider(authenticationProvider());
http
.requestMatchers()
.and()
.authorizeRequests()
.antMatchers("/swagger-ui/index.html","/v3/api-docs/","/v3/api-docs")
.authenticated()
.and()
.httpBasic();
return http.build();
}
You should use one of the following methods of HttpSecurity at least in one of your filters:
antMatcher(String), mvcMatcher(String), regexMatcher(String), requestMatcher(RequestMatcher), requestMatchers().
This will help you to configure certain HttpSecurity to only be invoked when matching the provided patterns.
You've used the last method in the second filter, but did not provide any matchers to the configurer.
So, try to rewrite your second filterChain like this:
#Bean
public SecurityFilterChain swaggerFilterChain(HttpSecurity http) throws Exception {
http
.requestMatchers().antMatchers("/swagger-ui/index.html","/v3/api-docs/","/v3/api-docs")
.and()
.authenticationProvider(authenticationProvider())
.authorizeRequests().anyRequest().authenticated()
.and()
.httpBasic();
return http.build();
}
Also mind that your swaggerFilterChain might be invoked first if you don't want to harcode all other endpoints' urls in the other filter chain - if a request matches a filter with first order it will be the only filter to be applied, so others will be ignored.
So you also need to change the order - place #Order(1) to your swaggerFilterChain and remove this annotation from the other filter chain.
try this, move .antMatchers("/api/**") to the beginning like the doc
#Bean
#Order(1)
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.authenticationProvider(authenticationProvider());
http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
http.cors().and().csrf().disable();
http.antMatchers("/api/**")
.authorizeRequests()
.antMatchers(HttpMethod.GET, "/api/products").hasRole("ADMIN")
.antMatchers(HttpMethod.PUT, "/api/orders").hasRole("ADMIN")
.anyRequest().permitAll();
http.addFilter(new JWTAuthenticationFilter(secret, authenticationManager(authConfig)));
http.addFilterBefore(new JWTAuthorizationFilter(secret), UsernamePasswordAuthenticationFilter.class);
return http.build();
}

Do you know what problem I have with my spring security config?

I need to authenticate all requests starting from "/api/auth" except "/api/auth/login" and "/api/auth/token/refresh". This is my security config configure method. Problem is, it does not work as intended. It checks for authentication for "/api/auth/token/refresh" even though I assigned permitAll to it.
#Override
protected void configure(HttpSecurity http) throws Exception {
http.antMatcher("/api/auth/login").antMatcher("/api/auth/token/refresh")
.antMatcher("/api/auth/**")
.antMatcher("/api/**");
http
.cors()
.and()
.csrf()
.disable()
.exceptionHandling()
.authenticationEntryPoint(unauthorizedHandler)
.and()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeRequests()
.antMatchers(AUTH_WHITELIST)
.permitAll()
.antMatchers("/api/auth/login","/api/auth/token/refresh").permitAll()
.antMatchers("/api/auth/**").authenticated()
.antMatchers("/api/**").permitAll()
.anyRequest()
.permitAll();
// Add our custom JWT security filter
http.addFilterBefore(jwtAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);
}
Remove the first 3 lines of code.
Javadoc of antMatcher(String) says:
Invoking antMatcher(String) will override previous invocations of [...], antMatcher(String), [...].
Calling it 4 times doesn't do what you think it does.

Disable Basic Authentication(Spring Security) for one request and leave for all any

How can i disable basic authentication for one request and leave it for all any requests.
I try do it, but these not work for mi.
#Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeRequests()
.antMatchers(HttpMethod.POST, "/registration").permitAll()
.and()
.authorizeRequests()
.anyRequest().authenticated().and().httpBasic();
}
Basic authentication still work for "/registration".
I assume the /registration is a web page which you have created. Then it should be
http.csrf()
.disable()
.httpBasic()
.and()
.authorizeRequests()
.antMatchers(HttpMethod.GET,"/registration")
.permitAll()
.anyRequest()
.authenticated()
You should use HttpMethod.POST if it is an API endpoint and not a webpage, or for some reason if you have a POST request for the /registration as well then remove the HttpMethod.GET all together and just leave /registration in the antMatchers

Spring Security applies filter to all paths, not only "/api**"

I am struggling to get my Spring Security config done properly.
I have JWT security set up, but I want it to work only on /api** and I can't get it right... Even when I try to hit localhost:8080 I am getting error from JWTFilter.
This is my config:
public static final String TOKEN_BASED_AUTH_ENTRY_POINT = "/api/**";
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.addFilterBefore(new CORSFilter(), ChannelProcessingFilter.class)
.exceptionHandling()
.authenticationEntryPoint(this.restAuthEntryPoint)
.and()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeRequests()
.antMatchers(HttpMethod.OPTIONS, "**").permitAll()
.antMatchers(FORM_BASED_REGISTRATION_ENTRY_POINT).permitAll()
.antMatchers(FORM_BASED_LOGIN_ENTRY_POINT).permitAll()
.and()
.authorizeRequests()
.antMatchers(TOKEN_BASED_AUTH_ENTRY_POINT).authenticated()
.and()
.addFilterBefore(buildJWTLoginFilter(), UsernamePasswordAuthenticationFilter.class)
.addFilterBefore(buildJWTAuthFilter(), UsernamePasswordAuthenticationFilter.class);
}
Theoretically it should apply filters only on API, but it somehow applies them on all paths.
Can someone help to make it working as it should work, so only /api** will be secured and I can freely access all paths outside /api ?
Add and().antMatchers("/**").permitAll()

Categories

Resources