如何实现多个IdentityServer

3
我们正在构建一个多租户应用程序,将在全球多个数据中心(Azure)进行托管。此应用程序还将公开API(不仅是MVC Web应用程序)。
为处理身份验证/授权问题,我们计划实施Owin OAuth,但后来我们发现“Thinktecture IdentityServer3”非常适合我们的要求。
另外,如果租户在任何区域实例(例如'NA1.ourwebsite.com')中拥有账户,则他不仅应该能够通过'NA1.ourwebsite.com'登录,而且还应该能够通过集中式实例/身份服务器'ourwebsite.com'登录。
NA1.ourwebsite.com - 北美实例
EA1.ourwebsite.com - 东亚实例
目前,我们每个租户都有不同的数据库,并且其用户信息也存在于其各自的数据库中。
我不确定一个应用程序如何拥有多个身份服务器(我不知道是否必须选择联合服务器)。
SalesForce.com正是这样做的,但我不知道如何操作。有人可以帮助我吗?
提前致谢。
1个回答

7
为了处理身份验证/授权,我们原本计划实施Owin OAuth,但后来发现'Thinktecture IdentityServer3'更适合我们的需求。确实如此。'Thinktecture IdentityServer3'是OpenID Connect的一种实现,而OpenID Connect是OAuth加上“身份层”的组合。您仍然可以使用OAuth进行授权(访问受保护的资源),因为OpenID提供者通常会返回一个访问令牌(access_token)。它还返回一个id_token以进行身份验证(身份确认)。
如果租户在任何区域实例(例如'NA1.ourwebsite.com')中拥有帐户,则不仅应该能够通过'NA1.ourwebsite.com'登录,而且还应该能够通过集中式实例/身份服务器'ourwebsite.com'登录。这是OpenID Connect可以实现的用例。您将能够给最终用户选择是否使用NA1.ourwebsite.com、ourwebsite.com或任何其他OpenID Connect提供程序登录。例如,我能够使用多个提供程序登录同一StackExchange帐户。

My stackExchange logins include StackExchange, Google, and Microsoft.

当然,最终用户需要将每个OpenID Connect身份与您的应用程序中的账户关联起来。有时,您的应用程序可以根据OpenID Connect声明(例如电子邮件)自动确定此关联,而其他情况下,最终用户必须手动关联登录信息。例如。

Logging in with a new account to StackExchange.

目前,我们为每个租户拥有不同的数据库,并且他们的用户信息也存储在各自的数据库中。
未来有很多方法可以采取。您需要区分仅适用于您的应用程序的用户信息和适用于身份验证的用户信息。您不能合理地期望所有OpenID Connect提供者存储您的应用程序所需的所有用户信息。关于用户信息,它只能验证您的用户身份并提供您的用户已经在提供者中存储的个人资料信息(例如,Twitter账户中的内容)。
我不确定一个应用程序如何拥有多个身份服务器(是否必须选择联合服务器)。
这有点像一个机场接受多种身份证件的方式:出生证明、电费单、护照、驾驶证。虽然很难理解,但一旦您了解了id_token就像是可信身份证件的一部分,您就可以开始欣赏它了。真实的例子是出生证明。在这种情况下,政府是身份提供者,而出生证明就是id_token。应用程序可以选择接受哪些身份提供者。
SalesForce.com 也能实现同样的功能,但我不知道具体如何操作。有人可以帮我吗?
除了 salesforce.com,如上所述,stackexchange.com 也能实现此功能。OpenID Connect 规范中的图表会对此有所帮助。
+--------+                                   +--------+
|        |                                   |        |
|        |---------(1) AuthN Request-------->|        |
|        |                                   |        |
|        |  +--------+                       |        |
|        |  |        |                       |        |
|        |  |  End-  |<--(2) AuthN & AuthZ-->|        |
|        |  |  User  |                       |        |
|   RP   |  |        |                       |   OP   |
|        |  +--------+                       |        |
|        |                                   |        |
|        |<--------(3) AuthN Response--------|        |
|        |                                   |        |
|        |---------(4) UserInfo Request----->|        |
|        |                                   |        |
|        |<--------(5) UserInfo Response-----|        |
|        |                                   |        |
+--------+                                   +--------+
  1. RP(客户端)向OpenID提供程序(OP)发送请求。
  2. OP对终端用户进行身份验证并获得授权。
  3. OP响应带有ID令牌和通常是访问令牌的请求。
  4. RP可以使用访问令牌向UserInfo端点发送请求。
  5. UserInfo端点返回有关终端用户的声明。

OP是OpenID Connect提供商。我认为这就是您所说的“身份服务器”。您可以接受来自应用程序决定信任的任何提供程序的令牌。终端用户在登录时可以选择要使用哪个提供程序(通常会看到选择使用Twitter,Facebook,Google,Microsoft等登录)。其中一个选项可能是ourwebsite.com。

RP是依赖方,这种情况下是您的应用程序。它被称为依赖方,因为它依赖各种OP进行身份验证、授权和某些用户配置文件存储。

步骤(1)到(3)几乎与OAuth授权流程完全相同,其中最终用户登录所选择的提供程序,提供程序响应令牌。 OpenID Connect的区别在于,在第(3)步中,响应通常除了access_token之外还包含一个id_tokenaccess_token代表最终用户的授权。它是OAuth beaker令牌。您的应用程序将其包括在请求受保护的资源时。这些受保护的资源可能包括存储在OpenID Connect提供程序中的用户信息。请参见步骤(4)和(5)。 id_token 表示终端用户的 认证,包含有关终端用户和 Open ID Connect 提供程序的声明。 iss 声明标识 OpenID 提供者,sub 声明唯一标识终端用户,aud 声明标识 Relying Party(您的应用程序)。其他标准声明包括经过身份验证的终端用户的 namegiven_namefamily_namemiddle_namepicturewebsiteemailphone_number
对于授权而言,最重要的是 subiss,因为这两者的组合唯一地标识了登录。
OpenID Connect 很复杂,需要一些时间来完全理解。您的坚持将会得到回报,因为它完美地匹配了您的用例。 Thinktecture IdentityServer3 看起来是一个可靠的选择。另一个类似的选择是 AspNet.Security.OpenIdConnect.Server

参考资料

OpenID Connect in a nutshell。这篇文章由OpenID Connect的作者之一撰写,包含两个特别有帮助的部分:“发出OpenID Connect请求”和“接收OpenID Connect响应”。

OpenID Connect Core 1.0 incorporating errata set 1。其中一个规范文档,包含在本答案中发布的有用图表。

The OAuth 2.0 Authorization Framework: Bearer Token Usage。OAuth RFC,解释如何在请求受保护资源时使用access_token


1
感谢Shaun提供的信息。但是这是否解决了我的问题(我在上面描述过)?除此之外,你能否提供一些关于“它与IdentityServer3有何不同”的详细信息? - Pragmatic
1
如果您有时间的话,帮我解决这个用例会非常棒。祝你周末愉快 :) - Pragmatic
1
嗨,肖恩,感谢提供的信息。我们已经决定使用IdentityServer 3。你能帮我解决以下问题吗?我们正在构建的应用程序有自己的用户基础。我的单页应用程序是这些资源的主要应用程序(或者说是所有者应用程序)。因此,我认为,如果用户进入我的SPA,它不应该使用OAuth/Open connect。OAuth/Open connect是为其他应用程序(这些应用程序不是这些资源的所有者应用程序)而设计的。我猜这就是Google的工作方式。当您登录到Gmail时,它从不使用OAuth,但在您在Stackoverflow中使用它时,它会使用OAuth。 - Pragmatic
1
Shaun,你真的建议我在我的主要应用程序中使用OAuth/Open Connect吗?我不认为Google是这样工作的。所有谷歌的应用程序(Gmail、地图等)似乎都是以不同的方式工作,并在它们之间共享cookie。但是当我们在stackoverflow上使用谷歌凭据时,他们才会使用OAuth。 - Pragmatic
1
进一步澄清,这个主要的应用程序是用来创建用户数据库的应用程序(添加/删除用户、创建/更新密码策略和所有其他资源管理)。我认为,其他应用程序应该请求id_token和access_token才能访问这些资源。 - Pragmatic
显示剩余6条评论

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