Zuul - API 网关认证

39

我想通过Spring Cloud中的Zuul作为API网关引入一些服务。

我对身份验证存在一些设计疑问。身份验证将由Spring Security处理,在servlet过滤器链中位于Zuul之前。

我的担忧:

  • 网关将位于许多服务之前

  • 一些服务可能会公开不需要身份验证的端点

  • 一些服务可能会公开需要Session Id和一些使用令牌的端点,即任意的不透明值(例如,如果您知道一个“难以猜测”的url下载文件) 在API网关/Spring Security中,您可以配置所有端点及其特定的身份验证要求。

在管理API网关方面:

  • 如何强制实际的服务团队提供每个下游服务所需的设置?
  • 如何允许网关频繁更改身份验证设置(根据服务需求)而无需停止整个网关?

谢谢, Adrian

2个回答

28

我们正在使用Spring Session来复制会话,使其在Zuul Edge Server后面的所有服务中同步。 Zuul将对用户进行身份验证,填充用户凭证并将经过身份验证的用户插入会话中。 然后,这将在所有服务之间进行复制,每个服务都负责自己的安全规则和设置。 因此,实际上,Zuul只是在Spring Security中查找用户,而后端的服务正在根据其需求执行安全规则。 这样,您可以独立更改每个服务,使网关成为一个简单的代理。

这种方法的一个很好的例子是Dave Syers关于Spring Security和Angular JS应用程序的教程。 我还发布了另一个相关问题,其中包含我们如何做到这一点的示例,这可能有所帮助。


1
好的,所以Zuul将查找用户并填充会话,并路由到服务。 服务本身将指定哪些端点需要身份验证以及何种类型的身份验证。因此,这个责任将由服务团队承担。这很好。 我的想法是我可以解放服务团队,使其不必再负责这项任务。 - Adrian Ivan
3
我在这里烦恼的是,必须通过网关来使下游应用程序工作。网关并不那么愚蠢,会话创建仍然是业务逻辑。通过数据存储共享该会话是不可避免的高度耦合,我仍然不明白为什么Spring推荐在微服务架构中使用它。 - Michael Técourt
1
你有更好的解决方案建议吗,@MichaelTecourt?我也不太喜欢会话复制作为解决方案,但还没有找到更好的方法。 - Andrew Serff
4
我不知道这个方法是否更好,只是一种不同的妥协。上周有一个来自Pivotal的人用与您相同的方法做了一个演示,声称这比我的优化得多:) 我选择使用OAuth 2.0为每个应用程序提供安全保护。应用程序通过向授权服务器发出HTTP调用来验证它们收到的访问令牌,并在交换中返回用户信息。在双方都添加了缓存(非共享)以加快进程。应用程序明显解耦,可以独立测试,但代价是使授权服务器成为瓶颈/单点故障。 - Michael Técourt
2
你的方法和那个关键人物之间唯一的区别在于,他使用JWT来保护每个应用程序(而不是通过HTTP调用来验证令牌),只有用户信息查找依赖于共享缓存。 - Michael Técourt

6
  • 网关将位于许多服务的前面。

这里的问题是什么?

  • 一些服务可能会公开不需要身份验证的端点。

Spring Security有一个permitAll()访问规则。

  • 一些服务可能会公开需要Session Id和一些带有令牌的端点,这是任意的不透明值(例如,如果您知道“难以猜测”的url,则可以下载文件)。在API Gateway/Spring Security中,您可以配置所有端点及其特定的身份验证要求。

您的Zuul代理可以具有会话。如果您使用Spring Security OAuth 2.0,则可以使用ResourceServerSecurityConfigurer#stateless(false)并通过HttpSecurity#sessionManagement().sessionCreationPolicy(...)激活会话,每次接收到有效访问令牌时都会创建会话。 JSESSIONID Cookie将放置在HTTP响应中。

  • 如何强制实际服务团队根据下游服务提供所需的设置?

我不确定我是否理解这个问题,您不想在API Gateway(Zuul代理)级别执行安全约束吗?还是您试图在代理和目标应用程序上都进行“安全双重检查”?

  • 如何允许网关中频繁的身份验证设置更改(根据服务需求),而无需停止整个网关?

Zuul允许您在运行时动态添加ZuulRoute,如果您将其用作独立库的话。如果包装在Spring Security中,其上下文在启动时只初始化一次...我怀疑您可以轻松地在运行时更改安全配置。

根据评论中OP的澄清编辑: 如果您的团队应对其安全规则负责,则具有集中式网关是设计上的矛盾。

我对微服务哲学的理解是,每个应用程序都是独立的,并负责其完整的功能范围和安全/访问控制。您可以轻松验证应用程序级别的令牌(通过向授权服务器发出调用或使用JWT),每个应用程序定义每个资源所需的范围。 Spring Cloud已经有一个OAuth 2.0 starter,如果使用“纯”Spring Boot,则可以轻松创建一个。

这样,您可以在任何地方部署单个应用程序(公共云或本地服务器),而无需依赖上游组件进行安全性或同步网关配置部署与其他团队。

API Gateway是一个简单的诱惑,但不要忽视风险和限制:

  • 您将无法保护内部通话
  • 您将不得不依赖上游网络组件,并默认应用程序的输入
  • 高级访问控制规则可能会成为一个头痛:如何获得用户的个人权限等
  • 您将不得不与其他团队同步配置更改

我需要解释得更好一些。我的主要关注点是,我希望为服务团队提供编辑网关中属于其服务的身份验证设置的机会和责任。我不希望网关成为组织瓶颈。 就路由方面而言,情况看起来更好了,因为正如你所说,可以动态添加路由过滤器,因此每个团队都可以以某种方式提供这些过滤器。 - Adrian Ivan
这个想法是在 Gateway 处理身份验证,在服务层级中准备好 Principal 并且只对服务进行身份验证(请求来自我信任的服务)。 - Adrian Ivan
“我信任的服务收到了请求”如果没有应用程序级别的安全性校验是不可能验证的。关于你的安全性依赖于网关填充的一些共享状态:它会在组件之间引入大量不可见的耦合,并且对“网关已经完成或未完成”的上游依赖性,但对于你的需要来说,这可能是一个足够公平的妥协。 - Michael Técourt
谢谢Michael,我会很快回来分享我的看法。 - Adrian Ivan

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