我使用带有JWT的Spring Boot 1.5.x + OAuth2开发了一组微服务(资源服务器)。目前,每个微服务都受到Spring Security的保护,即JWT访问令牌已在各个资源服务器级别进行了验证。 API Gateway没有适当的Spring安全性,因此它只是将请求路由到适当的服务器,并将身份验证标头传播到下游服务。
我想知道与仅在API网关级别验证AccessToken的设置相比,此设置是否有任何缺点。还是只是见仁见智?将安全性保持在API网关级别不会破坏松散耦合的原理,因为每个微服务可能会更好地了解给定用户在其自身上下文中的角色?
答案 0 :(得分:2)
API管理可以对您的JWT进行一次小检查(尽早失败),但是您的微服务是唯一可以真正管理所有安全性的工具!
如果仅在api管理上设置安全性,则意味着可以访问您的网络的人将能够未经授权将请求推送到您的API。 您将无法记录谁在做什么。最后,如果您需要设置某种ACL,则不可能(当您要求列出订单时,只能列出您的订单)。
也许您会考虑在api管理层上对JWT进行解码,并将带有用户名的标头推送到您的后端,以防止上述所有事情发生,但是我认为这并不是一个好习惯。
首先,访问网络意味着我可以成为任何人。那么,JWT不仅仅是一个用户名。例如,也许您在验证层上使用范围。 (合并范围读取订单/合并范围修改订单/合并范围删除订单)。这对于限制应用程序可以做什么(在client_id级别上)或用户接受给应用程序的范围(作用域共享电子邮件...)很有用。 对于此JWT,必须在后台进行。
好吧,您可以喜欢用户名并提取有关api管理的数据,并将特定的标头放入后端,但这真的吗?为什么要具体的东西?带有JWT的oauth2可以为您做到这一点。
答案 1 :(得分:2)
这是一个有趣的问题。在我们的团队中,我们就该主题进行了很多讨论。基本上,您有一些参数会影响该问题的单个答案。但是,您也应该始终在微服务级别上解码和验证授予的令牌。因为它们包含有关身份验证的信息,在某些情况下甚至包含授权的信息。如果您的微服务在封闭的环境中运行(例如在封闭的Kubernetes集群上,外部只有API-Gateway可用),则可以使用这种“混合”解决方案。
您真的可以考虑只在API网关上验证AccessToken并让其他微服务依赖于API网关。然后,API网关可以将AccessToken交换为另一个AuthToken,仅在微服务上下文中有效。例如,此新生成的AuthToken可以包含更敏感的应用程序绑定信息,因为它不会暴露给客户端。客户端仅获得所谓的不透明令牌。参见https://medium.com/tech-tajawal/microservice-authentication-and-authorization-solutions-e0e5e74b248a