auth0-spring-security5-api-sample
auth0-spring-security5-api-sample copied to clipboard
401 Unauthorized on POST endpoint in Spring Boot (MVC) application
Hi, I am using Spring Boot 3 and Spring Security 6 and following the sample https://github.com/auth0-samples/auth0-spring-security5-api-sample/tree/use-spring-6/01-Authorization-MVC. Tutorial works well until I try with GET endpoints. But the moment I built a POST endpoint and call it, I get 401 Unauthorized error in postman even though this is configured to be permitted in SecurityConfig.java. Here is the link to my code changes https://github.com/ashishrky/auth0-spring-security5-api-sample/commit/8bf9866a7a18fb9d2e0c78f1950725f2f42eaee2. What’s wrong? Why GET call work just fine, but POST call get 401?
Posted in Auth0 community as well at https://community.auth0.com/t/401-unauthorized-on-post-endpoint-in-spring-boot-mvc-application/103716
"hi, I have exactly the same problem, did you manage to solve yours?"
If you turn up the logging for Spring Security in application.yml
:
logging:
level:
org.springframework.security.web: DEBUG
You'll see the error when you try to do a POST:
2023-04-20T10:24:21.166-06:00 DEBUG 15786 --- [nio-3010-exec-1] o.s.security.web.FilterChainProxy : Securing POST /api/public/post
2023-04-20T10:24:21.184-06:00 DEBUG 15786 --- [nio-3010-exec-1] o.s.security.web.csrf.CsrfFilter : Invalid CSRF token found for http://localhost:3010/api/public/post
2023-04-20T10:24:21.184-06:00 DEBUG 15786 --- [nio-3010-exec-1] o.s.s.w.access.AccessDeniedHandlerImpl : Responding with 403 status code
2023-04-20T10:24:21.186-06:00 DEBUG 15786 --- [nio-3010-exec-1] o.s.security.web.FilterChainProxy : Securing POST /error
2023-04-20T10:24:21.189-06:00 DEBUG 15786 --- [nio-3010-exec-1] o.s.s.w.a.AnonymousAuthenticationFilter : Set SecurityContextHolder to anonymous SecurityContext
If you disable CSRF in SecurityConfig.java
, everything will work:
http.csrf().disable();
Here's proof:

CSRF (Cross-Site Request Forgery) is a type of attack on web applications. It happens when an attacker tricks a user into doing something they didn't intend to do on a different website where they are already logged in. Spring Boot Security uses CSRF protection to stop these tricks and keep your application safe.
In the above example, an authorized user has access only to the GetMapping method. That's why, as soon as they try to request the application with the PostMapping method, due to this CSRF, they get an unauthorised message. If we disable it, the post-mapping methods will work fine.
So how do you still get CSRF protection while still being able to interact with the REST server? Is it just simple as disabling csrf for development and enabling it for production?
SecurityFilterChain securityFilterChain(HttpSecurity http)throws Exception{ http.csrf((csrf) -> csrf.disable()) .authorizeHttpRequests((authorize)->{ authorize.requestMatchers(HttpMethod.POST,"/api/**").hasRole("ADMIN"); authorize.requestMatchers(HttpMethod.PUT,"/api/**").hasRole("ADMIN"); authorize.requestMatchers(HttpMethod.DELETE,"/api/**").hasRole("ADMIN"); authorize.anyRequest().authenticated(); }).httpBasic(Customizer.withDefaults()); return http.build(); }
In my case have already disabled it, but still getting 401 using POST from postman. However i can login using the browser.
@Siddhnak In postman, you can Authorization Tab beside the Headers and add your username and password.
@Siddhnak I am facing the same error as you did. Could you please share your knowledge if you have solved this in any manner. Thank you.
Here's what I did to retain the basic Auth in GET request and apply CSRF in POST request:
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.csrf(csrf -> csrf
.ignoringRequestMatchers( "/api/**")
.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
.csrfTokenRequestHandler(new CsrfTokenRequestAttributeHandler()))
.authorizeHttpRequests(auth -> {
auth.anyRequest().authenticated();
})
.httpBasic(Customizer.withDefaults());
return http.build();
}
No Auth requests in Postman produces 401 Unauthorized error and with Basic Auth the request passes through. Hope this helps!