Spring security permitall return 401

Viewed 557

Spring Security Config

 @Override
    protected void configure(HttpSecurity http) throws Exception {

    http.cors().and()
            .exceptionHandling().authenticationEntryPoint(unauthorizedHandler).and()
            .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
            .authorizeRequests()
            .antMatchers("/admin").hasRole("ADMIN")
            .antMatchers("/api/auth/**").permitAll()
            .antMatchers("/api/test/**").permitAll()
            .antMatchers("/").permitAll()
            .antMatchers("/favicon.ico").permitAll()
            .antMatchers("/static/**").permitAll()
            .antMatchers("/manifest.json").permitAll()
            .antMatchers("/logo192.png").permitAll()
            .anyRequest().authenticated();

    http.addFilterBefore(authenticationJwtTokenFilter(), UsernamePasswordAuthenticationFilter.class);
}

I also tried this but did not produce any result

.antMatchers(HttpMethod.POST, "/api/auth/**").permitAll()

/api/auth/signup return

error: "Unauthorized"
message: "Full authentication is required to access this resource"
path: "/error"
status: 401

Request URL: https://mysuite.ru/api/auth/signup

How can I fix this problem?

UPDATE

@Configuration
public class MvcSecurityConfig implements WebMvcConfigurer {
@Value("${path.frontend}")
private String frontendPath;
@Value("${frontendStaticResourcesPathPatterns}")
private String[] frontendStaticResourcesPathPatterns;
private static final String BASE_API_PATH = "/";

public void addResourceHandlers(ResourceHandlerRegistry registry){
    String pathToFrontend = "file:" + this.frontendPath;
    String pathToIndexHTML = pathToFrontend + "/index.html";

    registry
            .addResourceHandler(frontendStaticResourcesPathPatterns)
            .setCachePeriod(0)
            .addResourceLocations(pathToFrontend);

    registry.addResourceHandler("/", "/**")
            .setCachePeriod(0)
            .addResourceLocations(pathToIndexHTML)
            .resourceChain(true)
            .addResolver(new PathResourceResolver() {
                @Override
                protected Resource getResource(String resourcePath, Resource location) throws IOException {
                    if (resourcePath.startsWith(BASE_API_PATH) || resourcePath.startsWith(BASE_API_PATH.substring(1))) {
                        return null;
                    }
                    return location.exists() && location.isReadable() ? location : null;
                }
            });

}
}

This is my Spring MVC Config. Could any of this cause the problem? I also tried to do permitAll step by step along the path but it didn't work (api/, api/auth, api/autn/**)

3 Answers

By default, Spring Security comes with CSRF Protection enabled, so when you perform an unsafe request (POST, PUT, DELETE) you have to provide a CSRF Token.

In your configure method you can disable it to check if it will work.

http.csrf().disable()

I advise you that disabling CSRF protection can be harmful to your app and you should make sure if you need to use it or not.

Also, if you are using Spring Security's version 5.4 or higher, you can enable trace logs to help you debug it.

logging.level.org.springframework.security=TRACE

You can get more details in the reference docs.

In an Ant matcher, ** matches zero or more directories in a path. Given your request URL you just need to match zero or more characters. Having said that, try replacing your Ant matcher with the following:

.antMatchers(HttpMethod.POST, "/api/auth/*").permitAll()

By pass your filter because any API request throught Filter. Your API can not pass Filter so you get 401 response.

Try add this to your Spring Security Config:

@Override
public void configure(WebSecurity web) throws Exception {
    web.ignoring().antMatchers("/api/auth/**");
}

Or add this to OncePerRequestFilter:

    @Override
    protected boolean shouldNotFilter(HttpServletRequest request) throws ServletException {
        return new AntPathMatcher().match("/api/auth/**", request.getServletPath());
    }
Related