在REST微服务上使用Zuul Proxy,Oauth2实现身份验证和授权

时间:2019-01-23 17:02:10

标签: spring-boot oauth-2.0 microservices spring-security-oauth2 netflix-zuul

Microservices Architecture

我正在尝试使用Spring Boot在工作流中实现上述架构。

  • Web客户端通过Zuul代理向资源服务器(微服务端点)发出请求。
  • Zuul代理重定向到oauth2服务器进行身份验证。
  • 如果请求已通过身份验证,则Oauth2重定向到Zuul代理。
  • 如果未通过身份验证,Zuul将使用未经身份验证的响应重定向Web客户端。
  • 如果通过身份验证,则Zull代理将重定向到请求的微服务端点。
  • 微服务端点检查用户是否被授权(用户级访问)访问资源。
  • 微服务还可以在内部调用其他微服务。
  • 最后,请求的资源被发送回客户端。

我想确保我遵循正确的工作流程。

我想知道是否有解决方案已实施了类似的方法来保护微服务API。

我对以下问题感到困惑

  • 我们如何将用户详细信息传递给微服务,以便微服务可以进行自己级别的用户授权?
  • 是否应将OAuth2访问令牌标头传递给每个微服务,以便微服务可以分别验证令牌?
  • 每个微服务是否都应使用秘密凭据来验证访问令牌,以使令牌不能沿着请求链伪造?

我知道这是一个冗长的问题。但是我还没有找到上述架构的合适解决方案。

4 个答案:

答案 0 :(得分:0)

不幸的是,我没有完整的答案,只有部分内容:

一旦JWT令牌可供zuul代理使用,则每个微服务都可以通过配置其资源服务器来授权请求​​,例如

 @Override
  public void configure(HttpSecurity http) throws Exception {
    http
        .authorizeRequests().anyRequest().access("#oauth2.hasScope('microserviceA.read')").and()
        .csrf().disable()
        .httpBasic().disable();
  }

范围可以由带有数据库的oauth微服务管理-基于客户端凭据,它将获取范围信息并编码为JWT令牌。

我目前不知道的-如何使zuul代理使用“ Web客户端”凭据通过oauth进行自我授权-我不想对zuul代理凭据进行硬编码,因为那时Web-客户信誉将不会被使用。

我刚刚在这个主题上发布了类似的问题: Authorizing requests through spring gateway with zool via oauth server

更新: 我发现有一篇文章几乎描述了这种配置(没有eureka,但从我的经验来看,并没有增加太多复杂性):https://www.baeldung.com/spring-security-zuul-oauth-jwt,有一个带有源代码的github项目。不幸的是,源代码未完善,因为作者正在将其用于商业课程。 但是我已经设法从他的示例工作集中构建了。

摘要:在所描述的体系结构中,每个资源服务器(微服务A,B,..)都从zuul代理/网关接收来自请求客户端的JWT令牌。令牌在请求标头中转发。如果没有提供有效令牌,则网关会将请求重定向到授权页面。 此外,每个资源服务器都可以使用oauth服务检查令牌,如果需要,请按照我上面的描述进行范围检查。

答案 1 :(得分:0)

我一直在为基于Spring Cloud解决方案的微服务架构解决相同的安全设计问题。我只发现这篇文章对此有所启发:https://developer.okta.com/blog/2018/02/13/secure-spring-microservices-with-oauth

但是它与Okta sso服务提供商有关,而不是对其他oauth2服务器(例如密钥斗篷)的通用解决方案。

我还看到了一些有关如何使用oauth2服务器保护网关和微服务的解决方案,如下所示: https://github.com/jgrandja/oauth2login-gateway

但是它没有考虑Web客户端。

答案 2 :(得分:0)

我不确定您是否能够解决此问题,可以看到还没有解决,但是有一种方法可以将所有信息从JWT传递到所有下游微服务。 编写自己的ZuulAuthenticationFilter,然后创建以下方法

private void addClaimHeaders(RequestContext context, String token) {
    
    try {
        
        Map<String, Claim> claims = jwtTokenVerifier.getAllClaims(token);
        claims.forEach((key, claim) -> {
            
            context.addZuulRequestHeader("x-user-info-"+key, String.valueOf(claim.as(Object.class)));
        });
        
    }catch(Exception ex) {
        
        log.error("Error in setting zuul header : "+ex.getMessage(), ex);
    }
}

这样,您将在每个微服务的标头中从JWT获取信息,以“ x-user-info-”开头的标头将包含您的JWT详细信息

答案 3 :(得分:-1)

以下链接中有上述架构的实现: https://www.baeldung.com/spring-security-zuul-oauth-jwt