讨论基于声明的认证基础以及WIF(Windows Identity Foundation),并且通过一个例子探讨了如何创建自定义身份提供者(IP)和ASP.NET应用程序(RP)。这个ASP.NET应用程序使用身份提供者进行用户认证。现在,将讨论之前文章中讨论的模型所存在的问题。
在最后一个例子中,讨论了使用自定义身份提供者进行认证的简单方法。但事情并不像讨论的那样简单。现在,随着将认证系统外部化并使用身份提供者进行用户认证,可能会出现需要使用多个身份提供者,如Facebook、Google、Windows Live ID等的情况。这看起来可能是这样的:
假设创建了一个应用程序,希望允许用户选择身份提供者。那么流程图可能是这样的:
但在开放的世界中,身份提供者使用不同的协议,有些甚至开发了自己的专有协议,因此RP(Relying Party)必须理解所有这些协议。因此,应用程序需要理解所有这些协议,并且能够验证和读取令牌。为此,需要编写额外的代码来处理所有这些不同的协议。现在的情况可能是这样的:
这不是一个好的解决方案。如果想要为RP添加另一个身份提供者,这意味着需要更改应用程序的代码以适应新的身份提供者。所以这不是一个好的方法,因为需要每次都更改RP代码。
现在让考虑另一个场景。在组织中,有多个应用程序可供用户使用,这些应用程序信任多个身份提供者。现在需要在每个应用程序中编写管道代码来处理所有这些身份提供者。
还有一个场景,如果用户使用的身份提供者不被应用程序信任。但如果有一个身份提供者被应用程序信任,而这个身份提供者又信任另一个身份提供者,这被称为身份联合。
所有上述场景都可以通过身份联合轻松处理,即可以有一个身份提供者(称为联合提供者),它实际上接收(信任)来自各种身份提供者的令牌,然后发出一个应用程序可以理解的通用令牌,即应用程序只信任联合提供者。所有理解各种身份提供者的管道代码都已转移到联合提供者。
这使得生活变得非常容易。现在可以看到所有上述问题都可以轻松处理。那么现在,让讨论流程是如何进行的。
用户访问依赖方应用程序。
由于用户未认证,依赖方应用程序将用户转发到其信任的身份提供者(这里是联合提供者以进行认证)。
现在,联合提供者本身不是身份提供者,它依赖于其他几个身份提供者。因此,它向用户提供了一个身份提供者列表以进行认证。
现在,用户获得了一个受信任的身份提供者列表,并选择了一个身份提供者(其中它拥有账户)并进行认证。一旦认证成功,选定的身份提供者会为用户发出一个令牌并传递给联合提供者。
现在,由于联合提供者信任身份提供者,它可以理解令牌。它首先验证令牌,如果需要的话解密它。它验证并读取传入的令牌,并发出一个新的令牌,使用声明规则(如果有的话)将身份提供者令牌中的声明转换为新令牌。
新令牌(由FP发出)传递给应用程序(依赖方)。
这个令牌被转发给依赖方。由于依赖方信任联合提供者,它可以理解令牌并验证它,一旦验证成功,它允许访问应用程序。
因此,上述过程在幕后进行,用户不需要关心它。用户只需要选择列出的身份提供者之一,选择并输入凭据进行认证。其余的过程在幕后进行。整个过程也称为单点登录。
从上述流程中,了解到,不仅一个依赖方信任身份提供者,而且一个身份提供者也可以信任另一个身份提供者。