微服务架构中的授权/认证

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 之外的微服务不应具有公共地址。

【讨论】:

以上是关于微服务架构中的授权/认证的主要内容,如果未能解决你的问题,请参考以下文章

权限设计系列「认证授权专题」微服务架构的登陆认证问题

微服务架构中的 SPA 认证

#私藏项目实操分享#权限设计系列「认证授权专题」微服务架构的登陆认证问题

使用微服务架构思想,设计部署OAuth2.0授权认证框架

微服务架构认证鉴权方案

认证鉴权与API权限控制在微服务架构中的设计与实现