Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring Boot 1.3.3 @EnableResourceServer and @EnableOAuth2Sso at the same time

I want my server be a ResourceServer, which can accept a Bearer Access token

However, If such token doesn't exist, I want to use the OAuth2Server to authenticate my user.

I try to do like:

@Configuration
@EnableOAuth2Sso
@EnableResourceServer
public class SecurityConfiguration extends WebSecurityConfigurerAdapter{

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests().anyRequest().authenticated();
    }
}

However, in this case, only the @EnableResourceServer annotation works. It returns

Full authentication is required to access this resource

And do not redirect me to the login page

I mentioned that the @Order is important, if I add the @Order(0) annotation, I will be redirect to the login page, however, I cannot access my resource with the access_token in Http header:

Authorization : Bearer 142042b2-342f-4f19-8f53-bea0bae061fc

How can I achieve my goal? I want it use Access token and SSO at the same time.

Thanks~

like image 732
Fallflame Avatar asked May 05 '16 19:05

Fallflame


1 Answers

Using both configuration on same request would be ambiguous. There could be some solution for that, but more clear to define separate request groups:

  • OAuth2Sso: for users coming from a browser, we want to redirect them to the authentication provider for the token
  • ResourceServer: usually for api requests, coming with a token they got from somewhere (most probably from same authentication provider)

For achieving this, separate the configurations with request matcher:

@Configuration
@EnableResourceServer
public class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {

    @Bean("resourceServerRequestMatcher")
    public RequestMatcher resources() {
        return new AntPathRequestMatcher("/resources/**");
    }

    @Override
    public void configure(final HttpSecurity http) throws Exception {
        http
            .requestMatcher(resources()).authorizeRequests()
            .anyRequest().authenticated();
    }

}

And exclude these from the sso filter chain:

@Configuration
@EnableOAuth2Sso
public class SsoSecurityConfiguration extends WebSecurityConfigurerAdapter {

    @Autowired
    @Qualifier("resourceServerRequestMatcher")
    private RequestMatcher resources;

    @Override
    protected void configure(final HttpSecurity http) throws Exception {
        RequestMatcher nonResoures = new NegatedRequestMatcher(resources);
        http
            .requestMatcher(nonResoures).authorizeRequests()
            .anyRequest().authenticated();
    }
}

And put all your resources under /resources/**

Of course in this case both will use the same oauth2 configuration (accessTokenUri, jwt.key-value, etc.)

UPDATE1:

Actually you can achieve your original goal by using this request matcher for the above configuration:

new RequestHeaderRequestMatcher("Authorization")

UPDATE2: (Explanation of @sid-morad's comment)

Spring Security creates a filter chain for each configuration. The request matcher for each filter chain is evaluated in the order of the configurations. WebSecurityConfigurerAdapter has default order 100, and ResourceServerConfiguration is ordered 3 by default. Which means ResourceServerConfiguration's request matcher evaluated first. This order can be overridden for these configurations like:

@Configuration
@EnableResourceServer
public class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {

    @Autowired
    private org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfiguration configuration;

    @PostConstruct
    public void setSecurityConfigurerOrder() {
        configuration.setOrder(3);
    }
...
}

 

@Configuration
@EnableOAuth2Sso
@Order(100)
public class SsoSecurityConfiguration extends WebSecurityConfigurerAdapter {
...
}

So yes, request matcher is not needed for SsoSecurityConfiguration in the above sample. But good to know the reasons behind :)

like image 95
plajko Avatar answered Dec 31 '22 23:12

plajko