2
votes

I'm using Spring Security in my application to protect most of my endpoints. I'm using Spring Security OAuth2 to protect a certain subset. This subset of OAuth protected endpoints are going to be accessed both by external servers, and by users on the resource server itself.

Is it possible to have both kinds of protection on this endpoint, and use either-or? If a user is accessing the endpoint from an external server they will need an OAuth access token to get in, if the user is logged into the resource server directly they will not have an access token, but I would like to use my other filter chain to do my standard authentication.

I've never seen an HTTP block with two separate filter chains before, but maybe there's some way to do it that I don't know of.

1

1 Answers

7
votes

I don't think you need 2 filter chains for the protected resources, just some access rules that take into account the different authentications that might be encountered. The sparklr2 demo is a resource server that accepts cookies as well as tokens on its /photos endpoints for example. In sparklr you have 1 filter chain (a WebSecurityConfigurerAdapter) for the login and authorization endpoints, and 1 (a ResourceServerConfigurerAdapter) for the protected resourecs. By default the ResourceServerConfigurerAdapter is applied before the WebSecurityConfigurerAdapter so it has to not match the login and authorization resources. The relevant matchers and access rules are like this:

    @Override
    public void configure(HttpSecurity http) throws Exception {
        // @formatter:off
        http
            // Since we want the protected resources to be accessible in the UI as well we need 
            // session creation to be allowed (it's disabled by default in 2.0.6)
            .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED)
        .and()
            .requestMatchers().antMatchers("/photos/**", "/oauth/users/**", "/oauth/clients/**","/me")
        .and()
            .authorizeRequests()
                .antMatchers("/me").access("#oauth2.hasScope('read')")                  
                .antMatchers("/photos").access("#oauth2.hasScope('read') or (!#oauth2.isOAuth() and hasRole('ROLE_USER'))")                                        
        ...
    }

Here you see an OAuth only resource (/me) and one that works with tokens or cookies (/photos) because of the access rules.