Search code examples
springspring-bootspring-security

Spring MVC security gives 403 on permitted URLs


I want to achieve the following with Spring security:

User logs in via login.jsp page and receives a JWT access token which is being stored as a cookie. After that he get redirected to secure.jsp where he can see his own username (this URL is secured). I'm using a filter to perform the authentication:

@Component
public class JwtTokenFilter extends OncePerRequestFilter { 
    
    @Autowired
    private TokenService tokenService;
    
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
            throws ServletException, IOException {

        if (request.getCookies() == null) {
            filterChain.doFilter(request, response);
            return;
        }

        Cookie cookie = null;
        String token = null;

        for (Cookie current : request.getCookies()) {
            if (current.getName().equals("_jwt")) {
                cookie = current;
                token = cookie.getValue();
                break;
            }
        }

        
        if(token == null) {
            filterChain.doFilter(request, response);
            return;
        }   
        
        if(tokenService.validateAccessToken(token)) {
            UserDetails user = tokenService.extractUserDetails(token);
            SecurityContextHolder.getContext().setAuthentication(
                    new UsernamePasswordAuthenticationToken(user.getUsername(), user.getPassword(), user.getAuthorities()));
        }
        
        filterChain.doFilter(request, response);
    }

}

The security config class:

@Configuration
public class SecurityConfiguration {

    public static final String[] PUBLIC_URLS = {
            "/login",
            "/register",
    };
    
    // Other beans...
    
    @Bean
    @SneakyThrows
    public SecurityFilterChain filterChain(HttpSecurity http){
        return http
                .csrf(csrf -> csrf.disable())
                .sessionManagement(sess -> sess.sessionCreationPolicy(STATELESS))
                .cors(cors -> Customizer.withDefaults())
                .authorizeHttpRequests(requests -> requests
                        .requestMatchers(PUBLIC_URLS).permitAll()
                        .anyRequest().authenticated())
                .addFilterBefore(jwtFilter(), UsernamePasswordAuthenticationFilter.class)
                .build();
    }
}

Furthermore I have server.servlet.context-path=/Muzej in my application.properties.

My problem: even if my PUBLIC_URLS starts with /Muzej or not I get 403 error when I try to access my login page in the browser. I enabled debug logging and I got the following:

2024-06-02T12:19:59.187+02:00 DEBUG 26576 --- [VirtuelniVodic] [nio-8080-exec-1] o.s.security.web.FilterChainProxy        : Securing GET /login
2024-06-02T12:19:59.188+02:00 DEBUG 26576 --- [VirtuelniVodic] [nio-8080-exec-1] o.s.s.w.a.AnonymousAuthenticationFilter  : Set SecurityContextHolder to anonymous SecurityContext
2024-06-02T12:19:59.190+02:00 DEBUG 26576 --- [VirtuelniVodic] [nio-8080-exec-1] o.s.security.web.FilterChainProxy        : Secured GET /login
2024-06-02T12:19:59.201+02:00 DEBUG 26576 --- [VirtuelniVodic] [nio-8080-exec-1] o.s.security.web.FilterChainProxy        : Securing GET /index.jsp
2024-06-02T12:19:59.207+02:00 DEBUG 26576 --- [VirtuelniVodic] [nio-8080-exec-1] o.s.s.w.a.Http403ForbiddenEntryPoint     : Pre-authenticated entry point called. Rejecting access
2024-06-02T12:19:59.211+02:00 DEBUG 26576 --- [VirtuelniVodic] [nio-8080-exec-1] o.s.security.web.FilterChainProxy        : Securing GET /error
2024-06-02T12:19:59.212+02:00 DEBUG 26576 --- [VirtuelniVodic] [nio-8080-exec-1] o.s.s.w.a.AnonymousAuthenticationFilter  : Set SecurityContextHolder to anonymous SecurityContext
2024-06-02T12:19:59.213+02:00 DEBUG 26576 --- [VirtuelniVodic] [nio-8080-exec-1] o.s.s.w.a.Http403ForbiddenEntryPoint     : Pre-authenticated entry point called. Rejecting access

However when I change PUBLIC_URLS to ** it loads properly. So the problem is definietly with the Antmatchers in the config, but I just can't figure it out why. Any suggestion would be appreciated.


Solution

  • After some debugging I found out that I had to open the respective jsp URL-s as well. Here is how I solved it:

    public static final String[] PUBLIC_URLS = {
                "/login",
                "/register",
                "/logout",
                "/index.jsp",
                "/login.jsp",
                "/register.jsp",
                "/error.jsp"
        };