【问题标题】:Microservices authentication微服务认证
【发布时间】:2015-09-11 16:59:06
【问题描述】:

上下文

我有多种服务,例如:

  • 用户(LDAP 或活动目录等...)
  • 计费
  • 规划
  • 等等……
  • 身份验证

我需要使用 OAuth2.0 连接我的微服务,首先,使用标准登录名/密码(我使用我自己的数据,而不是连接第三方服务器)

问题

根据这些图片:

第一步

第 2 步

除了 authmicroservice 之外,我如何处理 access_token 控制或授权控制?

【问题讨论】:

标签: rest microservices


【解决方案1】:

在我们的激活器中有一个关于微服务中身份验证流程的教程和描述,它在 Scala 中 — http://www.typesafe.com/activator/template/reactive-microservices(来源:https://github.com/theiterators/reactive-microservices


基本思想是:您需要为每个请求验证身份验证令牌的真实性。 您可以:

——在代理(网关)中进行

——在计费微服务中进行


我们倾向于做的是:在每个面向客户端的微服务中验证 Auth-Token。

——我们将 Auth-Token 保存在 Redis 实例中的用户信息中。

——面向客户端的服务询问 redis 实例此令牌是否有效

——Redis 返回一些 JSON 字符串,我们可以将其用作用户数据以进行进一步授权。

所以服务器端流程是这样的

get("projects/" / Segment) { projectName =>
  getHeader("Auth-Token") { authToken =>
    Redis.get("auth:token:#{authToken}").map { userJson =>
      if(userJson("projects").include(projectName)) {
        ...processSth...
        Ok
      } else {
        Unauthorized
      }
    }
  }
}

【讨论】:

  • 感谢您的回复。我真正感兴趣的帖子部分是第二部分,当您告诉“您可以在网关或每个服务中执行此操作”时。你能详细说明一下广告和缺点吗? :- D
  • => 让我们将授权与身份验证分开。身份验证服务为“前端”“用户”提供了一种说“是的,是我,这是我的会话”的方式。授权告诉用户 X 可以做某事或不能做某事。虽然通过auth service/oauth等方式进行认证,但授权可以与更深更复杂的业务规则联系起来。假设网关检查 auth-token 是否有效,并使用 X-UserId HTTP 标头调用包装服务。现在这些服务需要自己检查具有给定 id 的用户是否可以做某事。前任。 if UserId == project.ownerId project.save()
  • 所以代理可以是一个 NGINX,它有一些脚本来访问 Redis 并检查令牌是否在 redis 中,并将令牌的值从 Redis 的标头中传递给包装的服务。或者它可以是一个常规的微服务。给定足够复杂的域,这可以根据需要分层。
  • 你的意思是你有一个分布式redis存储,每个微服务都可以访问?
  • 是的,看看github.com/twitter/twemproxy(编辑:真棒)分发redis
【解决方案2】:

可以创建单独的身份验证服务来提供 access_token,就像您在步骤 1 中展示的那样。但是在 API Gateway 中,每个服务都需要调用该身份验证服务来验证令牌。最好在我的产品中使用的 API 网关中应用 oauth 过程,并且在许多文章中也解释了这种方法。让我们看看下面的图片。

从技术角度来看,它可以只是处理请求标头的代码(函数)的一部分,以验证作为 oauth 身份验证提供的令牌,这可以在代码中处理或通过在将请求转发到服务端点之前访问自己的数据库来处理。

您可以按照一种方法通过增强型 API 网关的服务向端点提供身份验证、安全性和请求分派。 stackoverflow here 已经有问题了,但我发现很容易理解的是 3 或 4 个系列教程,你会发现 here

在您专注于要处理的微服务之前,清楚地了解您的 API Gateway 使用情况。

【讨论】:

    【解决方案3】:

    根据您构建微服务的方式,您还可以利用组合。

    由于您已经有一个身份验证服务,您可以在您的计费服务中使用它来检查请求的真实性,然后再处理它。

    例如,如果您使用像 StdLib 这样的平台(我们在内部使用):

    // Billing
    const lib = require('lib');
    
    module.exports = function(params, callback) {
      lib.user.isAuthenticated(params, function(err, user) {
        if (err) return callback(err);
        // Do stuff with user, process billing
      });
    };
    

    如果您总是使用 HTTP 在函数之间进行通信,这对您来说可能不是一个好主意(因为这可能会给您的请求增加 200-300 毫秒的时间)。但是 StdLib 在同一区域内加载了一些服务,您可以像访问解决该问题的函数一样访问它们(至少,到目前为止,我们已经看到了)。

    【讨论】:

      【解决方案4】:

      为了在微服务架构中管理身份验证,您必须有不同的观点。

      请记住,当您在单体应用上工作时,您只有一个身份验证过程。

      作为 PHP 应用程序中的示例,您在具有相应凭据的数据库中找到您的用户,然后您创建了一个会话,该用户已“经过身份验证”。

      使用微服务,工作流程是一样的。现在唯一改变的是您无法在不同的服务中打开会话。此外,您不需要获取经过身份验证的用户。您只需要确保他有权在您的微服务上执行当前调用。

      感谢 oauth2,拥有有效的 access_token 可为您提供此信息。

      这应该回答前端部分。在后端部分(我的意思是在 api 网关后面),您不应该管理 access_token,因为它与微服务无关。您可以使用功能键在微服务中查找与用户相关的任何信息,例如 uuid。

      为了在使用 oauth2 时获得 uuid,我建议也使用 openid connect。使用此协议管理特定用户信息的是用户,它使您可以访问特定端点“/userinfo”。

      希望这个架构能让这个答案更清楚。

      【讨论】:

      猜你喜欢
      • 2020-12-14
      • 2019-01-03
      • 2019-05-27
      • 2019-01-07
      • 2015-06-21
      • 2019-07-29
      • 2016-07-17
      • 2015-07-24
      • 2018-01-06
      相关资源
      最近更新 更多