Spring Security OAuth Java 配置

Posted

技术标签:

【中文标题】Spring Security OAuth Java 配置【英文标题】:Spring Security OAuth Java Config 【发布时间】:2017-01-21 04:31:27 【问题描述】:

我有一个 Spring 应用程序——不是一个 Spring Boot 应用程序——我试图将 API 的一部分声明为使用 Spring Security 保护的 OAuth2。当我在 XML 中定义 http 元素时,我的授权和一般资源访问配置工作得很好,但是当我尝试使用 ResourceServerConfigureAdapter#configure(HttpSecurity) 实现资源访问块时 - 完成 @EnableResourceServer 等,configure 方法甚至永远不会火灾(端到端测试也失败)。下面的示例 Java 配置:

        @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);
        

我尝试过声明几种不同的方式来影响配置,但没有骰子。即,我已经尝试过扩展ResourceServerConfigurerAdapter 的***@Configuration 类和返回ResourceServerConfiguration 的bean 方法,如Dave Syer's example;我还尝试在适当的 bean 上将 order 显式设置为 Ordered.HIGHEST_PRECEDENCE

很可能需要注意的是,大多数应用程序的遗留安全配置都是通过上述 XML 元素定义的。关于我的配置的另一个可能的危险信号 - 为了让令牌端点对基本身份验证 client_id:client_secret 进行身份验证,我必须连接我自己的BasicAuthFilter(ProviderManager(DaoAuthProvider(ClientUserDetailsService(clientDetailsService))))),因为这是验证令牌端点的普通和“正确”方式,我希望spring config默认为它。

无论如何,在任何情况下我都不能让ResourceServerConfigureAdapter#configure(HttpSecurity) 开火。我的理论是:

关于前面的 XML HTTP 块的某些内容阻止了我的 configure 方法从未被调用过

这只是 Spring Boot 独有的功能——尽管我没有看到有这种效果的语言

我在应用程序上下文中直接缺少一些对象(同样,我在工作中的操作注释——除了明显的@Configuration@Bean——是@EnableWebSecurity@EnableAuthenticationServer@EnableResourceServer)。

我犯了一些配置错误(呃)。

任何例子将不胜感激

以下示例 OAuth2 配置类(几个不同的迭代之一):

@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 ...
    

获取的类似&lt;http&gt;配置:

<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>

【问题讨论】:

【参考方案1】:

如果您同时使用基于 Java 和基于 XML 的安全配置,则只会选择基于 XML 的安全配置。您是否尝试过禁用/注释掉所有基于 XML 的 http 安全配置并查看您的基于 Java 的安全配置是否会激活?

我之前也遇到过类似的问题。我在 Spring Security Gitter 频道寻求帮助并进行了一些调查。见下文:

【讨论】:

应该猜到了。谢谢@Sofia!

以上是关于Spring Security OAuth Java 配置的主要内容,如果未能解决你的问题,请参考以下文章

Spring Security 入门(1-3)Spring Security oauth2.0 指南

使用 spring-session 和 spring-cloud-security 时,OAuth2ClientContext (spring-security-oauth2) 不会保留在 Redis

社交登录,spring-security-oauth2 和 spring-security-jwt?

弃用 spring-security-oauth 作为客户端

spring-security-oauth2中的HttpSecurity配置问题

spring-security-oauth2 - 从资源服务器检查ClientDetails