第22章 使用外部身份提供商登录 - Identity Server 4 中文文档(v1.0.0)
ASP.NET Core有一种灵活的方式来处理外部身份验证。这涉及几个步骤。
注意
如果您使用的是ASP.NET Identity,则会隐藏许多基础技术细节。建议您还阅读Microsoft 文档并执行ASP.NET Identity 快速入门。
22.1 为外部提供者添加身份验证处理程序
与外部提供者通信所需的协议实现封装在身份验证处理程序中。一些提供商使用专有协议(例如Facebook等社交提供商),有些提供商使用标准协议,例如OpenID Connect,WS-Federation或SAML2p。
有关添加外部身份验证和配置它的分步说明,请参阅此快速入门。
22.2 cookies的作用
调用外部身份验证处理程序的一个选项SignInScheme,例如:
services.AddAuthentication()
.AddGoogle("Google", options =>
{
options.SignInScheme = "scheme of cookie handler to use";
options.ClientId = "...";
options.ClientSecret = "...";
})
登录方案指定将临时存储外部认证结果的cookie处理程序的名称,例如由外部提供者发送的声明。这是必要的,因为在完成外部身份验证过程之前通常会涉及一些重定向。
鉴于这是一种常见做法,IdentityServer专门为此外部提供程序工作流注册cookie处理程序。该方案通过IdentityServerConstants.ExternalCookieAuthenticationScheme常数表示。如果您要使用我们的外部cookie处理程序,那么对于SignInScheme上面的内容,您将赋值为IdentityServerConstants.ExternalCookieAuthenticationScheme常量:
services.AddAuthentication()
.AddGoogle("Google", options =>
{
options.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme;
options.ClientId = "...";
options.ClientSecret = "...";
})
您也可以注册自己的自定义cookie处理程序,如下所示:
services.AddAuthentication()
.AddCookie("YourCustomScheme")
.AddGoogle("Google", options =>
{
options.SignInScheme = "YourCustomScheme";
options.ClientId = "...";
options.ClientSecret = "...";
})
注意
对于特殊情况,您还可以将外部cookie机制短路并将外部用户直接转发到主cookie处理程序。这通常涉及处理外部处理程序上的事件,以确保您从外部标识源执行正确的声明转换。
22.3 触发认证处理程序
您可以通过(或使用MVCChallengeResult )HttpContext上的ChallengeAsync扩展方法调用外部认证处理程序。
您通常希望将一些选项传递给挑战操作,例如回调页面的路径和簿记提供者的名称,例如:
var callbackUrl = Url.Action("ExternalLoginCallback");
var props = new AuthenticationProperties
{
RedirectUri = callbackUrl,
Items =
{
{ "scheme", provider },
{ "returnUrl", returnUrl }
}
};
return Challenge(provider, props);
22.4 处理回调并签署用户
在回调页面上,您的典型任务是:
- 检查外部提供商返回的身份。
- 决定如何处理该用户。如果这是新用户或返回用户,则可能会有所不同。
- 新用户在被允许之前可能需要额外的步骤和UI。
- 可能会创建一个链接到外部提供程序的新内部用户帐户。
- 存储您要保留的外部声明。
- 删除临时cookie
- 登录用户
22.4.1 检查外部身份:
// read external identity from the temporary cookie
var result = await HttpContext.AuthenticateAsync(IdentityServerConstants.ExternalCookieAuthenticationScheme);
if (result?.Succeeded != true)
{
throw new Exception("External authentication error");
}
// retrieve claims of the external user
var externalUser = result.Principal;
if (externalUser == null)
{
throw new Exception("External authentication error");
}
// retrieve claims of the external user
var claims = externalUser.Claims.ToList();
// try to determine the unique id of the external user - the most common claim type for that are the sub claim and the NameIdentifier
// depending on the external provider, some other claim type might be used
var userIdClaim = claims.FirstOrDefault(x => x.Type == JwtClaimTypes.Subject);
if (userIdClaim == null)
{
userIdClaim = claims.FirstOrDefault(x => x.Type == ClaimTypes.NameIdentifier);
}
if (userIdClaim == null)
{
throw new Exception("Unknown userid");
}
var externalUserId = userIdClaim.Value;
var externalProvider = userIdClaim.Issuer;
// use externalProvider and externalUserId to find your user, or provision a new user
22.4.2 清理和登录:
// issue authentication cookie for user
await HttpContext.SignInAsync(user.SubjectId, user.Username, provider, props, additionalClaims.ToArray());
// delete temporary cookie used during external authentication
await HttpContext.SignOutAsync(IdentityServerConstants.ExternalCookieAuthenticationScheme);
// validate return URL and redirect back to authorization endpoint or a local page
if (_interaction.IsValidReturnUrl(returnUrl) || Url.IsLocalUrl(returnUrl))
{
return Redirect(returnUrl);
}
return Redirect("~/");
22.5 状态,URL长度和ISecureDataFormat
重定向到外部提供程序进行登录时,必须经常从客户端应用程序进行往返状态。这意味着在离开客户端之前捕获状态并保留状态,直到用户返回到客户端应用程序。许多协议(包括OpenID Connect)允许将某种状态作为参数传递作为请求的一部分,并且身份提供者将在响应上返回该状态。ASP.NET Core提供的OpenID Connect身份验证处理程序利用协议的这一功能,即它实现上述returnUrl功能的方式。
在请求参数中存储状态的问题是请求URL可能变得太大(超过2000个字符的公共限制)。OpenID Connect身份验证处理程序确实提供了一个可扩展点,用于在服务器中而不是在请求URL中存储状态。您可以通过ISecureDataFormat<AuthenticationProperties>在OpenIdConnectOptions上实现和配置它来自行实现。
幸运的是,IdentityServer为您提供了一个实现,由IDistributedCache DI容器中注册的实现(例如标准MemoryDistributedCache)支持。要使用IdentityServer提供的安全数据格式实现,只需在配置DI时调用IServiceCollection扩展AddOidcStateDataFormatterCache方法。如果未传递任何参数,则配置的所有OpenID Connect处理程序将使用IdentityServer提供的安全数据格式实现:
public void ConfigureServices(IServiceCollection services)
{
// configures the OpenIdConnect handlers to persist the state parameter into the server-side IDistributedCache.
services.AddOidcStateDataFormatterCache();
services.AddAuthentication()
.AddOpenIdConnect("demoidsrv", "IdentityServer", options =>
{
// ...
})
.AddOpenIdConnect("aad", "Azure AD", options =>
{
// ...
})
.AddOpenIdConnect("adfs", "ADFS", options =>
{
// ...
});
}
如果只配置特定方案,则将这些方案作为参数传递:
public void ConfigureServices(IServiceCollection services)
{
// configures the OpenIdConnect handlers to persist the state parameter into the server-side IDistributedCache.
services.AddOidcStateDataFormatterCache("aad", "demoidsrv");
services.AddAuthentication()
.AddOpenIdConnect("demoidsrv", "IdentityServer", options =>
{
// ...
})
.AddOpenIdConnect("aad", "Azure AD", options =>
{
// ...
})
.AddOpenIdConnect("adfs", "ADFS", options =>
{
// ...
});
}
第22章 使用外部身份提供商登录 - Identity Server 4 中文文档(v1.0.0)的更多相关文章
- 第21章 登录 - Identity Server 4 中文文档(v1.0.0)
为了使IdentityServer能够代表用户发出令牌,该用户必须登录IdentityServer. 21.1 Cookie身份验证 使用由ASP.NET Core中的cookie身份验证处理程序管理 ...
- 第53章 结束会话端点(End Session Endpoint) - Identity Server 4 中文文档(v1.0.0)
结束会话端点可用于触发单点注销(请参阅规范). 要使用结束会话端点,客户端应用程序会将用户的浏览器重定向到结束会话URL.用户在会话期间通过浏览器登录的所有应用程序都可以参与注销. 注意 终端会话端点 ...
- 第50章 设备授权端点(Device Authorization Endpoint) - Identity Server 4 中文文档(v1.0.0)
设备授权端点可用于请求设备和用户代码.此端点用于启动设备流授权过程. 注意 终端会话端点的URL可通过发现端点获得. client_id 客户标识符(必填) client_secret 客户端密钥可以 ...
- 第25章 退出外部身份提供商 - Identity Server 4 中文文档(v1.0.0)
当用户注销 IdentityServer并且他们使用外部身份提供程序登录时,可能会将其重定向到注销外部提供程序.并非所有外部提供商都支持注销,因为它取决于它们支持的协议和功能. 要检测是否必须将用户重 ...
- 第59章 IdentityServer交互服务 - Identity Server 4 中文文档(v1.0.0)
IIdentityServerInteractionService接口旨在提供用户界面用于与IdentityServer通信的服务,主要与用户交互有关.它可以从依赖注入系统获得,通常作为构造函数参数注 ...
- 第27章 联合网关 - Identity Server 4 中文文档(v1.0.0)
通用架构是所谓的联合网关.在此方法中,IdentityServer充当一个或多个外部身份提供商的网关. 该架构具有以下优点: 您的应用程序只需要了解一个令牌服务(网关),并且屏蔽了有关连接到外部提供程 ...
- 第26章 联合注销 - Identity Server 4 中文文档(v1.0.0)
联合注销是指用户使用外部身份提供程序登录IdentityServer,然后用户通过IdentityServer未知的工作流程注销该外部身份提供程序的情况.当用户注销时,对IdentityServer进 ...
- 第65章 博客帖子 - Identity Server 4 中文文档(v1.0.0)
第65章 博客帖子 65.1 团队帖子 65.1.1 2019 IdentityServer中的范围和声明设计 尝试使用IdentityServer4的设备流程 OAuth2中隐含流的状态 另一种保护 ...
- 第2章 术语 - Identity Server 4 中文文档(v1.0.0)
规范.文档和对象模型等都使用特定的术语来表述. 2.1 IdentityServer IdentityServer是OpenID Connect提供程序 - 它实现OpenID Connect和OAu ...
随机推荐
- centos7.5安装python3.7
系统状态 CentOS Linux release 7.5.1804 (Core) mini版安装系统 Python-3.7.0.tgz 官方下载源码包 安装系统依赖包 # 编译必备 yum inst ...
- 多路分支----switch语句
switch-case与if-else有相似的作用,都是表达分支的方式. 语法形式: switch(type){ case 常量1: do something; break; case 常量2: do ...
- python中的单向链表实现
引子 数据结构指的是是数据的组织的方式.从单个数据到一维结构(线性表),二维结构(树),三维结构(图),都是组织数据的不同方式. 为什么需要链表? 顺序表的构建需要预先知道数据大小来申请连续的存储空间 ...
- Linux shell编程 -test
test 命令的格式非常简单 test condition condition 是test命令要测试的一系列参数和值.当用在if-then 语句中时,test 命令看起来是这样的 if test co ...
- Ubuntu上安装使用WeChat、TIM
WeChat可以直接到软件商店安装,不过是网页版...(其实个人感觉还行,就是什么都不能设置就挺蛋疼的,字体大小.背景什么的) 以下是网上找到的教程,在此总结一下: 下载地址:https://gith ...
- c# 钩子类
using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using S ...
- TCP与UDP区别总结
TCP与UDP区别总结:1.TCP面向连接(如打电话要先拨号建立连接);UDP是无连接的,即发送数据之前不需要建立连接2.TCP提供可靠的服务.也就是说,通过TCP连接传送的数据,无差错,不丢失,不重 ...
- Linux安装Gradle
Linux安装Gradle Gradle 是以 Groovy 语言为基础,面向Java应用为主.基于DSL(领域特定语言)语法的自动化构建工具.在github上,gradle项目很多,有的是gra ...
- 【逆元】HDU-1576
逆元: 同余方程 ax≡1(mod n),gcd(a,n) = 1 时有解,这时称求出的 x 为 a 的对模n的乘法逆元.(注意:如果gcd(a,n)如果不等于1则无解),解法还是利用扩展欧几里得算法 ...
- ansible基础-理解篇
1. 介绍 要说现在的部署工具,ansible可以说家喻户晓了. ansible是一个开源软件,用于软件供应.配置管理.应用部署.ansible可以通过SSH.remote PowerShell.其他 ...