微服务认证

25

上下文

我有多个服务,例如:

  • 用户(LDAP或Active Directory等)
  • 计费
  • 规划
  • 等等...
  • 身份验证

我需要使用OAuth2.0连接到我的微服务,对于初始阶段,使用标准的登录/密码(我使用自己的数据,而不是使用第三方服务器)。

问题

根据这些图片:

步骤1

输入图像描述

步骤2

输入图像描述

我如何处理access_token控制或授权控制,以在authmicroservice之外的其他服务中使用?


https://dev.to/s2agrahari/authentication-between-microservices-part-i-3dpp - Suraj
5个回答

12
为了在微服务架构中管理身份验证,您必须有一种不同的视角。
还记得当你在单体应用上工作时,你只有一个身份验证过程。
例如,在PHP应用程序中,您在数据库中查找用户及其相应的凭据,然后创建会话以使用户“已认证”。
对于微服务,工作流程基本相同。现在唯一改变的是您不能在不同服务中打开会话。此外,您不需要获取已经认证的用户。您只需要确保他被授权执行当前调用您的微服务。
由于oauth2,拥有有效的access_token可以为您提供此信息。
这应该回答了前端部分。在后端部分(我指api网关后面),您不应该管理access_token,因为它与微服务无关。您可以使用功能密钥在微服务内查找与用户相关的任何信息,例如uuid。
为了在使用oauth2时获取uuid,建议同时使用openid connect。它是用于管理特定用户信息的协议,并为您提供访问特定端点“/userinfo”的权限。
希望这个模式能让这个答案更清晰。
参考示意图: enter image description here

https://dev.to/s2agrahari/authentication-between-microservices-part-i-3dpp - Suraj

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

inlined image

从技术角度来看,它可能只是处理请求头以验证提供的令牌作为oauth身份验证的代码部分(函数),这可能在代码内部处理或通过访问自己的数据库进行处理,然后将请求转发到服务端点。
您可以通过增强的API网关服务或服务来遵循一种方法来提供身份验证、安全性和请求分派到端点。已经在stackoverflow上提出了一个问题here,但我发现易于理解的是你会在这里找到三四个系列的教程here
在专注于微服务之前,清楚地了解您的API网关使用情况。

0

我们的激活器中有一个微服务认证流程的教程和描述,它是用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 - mfrachet
1
让我们将授权与认证分开。认证服务为“前端”“用户”提供一种方式来表明“是的,这是我,这是我的会话”。授权告诉用户X可以做什么或不能做什么。虽然认证由auth服务/oauth等完成,但授权可以与更深入和复杂的业务规则相连接。假设网关检查auth-token是否有效,并使用X-UserId HTTP标头调用包装服务。现在,这些服务需要自己检查具有给定ID的用户是否可以执行某些操作。例如,如果UserId == project.ownerId,则project.save()。 - Jacek Głodek
代理可以是一个NGINX,它有一些脚本来访问Redis并检查令牌是否在redis中,并将Redis中令牌的值作为标头传递给包装服务。或者它可以是一个常规的微服务。如果领域足够复杂,这可以按需分层。 - Jacek Głodek
你的意思是你有一个分布式的 Redis 存储,每个微服务都可以访问吗? - Luc
是的,请查看 https://github.com/twitter/twemproxy(编辑:太棒了)以分发 Redis。 - Jacek Głodek

0

0

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

由于您已经拥有一个身份验证服务,因此您可以在账单服务中使用它来在处理请求之前检查请求的真实性。

例如,如果您正在使用像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在同一区域内加载了几个服务,你可以像调用函数一样访问它们,从而解决了这个问题(至少在我们目前看到的情况下)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接