微服务架构中的授权/认证
Posted
技术标签:
【中文标题】微服务架构中的授权/认证【英文标题】:Authorization/Authentication in Microservice Architecture 【发布时间】:2020-10-11 03:46:25 【问题描述】:我有:
myApp(服务器 1) 用户身份验证微服务 + 用户数据库(服务器 2)用户身份验证微服务有一个 REST API,我可以通过它管理用户(创建/删除用户、更新用户数据、获取所有用户列表、检查用户密码等)
现在我需要实现授权/认证:
在 user 和 myApp 之间(为此,我将使用常规会话(仅包含会话 ID 的 cookie)并将会话数据存储在 Redis 中) 在 myApp 和用户身份验证微服务之间(为此我假设我需要使用某种 API 密钥/令牌)myApp 应用无法直接访问用户数据库,所有通信仅通过用户身份验证微服务处理。
在过去的一周里,我一直在广泛阅读有关 REST API 中的授权/身份验证的内容,但仍然无法弄清楚 如何为 user -> myApp 和 myApp -> 用户身份验证微服务。
这是我目前想出的。
注册 (Diagram):
-
用户注册后向 myApp 发送用户名/密码/其他数据
myApp 将用户名/密码/其他数据发送到用户身份验证微服务
用户身份验证微服务在用户数据库中创建一个新用户
登录 (Diagram):
-
现在,用户登录,将用户名/密码发送到 myApp
myApp 将用户名/密码发送到验证用户名/密码的用户身份验证微服务
如果用户名和密码正确,User-Authentication Microservice 会生成 API Key(随机字符串)并将其保存到用户数据库,并将此 API Key 与用户记录相关联:
username | password | email | address | APIKEY
---------+----------+-------+---------+-----------
steve | n8Y5e... | ... | ... | D4ED43...
然后用户身份验证微服务将保存的 API 密钥(+有关其所属用户的一些附加信息)返回给 myApp
myApp 创建一个新的会话将其存储在 Redis 中:生成会话 ID 并将会话 ID + API 密钥 + 其他会话数据保存到 Redis:
sessionID: 9w72tv3MHZD...
session_data:
"cookie":
"originalMaxAge": ...,
"expires": ...,
"httpOnly":true,
"path": ...
,
"user":
"authenticated": true,
"username":"steve",
"apiKey": D4ED43C0...,
"created": ...
expire: ...
最后,myApp 服务器发送一个响应,其中包含一个包含会话 ID 的 cookie。
完成,用户已登录。
针对每个后续请求 (Diagram):
-
用户发送一个包含会话 ID 的 cookie
myApp 服务器将会话 ID 与存储在 Redis 中的 ID 进行比较。
如果匹配,myApp 会再次查看会话数据,检索与会话 ID 关联的 API 密钥并将此 API 密钥发送到用户身份验证微服务
用户身份验证微服务通过 API 密钥在用户数据库中查找用户。如果提供的
API key 存在,说明与此 API key 关联的用户通过了身份验证。
用户身份验证微服务通过向 myApp 返回类似
authenticated: true, username: "steve"
的内容来授予访问权限
myApp 使用此响应来授予/限制对页面/应用功能的访问权限
退出 (Diagram)(前 4 个步骤与上面的“针对每个后续请求”中的完全相同):
-
用户发送一个包含会话 ID 的 cookie
myApp 服务器将会话 ID 与存储在 Redis 中的 ID 进行比较。
如果匹配,myApp 会再次查看会话数据,检索与会话 ID 关联的 API 密钥并将此 API 密钥发送到用户身份验证微服务
用户身份验证微服务通过 API 密钥在用户数据库中查找用户。如果提供的 API 密钥存在,则表示与该 API 密钥关联的用户已通过身份验证。
用户身份验证微服务从用户数据库中删除 API 密钥,并以
authenticated: false
之类的内容响应 myApp
myApp 发现用户未通过身份验证,并从 Redis 中删除所有会话数据。
myApp 还会通过将 cookie 设置为过去的过期日期来“删除”cookie,然后用户退出。
问题:我做错了吗?我应该改变什么?我以前从未为 API 构建过身份验证,因此我将不胜感激任何建议。我想了解“大局”。
【问题讨论】:
【参考方案1】:您应该使用基于令牌的身份验证。你的流程应该是这样的:
1- 用户在您的身份验证微服务中注册。
2- 用户将用户名和密码发送到身份验证微服务并接收承载令牌。
3- 用户将收到的承载令牌发送到每个端点 (api),每个微服务都应使用该令牌对用户进行身份验证。
您还可以在 ApiGateway 中配置身份验证。在这种方法中,当用户从身份验证微服务接收承载令牌时,他会调用您的 ApiGateway 以访问特定资源,并且 ApiGateway 对用户进行身份验证并将请求路由到适当的微服务。请注意,在这种方法中,除 ApiGateway 之外的微服务不应具有公共地址。
【讨论】:
以上是关于微服务架构中的授权/认证的主要内容,如果未能解决你的问题,请参考以下文章