Search code examples
javaspringspring-bootspring-security

Why does spring security ask for authentication even after including endpoint in permitAll()?


I am using Spring Boot 3.2.2 with spring security. I have 3 endpoints for which I permitAll(). The strange thing is that only for the /upload endpoint permit all does not work. It still asks for authentication and even after authentication it throws 403. Even if I move the /upload endpoint to the requestMatchers() for ADMIN or USER it still throws 403, while the other endpoints work.

The only difference between these endpoints is that /upload is a POST request and it takes in a MultipartFile, while the others are simple GET requests.

@PostMapping("/upload")
    public ResponseEntity<String> uploadFile(@RequestParam("file") MultipartFile file) {

Does anyone know what the problem is?

 @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http.formLogin(Customizer.withDefaults())
                .authorizeHttpRequests((authorize) -> authorize
                        .requestMatchers("/test/user").hasRole(UserRole.USER.name())
                        .requestMatchers("/test/admin").hasRole(UserRole.ADMIN.name())
                        .requestMatchers("/test/no-role", "/upload", "/api/ai/generate").permitAll()
                        .anyRequest().authenticated()
                );
        return http.build();
    }

Update:

Changed logging level to debug. Here are the logs:

2024-02-13T12:50:34.003+02:00 DEBUG 16611 --- [nio-8080-exec-1] o.s.security.web.FilterChainProxy        : Securing POST /upload
2024-02-13T12:50:34.005+02:00 DEBUG 16611 --- [nio-8080-exec-1] o.s.security.web.csrf.CsrfFilter         : Invalid CSRF token found for http://localhost:8080/upload
2024-02-13T12:50:34.007+02:00 DEBUG 16611 --- [nio-8080-exec-1] o.s.s.w.access.AccessDeniedHandlerImpl   : Responding with 403 status code
2024-02-13T12:50:34.009+02:00 DEBUG 16611 --- [nio-8080-exec-1] o.s.security.web.FilterChainProxy        : Securing POST /error
2024-02-13T12:50:34.009+02:00 DEBUG 16611 --- [nio-8080-exec-1] w.c.HttpSessionSecurityContextRepository : Retrieved SecurityContextImpl [Authentication=UsernamePasswordAuthenticationToken [Principal=org.springframework.security.core.userdetails.User [Username=admin, Password=[PROTECTED], Enabled=true, AccountNonExpired=true, CredentialsNonExpired=true, AccountNonLocked=true, Granted Authorities=[ROLE_ADMIN]], Credentials=[PROTECTED], Authenticated=true, Details=WebAuthenticationDetails [RemoteIpAddress=0:0:0:0:0:0:0:1, SessionId=7579E5587784A8B4847F2571BCD188A2], Granted Authorities=[ROLE_ADMIN]]]
2024-02-13T12:50:34.009+02:00 DEBUG 16611 --- [nio-8080-exec-1] o.s.security.web.FilterChainProxy        : Secured POST /error
2024-02-13T12:50:34.009+02:00 DEBUG 16611 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : "ERROR" dispatch for POST "/error", parameters={}
2024-02-13T12:50:34.010+02:00 DEBUG 16611 --- [nio-8080-exec-1] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController#error(HttpServletRequest)
2024-02-13T12:50:34.010+02:00 DEBUG 16611 --- [nio-8080-exec-1] o.j.s.OpenEntityManagerInViewInterceptor : Opening JPA EntityManager in OpenEntityManagerInViewInterceptor
2024-02-13T12:50:34.012+02:00 DEBUG 16611 --- [nio-8080-exec-1] o.s.w.s.m.m.a.HttpEntityMethodProcessor  : Using 'application/json', given [*/*] and supported [application/json, application/*+json]
2024-02-13T12:50:34.013+02:00 DEBUG 16611 --- [nio-8080-exec-1] o.s.w.s.m.m.a.HttpEntityMethodProcessor  : Writing [{timestamp=Tue Feb 13 12:50:34 EET 2024, status=403, error=Forbidden, path=/upload}]
2024-02-13T12:50:34.022+02:00 DEBUG 16611 --- [nio-8080-exec-1] o.j.s.OpenEntityManagerInViewInterceptor : Closing JPA EntityManager in OpenEntityManagerInViewInterceptor
2024-02-13T12:50:34.022+02:00 DEBUG 16611 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Exiting from "ERROR" dispatch, status 403

Solution

  • As I see in your configuration the problem that you get is related to csrf and in current one configuration to permit the POST requests, you have to disable it. Because it is enabled by default in spring security.

    Something like it you have to add to configuration:

    http.csrf(AbstractHttpConfigurer::disable);
    

    More details you could find into relevant section in documentation