微服务之间的访问令牌/授权
Posted
技术标签:
【中文标题】微服务之间的访问令牌/授权【英文标题】:Access Token/Authorization Between Microservices 【发布时间】:2018-01-15 12:45:01 【问题描述】:我正在创建一个主要由移动应用程序使用的在线商店 REST API。该计划是使用 Spring Cloud 框架和 Spring Cloud OAuth 的微服务架构来确保安全性。
我的问题实际上是关于微服务之间通信的最佳实践:我应该让每个服务注册自己的令牌,还是应该只传递用户的令牌?
例如,我有 3 个服务:用户服务、帐户服务、订单服务。 我已经能够实现两个创建订单的过程:一个传递用户的令牌,另一个是每个服务都获得自己的令牌。我对这两种方法都使用了 Feign。
所以对于选项 1:order-service -> GET account-service/account/current
order-service 调用 account-service,它根据令牌中的 userId 返回帐户。然后 order-service 为该帐户创建一个订单。
或者对于选项 2:order-service -> GET account-service/account/user-id/userId
order-service 从发送的 token 中获取 userId,使用自己的 token 调用 account-service,然后使用检索到的帐户创建订单。
我真的不确定哪个选项最适合使用。一个更好地分离信息,但随后需要两个 Feign Client。然而,另一个不需要 2 个客户端,并且将某些端点阻止到外部客户端变得更容易,但是它需要创建额外的端点并且几乎每个服务都需要挖掘 Authentication 对象。
你的想法是什么?有没有人完全以一种或另一种方式实施他们的系统?或者我的想法完全错误。
感谢任何帮助。
【问题讨论】:
dev.to/s2agrahari/… 【参考方案1】:当您进行服务器到服务器通信时,您实际上并不是代表用户行事,而是代表服务器本身行事。为此使用了客户端凭据。
以 curl 为例: curl acme:acmesecret@localhost:9999/oauth/token -d grant_type=client_credentials
您应该对您的 http 客户端执行相同的操作,您将获得访问令牌。用它来调用其他服务。
【讨论】:
【参考方案2】:您应该使用使用client_credentials 流的客户端令牌进行服务间通信。这个流程默认暴露在 spring security oauth 的 /oauth/token 端点上。
除此之外,您还可以使用不暴露于互联网的私有 api,并且使用只能授予 oauth 客户端的角色进行保护。通过这种方式,您可以公开可能限制较少且验证较少的特权 API,因为您可以控制传递给它的数据。
在您的示例中,您可以公开一个公共端点 GET account-service/account/current
(获取有关您自己的信息没有害处)和一个私有 api GET account-service/internal/account/user-id/userId
可以由 oauth 客户端专门用于查询任何现有用户。
【讨论】:
【参考方案3】:我找到了以下 3 个选项:
如果每个微服务都在验证令牌,那么我们可以传递相同的令牌。但问题是——在同一令牌之间可能会过期。
如果我们使用 client_credentials 授权,那么我们有两个问题:一个是,我们需要在下一个微服务中发送用户名/ID。另一个是,我们需要请求两次——第一次是获取访问令牌,然后是实际调用。
如果我们只在 API 网关(不在微服务中)进行令牌验证,那么我们需要从 API 网关在每个微服务中发送用户名。并且需要更改微服务实现以接受该参数/标头。
【讨论】:
以上是关于微服务之间的访问令牌/授权的主要内容,如果未能解决你的问题,请参考以下文章