Denis Stephanov
Denis Stephanov

Reputation: 5241

Cannot access to unsecured endpoints in Spring Boot

In my controller I have two endpoints where one is secured and one is public:

@GetMapping("/public")
public String getPublic() {
    return "public";
}

@PreAuthorize("hasRole('USER')")
@GetMapping("/private")
public String getPrivate() {
    return "public";
}

Secured endpoint works only when I am logged and token with right role is placed in request header. But when I want access to public endpoint without token I always got status 401 with error

Full authentication is required to access this resource

Here is my security configuration:

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    public void configure(HttpSecurity http) throws Exception {
        http
            .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
            .and()
            .authorizeRequests().anyRequest().authenticated()
            .and()
            .csrf().disable();
    }
}

and authorization server config:

@Configuration
@EnableAuthorizationServer
public class OAuth2AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {

    private final UserDetailsService appUserDetailService;

    private final AuthenticationManager authenticationManager;

    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) {
        endpoints
                .tokenStore(tokenStore())
                .tokenEnhancer(tokenEnhancer())
                .authenticationManager(authenticationManager)
                .userDetailsService(appUserDetailService);
    }
}

I also tried change .authorizeRequests().anyRequest().authenticated() to this : .authorizeRequests().anyRequest().permitAll() with no change. My preferred way is handle security with annotations. Thank you.

Upvotes: 1

Views: 2356

Answers (2)

Supun Wijerathne
Supun Wijerathne

Reputation: 12948

You have two options, can go with either.

Option 1: In your endpoint, change like this.

@PreAuthorize("permitAll()")  
@GetMapping("/public")
public String getPublic() {
    return "public";
}

And change your configure(HttpSecurity http) method, do like this.

@Override
public void configure(HttpSecurity http) throws Exception {
    http
        .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
        .and()
        .authorizeRequests()
        .anyRequest().permitAll()
        .and()
        .csrf().disable();
}

Option 2: In your configure(HttpSecurity http) method, just do like this.

@Override
public void configure(HttpSecurity http) throws Exception {
    http
        .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
        .and()
        .authorizeRequests()
        .antMatchers("/public").permitAll()  
        .anyRequest().authenticated()
        .and()
        .csrf().disable();
}

Upvotes: 2

kann
kann

Reputation: 737

antMatchers() will do the trick. We use it a lot. It is also better to have insecured endpoints in different class and control security on class level through request mapping.

antMatchers("/public").permitAll()

Link to spring security api - https://docs.spring.io/spring-security/site/docs/current/api/org/springframework/security/config/annotation/web/builders/HttpSecurity.html#antMatcher-java.lang.String-

Upvotes: 0

Related Questions