【问题标题】:How to deal with authentication in a micro-services architecture如何处理微服务架构中的身份验证
【发布时间】:2018-09-24 22:49:35
【问题描述】:

我目前正在阅读很多有关微服务的内容,但我仍然不了解某些部分。我做了以下画:

每个微服务有 2 次访问:

  • REST:用于 http
  • gRPC:用于内部/后台通信/交换

如果我想登录,我可以向我的身份验证服务发送一个 Http 请求。但是,如果我想访问需要您已经连接的 Stuff 服务呢?

假设用户想要显示数据库 STUFF 中可用的东西,服务 Stuff 将首先检查连接用户的“令牌”是否正确,通过与身份验证服务交换,然后返回这些东西或“登录需要请求”。

所以我不明白的是,如果需要已连接客户端的每个服务都需要与身份验证进行交换,那么它将创建巨大的互联网流量以检查每个用户请求.. 所以我想每个服务一个身份验证服务,但既然我应该只有一个数据库,那么是数据库会减慢流量?

另外,如果我理解的话,每个微服务应该在不同的服务器上,而不是同一个服务器上?

我希望我清楚,不要犹豫,询问更多细节!

提前致谢:)

最大

编辑 1

基于@notionquest 的回答:

所以应该更像这样吧?

此外,根据 Peter 的评论,每个服务都可以实现自己的中间件(如前所述的 JWT),因此 API 网关只是“传递”。但是,我觉得这对我来说不是一件好事,因为每个服务都会对每个内部交易所进行令牌检查,不是吗?

对于这些东西,这很容易,因为它只检查 1 次令牌。现在,假设用户拿到东西后,他选择了一个并想购买它。然后“购买服务”将调用 stuff 服务以验证商品的价格,但是......它必须检查用户令牌,因为东西是“经过身份验证的访问”,所以这意味着“购买" 服务和 "Stuff" 服务都检查令牌,这增加了一个额外的检查。

我虽然关于服务之间的内部保证访问但值得吗?

另外,也许您说要为每个服务实现中间件,因为它们具有 REST 访问权限,但 API 网关只会破坏拥有 REST 访问权限的想法

【问题讨论】:

  • 不要低估单个 authz/authn 服务可以处理多少。实际上,它只是通过主键查找单个数据库行。一个流行的替代方案是 JWT。但在你跳上微服务火车之前,请注意它们解决了组织问题,但会产生技术问题——很多。不要因为它很现代而这样做。
  • 感谢您的回答!我不这样做是因为它是现代的,我有一个真正的需求:) 我读过 JWT 并且我已经在 Monolith 方法中使用了它,但是我仍然必须共享在每个服务之间进行 JWT 检查的服务。我只是担心互联网流量交换,我不希望获得太多请求的服务会减慢其他服务:/
  • JWT 经过专门的加密签名,因此您不必与任何人签到。它们是自包含的证明。
  • @Peter 根据您的回答和概念的小更新

标签: microservices grpc


【解决方案1】:

对于这个问题有多种解决方案。解决方案之一是API Gateway pattern

  1. 第一个请求转到 API 网关
  2. API 网关对请求进行身份验证和授权
  3. 身份验证存储在缓存数据库中,例如 Redis、Memcache 等,并带有过期时间
  4. 保存的访问令牌返回给客户端
  5. 客户端可以在随后的调用中使用保存的访问令牌一段时间(即直到令牌有效)
  6. 令牌过期后,API 网关将进行身份验证并将新令牌共享给客户端
  7. 此解决方案将减少对每个请求进行身份验证的需要并提高性能

API 网关是所有服务的单一入口点。因此,您可能不需要为每个服务单独缓存。

请参阅此page 中的图表。

【讨论】:

  • 感谢您的回答。这意味着每个服务都应该有自己的标记化缓存吗?所以它不必与认证服务通信
  • 更新了答案。 API 网关是所有服务的单一入口点。因此,您可能不需要为每个服务单独缓存。
  • 好吧,我觉得很有趣!但是现在,API 网关必须处理所有的请求,这就像一个整体方法一样,不是吗?
  • 不,它不是一个单一的应用程序。它是所有服务前面的附加层,用于执行身份验证、聚合等常见任务。我想如果你能阅读完整的博客,你会得到更多的理解。
  • 我根据您的回答和彼得的回答做了一点更新
【解决方案2】:

除了@notionquest 答案,还有另一种方法不涉及使用 API 网关;

您可以在所有服务之间共享SESSION_SECRET,因此身份验证服务的唯一任务是根据数据库验证用户名和密码,然后使用SESSION_SECRET 加密此信息并返回jwt token。所有其他服务都不需要与 Authentication Service 交互,只需使用 SESSION_SECRET 检查 jwt 令牌是否有效(可以解密)。

然后您还有另外两个选择;

  1. 将您需要的所有用户数据存储在令牌中 - 这将增加从客户端传输到微服务的数据量。这可能会令人望而却步,具体取决于此信息的大小

  2. 您可以仅存储 userId,并根据每个微服务的需要请求其他数据,这取决于您的数据的频率/大小会产生您所描述的问题。

请注意,您并不总是能够使用这种方法,但根据您的特定场景和要求,考虑到这种架构可能会很有用。

还要记住,旋转SESSION_SECRET 可能会很棘手(尽管出于安全原因是必要的)。 AWS 刚刚发布了一项名为AWS Secrets Manager 的服务,因此,让事情变得简单的一个想法是让您的微服务定期查询这样的服务以获取当前有效的SESSION_SECRET,而不是将这些值硬编码或作为环境变量。

【讨论】:

  • 感谢您的编辑和回答。我觉得,有了你所有的答案(而且因为我根本没有从事安全编程工作),最后,每种方法都保持不安全......并且可以很容易地进行逆向工程:/
  • 不客气,@Emixam23 你能详细说明你为什么认为它不安全吗?
  • 这不是最初问题的主要目的,但是假设我有一个使用给定密钥加密的 JWT 令牌。这意味着任何人都可以使用这个令牌来访问每个 API,然后做他们想做的任何事情。我想要的是拥有一些公共 MS 和一些私人 MS。对于私人的,我想确保它是我应用程序中的某个人,而不是其他人。如果只是传输的 JWT 令牌,那么令牌可以被数据包捕获并重用:/
  • 没错。但这对于网络中的大多数网站都是如此。例如,如果有人获得了对您的会话 cookie 的访问权,那么任何人都可以冒充您自己。这就是人们目前使用https的原因。但我理解你的担忧。
  • 另外,如果你想拥有私有的微服务(从某种意义上说,它们不对网络开放),那么你应该使用 API 网关。亚马逊AWS为此专门提供了一项服务,你可能想看看。
猜你喜欢
  • 1970-01-01
  • 2015-09-11
  • 1970-01-01
  • 1970-01-01
  • 2017-05-28
  • 2017-10-05
  • 1970-01-01
  • 2020-09-26
  • 2018-07-17
相关资源
最近更新 更多