0

I have Spring web app with REST WS built using spring-security-oauth2:2.3.3 and spring-boot-starter-security:2.0.2. But I am not able to set which endpoints are protected.

ResourceServerConfig

@EnableResourceServer
@Configuration
public class ResourceServerConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .antMatchers("/", "/customers", "/v2/**").permitAll()
                .antMatchers("/api/**").authenticated();
    }

    @Bean
    public AuthenticationManager authenticationManager(AuthenticationProvider authenticationProvider) {
        return new CustomAuthenticationManager(authenticationProvider);
    }

    @Bean
    public AuthenticationProvider authenticationProvider(UserRepository userRepository, PasswordEncoder passwordEncoder) {
        return new DBAuthenticationProvider(userRepository, passwordEncoder);
    }

}

AuthorizationServerConfig

@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {

    @Autowired
    private AuthenticationManager authenticationManager;

    @Override
    public void configure(AuthorizationServerSecurityConfigurer security) {
        security.checkTokenAccess("isAuthenticated()");
    }

    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        clients
                .inMemory()
                .withClient("ClientId")
                .secret("secret")
                .authorizedGrantTypes("password")
                .scopes("read", "write");
    }

    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) {
        endpoints.authenticationManager(authenticationManager);
    }
}

When I obtain access token first, everything works perfectly, but I expect endpoints "/", "/customers", "/v2/**" to be permited for all without any authorization. But when I call 'curl http://{{host}}/' or http://{{host}}/customers I still get 401:

{"error":"unauthorized","error_description":"Full authentication is required to access this resource"}

adding "--header "Authorization: Basic {{base64 client id:password}}" doesnt help either. How is that possible?

EDIT according to spring security permitAll still considering token passed in Authorization header and returns 401 if token is invalid solved by adding @Order(1) to ResourceServerConfig to override default OAuth2. But that should kick in only when "Authorization" header is added, which is not my case. So how is this possible?

Dlike
  • 73
  • 1
  • 1
  • 8
  • What method are you using when call with the curl? Do you have a endpoint mapped to this url? Are you generating a token to your client? – Allan Braga Jun 04 '18 at 13:58
  • I call 'curl -X GET http://localhost:8080/customers' while having application deployed locally using tomcat on port 8080. Endpoints are correctly mapped during application start (i.e. RequestMappingHandlerMapping : Mapped "{[/customers],methods=[GET]}" onto public java.lang.String com.david.demo.customer.CustomerViewController.showCustomersList(org.springframework.ui.Model)). – Dlike Jun 04 '18 at 14:05
  • I am not generating any token. I expect context paths "/", "/customers", "/v2/**" to be public! – Dlike Jun 04 '18 at 14:07
  • Try to see this: https://stackoverflow.com/questions/36296869/spring-security-permitall-still-considering-token-passed-in-authorization-header – Allan Braga Jun 04 '18 at 14:33
  • Wow, adding @Order(1) really did help. But I dont understand why. Oauth2 should intercept only when header "Authorization" is added while calling permitted endpoints. But when I use curl, i am pretty sure I dont add it though. There was no need for AnonymousAuthFilter – Dlike Jun 04 '18 at 14:40

1 Answers1

0

Add this to your project.

@Configuration
public class ResourceServer extends ResourceServerConfigurerAdapter {
    @Override
    public void configure(HttpSecurity http) throws Exception {
        http.antMatcher("/user/**")
        .authorizeRequests().anyRequest().authenticated();
    }
}

If you want to make any request to /user/** you need to pass your access token in the header as Authorization: Bearer {access_token}. All other endpoints will not ask for a token.

4b0
  • 21,981
  • 30
  • 95
  • 142
Nihil
  • 1
  • 3