1

In my JWT authenticated API I want these paths to be accessible without any authentication, and all other endpoints to be disallowed/disabled:

  • GET /apis/id/{id}
  • POST /apis
  • PATCH /apis/id/{id}
  • DELETE /apis/id/{id}
  • GET /swagger-ui.html

As you can see most of the above endpoints begin with /apis/id, POST has /apis. Here is my configurations:

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {


    @Override
    protected void configure(HttpSecurity httpSecurity) throws Exception {
        httpSecurity.authorizeRequests()
           .mvcMatchers(HttpMethod.GET,"/apis/id/**").permitAll()
           .mvcMatchers(HttpMethod.PATCH,"/apis/id/**").permitAll()
           .mvcMatchers(HttpMethod.DELETE,"/apis/id/**").permitAll()
           .mvcMatchers(HttpMethod.POST,"/apis", "/apis/").permitAll()
           .antMatchers(HttpMethod.GET,"/csrf","/v2/api-docs","/swagger-resources/configuration/ui",  "/configuration/ui", "/swagger-resources", "/configuration/security", "/swagger-ui.html", "/webjars/**","/swagger-resources/configuration/ui","/swagger-resources/configuration/security", "/configuration/security").permitAll()// for Swagger UI
        .anyRequest().denyAll();
    }
}

Only GET /apis/id/{id} and /swagger-ui.html get through. The other endpoints with the identical configs (except for POST) all got rejected (403). I added an exception handler and print out the AuthenticationException message, and it says:

Full authentication is required to access this resource path

How do I make these endpoints public? I feel like I am missing some configurations.

Framworks I am using:

  • Spring Boot version 2.0.4
  • Spring Security version 5.1.0
Hanjun Chen
  • 544
  • 4
  • 11

1 Answers1

2

You can take a look at this answer for the possible explanation of you problem.

Invoking antMatcher(String) will override previous invocations of mvcMatcher(String), requestMatchers(), antMatcher(String), regexMatcher(String), and requestMatcher(RequestMatcher).

Now that you understand the underlying problem, you can now then change your code into something like this:

http
    .requestMatchers()
        .antMatchers("/apis/id/**", "/csrf","/v2/api-docs","/swagger-resources/configuration/ui",  "/configuration/ui", "/swagger-resources", "/configuration/security", "/swagger-ui.html", "/webjars/**","/swagger-resources/configuration/ui","/swagger-resources/configuration/security", "/configuration/security").permitAll()
        .anyRequest().authenticated();
Royts
  • 501
  • 6
  • 14
  • Hey @Royts, if I need to authenticate with token for all "/apis/id/**" but not for "/apis/id/get/**", how can I do that? – Shiva kumar Oct 25 '19 at 12:44
  • same as the answer above. Assuming you are using spring security for authentication of your token, you just need to put all the api's that you do not want to authenticate in `antmatchers()` with `.permitAll()`, otherwise, `.anyRequest().authenticated();` will validate all the api's that are not marked as .permitAll() – Royts Oct 25 '19 at 13:24
  • In the above example, we have permitted paths for some patterns which are mentioned in antMatchers and other than those patterns we're authenticating, I need to authenticate for a parent pattern like /web/** and not authenticate for /web/get/** – Shiva kumar Oct 25 '19 at 13:32
  • And your above example doesn't work because .permitAll() method is for an AuthorizedUrl. whereas requestMatchers().antMatchers returns RequestMatcherConfigurer – Shiva kumar Oct 25 '19 at 14:20
  • Maybe you can try to implement multiple http configuration like this https://docs.spring.io/spring-security/site/docs/current/reference/htmlsingle/#multiple-httpsecurity. I haven't tried that case though. – Royts Oct 28 '19 at 06:14
  • Btw, I think you can actually add authentication in specific endpoint, something like this `.antMatchers("/api/foos").authenticated()`, I think I read it somewhere before, haven't tried yet though. – Royts Oct 28 '19 at 06:21