如何使用spring-session和spring-security-oauth保护相同的资源

时间:2018-01-18 18:31:33

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

我要求使用两种身份验证, 对于web我们@EnableRedisHttpSession和其他消费者,比如移动我们使用@EnableAuthorizationServer和@EnableResourceServer。

假设我们尝试保护两个身份验证机制共同的控制器,例如/ api / v1 / test

我遇到了障碍。 我只能使用一种身份验证方案 如果我设置@WebSecurityConfigurerAdapter @order(2)和@ResourceServerConfigurerAdapter @order(3)那么我只能通过网络访问资源

如果我设置@ResourceServerConfigurerAdapter @order(2)和@WebSecurityConfigurerAdapter @order(3),那么只有OAuth可以工作。

我无法同时使用这两种机制。我们可以让两者一起工作,例如,如果请求来自Web使用负责该过滤器的过滤器,并且如果请求来自移动设备,则使用适当的过滤器。 web使用cookie和API使用者使用Authorization:Bearer标题。

请帮助

1 个答案:

答案 0 :(得分:2)

这听起来很奇怪。我建议您查看REST API的使用方式以及浏览器用户应该如何使用它。最好将Web视图和REST API分开,不要混用它。

无论如何,作为您问题的答案“我可以同时对某些URI使用两种身份验证” - 是的,您可以。
为此,您需要一个自定义RequestMatcher来决定如何路由传入的请求。

所以:

  • 表示“API使用者” - 检查Authorization标题的存在 包含“Bearer”
  • 代表“浏览器用户” - 只是反向第一条规则

代码示例:

public abstract class AntPathRequestMatcherWrapper implements RequestMatcher {

    private AntPathRequestMatcher delegate;

    public AntPathRequestMatcherWrapper(String pattern) {
        this.delegate = new AntPathRequestMatcher(pattern);
    }

    @Override
    public boolean matches(HttpServletRequest request) {
        if (precondition(request)) {
            return delegate.matches(request);
        }
        return false;
    }

    protected abstract boolean precondition(HttpServletRequest request);

}
  1. OAuth2身份验证
  2. @EnableResourceServer
    @Configuration
    public class ResourceServerConfigurer extends ResourceServerConfigurerAdapter {
        @Override
        public void configure(HttpSecurity http) throws Exception {
            http.requestMatcher(new AntPathRequestMatcherWrapper("/api/v1/test") {
                @Override
                protected boolean precondition(HttpServletRequest request) {
                    return String.valueOf(request.getHeader("Authorization")).contains("Bearer");
                }
            }).authorizeRequests().anyRequest().authenticated();
        }
    }
    
    1. 网络身份验证
    2. @Configuration
      @EnableWebSecurity
      public class WebSecurityConfigurer extends WebSecurityConfigurerAdapter {
      
          @Override
          protected void configure(HttpSecurity http) throws Exception {
              http.requestMatcher(new AntPathRequestMatcherWrapper("/api/v1/test") {
                  @Override
                  protected boolean precondition(HttpServletRequest request) {
                      return !String.valueOf(request.getHeader("Authorization")).contains("Bearer");
                  }
              }).authorizeRequests().anyRequest().authenticated();
          }
      }
      

      使用此配置,可以为一个URI /api/v1/test使用两种不同的身份验证类型。

      此外,我强烈建议阅读Dave Syer关于Spring Security架构的文章,了解它是如何工作的:
      https://spring.io/guides/topicals/spring-security-architecture/#_web_security