Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring Security OAuth Java Config

I have a Spring app -- not a Spring Boot app -- that I'm trying to declare a section of the API as OAuth2 protected using Spring Security. My authorization and general resource access config works great when I define http elements in the XML, but when I try to implement the resource access blocks using ResourceServerConfigureAdapter#configure(HttpSecurity) -- complete with @EnableResourceServer etc, that configure method never even fires (end to end tests also fail). Example Java config below:

        @Override
        public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
            resources.resourceId("oauth2/control");
        }

        @Override
        public void configure(HttpSecurity http) throws Exception {
            http.antMatcher("/api/**")
                .authorizeRequests().anyRequest().hasRole("OAUTH_USER").and()
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
                // before=PRE_AUTH_FILTER
                .addFilterBefore(oAuth2AuthenticationProcessingFilter, AbstractPreAuthenticatedProcessingFilter.class)
                .csrf().disable()
                .anonymous().disable()
                .exceptionHandling()
                .accessDeniedHandler(oAuth2AccessDeniedHandler)
                .authenticationEntryPoint(loginUrlAuthenticationEntryPoint);
        }

I have tried declaring a few different ways of effecting the config, but no dice. Namely, I have tried both top level @Configuration classes extending ResourceServerConfigurerAdapter and bean methods returning ResourceServerConfiguration as in Dave Syer's example; I've also tried explicitly setting order to Ordered.HIGHEST_PRECEDENCE on the appropriate beans.

It's quite possibly important to note that most of the application's legacy security config is defined via XML elements like the above. Another possible red flag about my configuration -- in order to get the token endpoint to authenticate against basic auth client_id:client_secret I had to wire my own BasicAuthFilter(ProviderManager(DaoAuthProvider(ClientUserDetailsService(clientDetailsService))))) when, because it's the vanilla and 'right' way to authenticate the token endpoint, I'd expect spring config to just default to it.

Anyway, in no situation can I get ResourceServerConfigureAdapter#configure(HttpSecurity) to fire. My going theories are:

  • Something about the preceding XML HTTP blocks is preventing my configure method from ever even being called

  • This is simply a Spring Boot only feature -- although I've seen no language to that effect

  • There's straight up some object in the application context that I'm missing (again, the operative annotations that I have at work -- besides the obvious @Configuration and @Bean -- are @EnableWebSecurity, @EnableAuthenticationServer, and @EnableResourceServer).

  • I've made some configuration error (duh).

Any examples would be much appreciated

Example OAuth2 configuration class (one of a few different iterations) below:

@Configuration
@EnableWebSecurity
@EnableResourceServer
public class OAuth2Configuration {
    ... etc ...

    @Bean
    public ResourceServerConfiguration adminResources() {
        // copped from https://github.com/spring-projects/spring-security-oauth/tree/master/tests/annotation/multi
        ResourceServerConfiguration resource = new ResourceServerConfiguration() {
            public void setConfigurers(List<ResourceServerConfigurer> configurers) {
                super.setConfigurers(configurers);
            }
        };

        resource.setConfigurers(Collections.singletonList(new ResourceServerConfigurerAdapter() {

            @Override
            public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
                resources.resourceId("oauth2/control");
            }

            @Override
            public void configure(HttpSecurity http) throws Exception {
                http.antMatcher("/api/**")
                    .authorizeRequests().anyRequest().hasRole("OAUTH_USER").and()
                    .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
                    // before=PRE_AUTH_FILTER
                    .addFilterBefore(oAuth2AuthenticationProcessingFilter, AbstractPreAuthenticatedProcessingFilter.class)
                    .csrf().disable()
                    .anonymous().disable()
                    .exceptionHandling()
                    .accessDeniedHandler(oAuth2AccessDeniedHandler)
                    .authenticationEntryPoint(loginUrlAuthenticationEntryPoint);
            }

        }));
        resource.setOrder(Ordered.HIGHEST_PRECEDENCE);

        return resource;
    }

    @Configuration
    @EnableAuthorizationServer
    public static class OAuth2AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
      ... etc ...
    }
}

Analogogous <http> config that is picked up:

<sec:http pattern="/api/**" create-session="stateless"
          entry-point-ref="loginUrlAuthenticationEntryPoint">
    <sec:anonymous enabled="false" />
    <sec:csrf disabled="true"/> <!-- csrf tokens don't make sense for a 3rd party API -->
    <sec:custom-filter ref="oauth2ProcessingFilter" before="PRE_AUTH_FILTER"/>
    <sec:access-denied-handler ref="oauthAccessDeniedHandler" />
    <sec:intercept-url pattern="/api/**" access="hasRole('OAUTH_USER')" />
</sec:http>
like image 960
jwilner Avatar asked Nov 09 '22 09:11

jwilner


1 Answers

If you are simultaneously using both Java-based and XML-based security configuration, only the XML-based will be picked up. Have you tried disabling/commenting-out all your XML-based http security config and see if your Java-based would activate?

I had a similar problem before. I asked help at the Spring Security Gitter channel and also did some investigation. See below:

enter image description here

like image 111
sofiaguyang Avatar answered Nov 14 '22 23:11

sofiaguyang