【问题标题】:Spring Boot 1.3.3 @EnableResourceServer and @EnableOAuth2Sso at the same timeSpring Boot 1.3.3 同时使用@EnableResourceServer 和@EnableOAuth2Sso
【发布时间】:2016-08-31 17:52:41
【问题描述】:

我希望我的服务器是 ResourceServer,它可以接受承载访问令牌

但是,如果这样的令牌不存在,我想使用 OAuth2Server 来验证我的用户。

我尝试这样做:

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

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

但是,在这种情况下,只有 @EnableResourceServer 注释有效。它返回

Full authentication is required to access this resource

并且不要将我重定向到登录页面

我提到@Order很重要,如果我添加@Order(0)注解, 我将被重定向到登录页面,但是,我无法使用 Http 标头中的 access_token 访问我的资源:

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

我怎样才能实现我的目标?我希望它同时使用访问令牌和 SSO。

谢谢~

【问题讨论】:

    标签: spring spring-boot spring-security-oauth2


    【解决方案1】:

    在同一个请求上同时使用这两种配置是不明确的。可能有一些解决方案,但更清楚地定义单独的请求组:

    • OAuth2Sso:对于来自浏览器的用户,我们希望将他们重定向到令牌的身份验证提供程序
    • ResourceServer:通常用于 api 请求,带有从某处获得的令牌(很可能来自同一个身份验证提供程序)

    为此,请使用请求匹配器将配置分开:

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

    并从 sso 过滤器链中排除这些:

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

    并将你所有的资源放在/resources/**

    当然,在这种情况下,两者都将使用相同的 oauth2 配置(accessTokenUrijwt.key-value 等)

    更新1:

    实际上您可以通过使用此请求匹配器进行上述配置来实现您的原始目标:

    new RequestHeaderRequestMatcher("Authorization")
    

    更新 2: (@sid-morad 评论的解释)

    Spring Security 为每个配置创建一个过滤器链。每个过滤器链的请求匹配器按照配置的顺序进行评估。 WebSecurityConfigurerAdapter 默认排序为 100,ResourceServerConfiguration 默认排序为 3。这意味着首先评估ResourceServerConfiguration 的请求匹配器。对于这些配置,可以覆盖此顺序,例如:

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

    所以是的,上面示例中的SsoSecurityConfiguration 不需要请求匹配器。但很高兴知道背后的原因:)

    【讨论】:

    • 您的回答对我很有帮助,谢谢!并想指出new NegatedRequestMatcher(resources) 部分在我的情况下是不必要的。
    • 您好,谢谢!我在原始帖子的 UPDATE2 部分解决了您的评论。
    • 如果回答有帮助,请采纳,对他人有帮助
    • 我在 zuul 网关上有类似的问题。使用解决方案中的 update#1 解决了它。
    猜你喜欢
    • 2017-08-13
    • 2018-12-14
    • 2016-06-26
    • 2016-06-07
    • 2019-01-05
    • 2016-02-18
    • 2017-07-29
    • 1970-01-01
    • 2023-03-19
    相关资源
    最近更新 更多