Spring Boot 1.3.3同时使用@EnableResourceServer和@EnableOAuth2Sso

17

我希望我的服务器成为一个ResourceServer,可以接受Bearer Access token。

但是,如果这样的token不存在,我想使用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。

谢谢~

1个回答

14

在同一请求中同时使用这两个配置可能会产生歧义。虽然有一些解决方案,但更清晰的方法是定义单独的请求组:

  • 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) 部分是不必要的。 - SidMorad
嗨,谢谢!我在原帖的 UPDATE2 部分回应了您的评论。 - plajko
如果这个答案有帮助,请接受答案,这将对其他人有所帮助。 - Akshatha S R
我在Zuul网关上遇到了类似的问题。使用解决方案中的更新#1解决了它。 - Mitesh

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接