我正在创建一个主要由移动应用程序使用的在线商店REST API。该计划适用于使用Spring Cloud框架和Spring Cloud OAuth实现安全性的微服务架构。
我的问题实际上是关于微服务之间通信的最佳实践:我应该为每个服务注册他们自己的令牌,还是他们只是传递用户的令牌?
例如,我有3项服务:用户服务,帐户服务,订单服务。 我已经能够实现两个创建订单的程序:一个传递用户的令牌,另一个服务获得自己的令牌。我使用Feign进行两种方法。
因此对于选项1:订单服务 - >获取帐户服务/帐户/当前
order-service调用帐户服务,该服务根据令牌中的userId返回帐户。然后,订单服务为帐户创建订单。
或者选项2:订单服务 - >获取帐户服务/帐户/用户ID / {userId}
order-service从发送的令牌中获取userId,使用自己的令牌调用account-service,然后使用检索到的帐户创建订单。
我真的不确定哪个选项最好用。一个更好的分离信息,但然后需要两个Feign客户端。然而,另一个不需要2个客户端,并且更容易阻止将某些端点结束到外部客户端,但是它需要创建额外的端点,并且几乎每个服务都需要深入到Authentication对象中。
你有什么想法?有没有人完全以某种方式实现他们的系统?或许我的想法完全错误。
感谢任何帮助。
答案 0 :(得分:1)
我找到了以下3个选项:
如果每个微服务都在验证令牌,那么我们可以传递相同的令牌。但问题是 - 在同一令牌之间可以过期。
如果我们使用client_credentials grant那么我们就有两个问题:一个是,我们需要在下一个微服务中发送用户名/ id。另一个是,我们需要两次请求 - 首先是获取访问令牌,然后是实际呼叫。
如果我们只在API网关中进行令牌验证(不在微服务中),那么从API网关我们需要在每个微服务中发送用户名。并且需要更改微服务实现以接受该参数/标题。
答案 1 :(得分:0)
当您进行服务器到服务器的通信时,您并不是真的代表用户行事,而是代表服务器本身。对于该客户端使用凭据。
使用curl作为示例: curl acme:acmesecret @ localhost:9999 / oauth / token -d grant_type = client_credentials
您应该对您的http客户端执行相同的操作,您将获得访问令牌。用它来打电话给其他服务。
答案 2 :(得分:0)
您应该使用client_credentials流程来使用客户端令牌进行服务间通信。默认情况下,此流在spring security oauth中的/ oauth / token端点上公开。
除此之外,您还可以使用未暴露于互联网的私有api,并使用只能提供给oauth客户端的角色进行保护。这样,您可以公开特权api,这些api可能限制性较小,并且由于您控制传递给它的数据,因此验证次数较少。
在您的示例中,您可以公开公共端点GET account-service/account/current
(无法获取有关您自己的信息)和私有API GET account-service/internal/account/user-id/{userId}
,它们可以由oauth客户端专门用于查询任何现有用户。