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 触发认证处理程序

您可以通过(或使用MVCChallengeResultHttpContext上的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 =>
{
// ...
});
}

github地址

第22章 使用外部身份提供商登录 - Identity Server 4 中文文档(v1.0.0)的更多相关文章

  1. 第21章 登录 - Identity Server 4 中文文档(v1.0.0)

    为了使IdentityServer能够代表用户发出令牌,该用户必须登录IdentityServer. 21.1 Cookie身份验证 使用由ASP.NET Core中的cookie身份验证处理程序管理 ...

  2. 第53章 结束会话端点(End Session Endpoint) - Identity Server 4 中文文档(v1.0.0)

    结束会话端点可用于触发单点注销(请参阅规范). 要使用结束会话端点,客户端应用程序会将用户的浏览器重定向到结束会话URL.用户在会话期间通过浏览器登录的所有应用程序都可以参与注销. 注意 终端会话端点 ...

  3. 第50章 设备授权端点(Device Authorization Endpoint) - Identity Server 4 中文文档(v1.0.0)

    设备授权端点可用于请求设备和用户代码.此端点用于启动设备流授权过程. 注意 终端会话端点的URL可通过发现端点获得. client_id 客户标识符(必填) client_secret 客户端密钥可以 ...

  4. 第25章 退出外部身份提供商 - Identity Server 4 中文文档(v1.0.0)

    当用户注销 IdentityServer并且他们使用外部身份提供程序登录时,可能会将其重定向到注销外部提供程序.并非所有外部提供商都支持注销,因为它取决于它们支持的协议和功能. 要检测是否必须将用户重 ...

  5. 第59章 IdentityServer交互服务 - Identity Server 4 中文文档(v1.0.0)

    IIdentityServerInteractionService接口旨在提供用户界面用于与IdentityServer通信的服务,主要与用户交互有关.它可以从依赖注入系统获得,通常作为构造函数参数注 ...

  6. 第27章 联合网关 - Identity Server 4 中文文档(v1.0.0)

    通用架构是所谓的联合网关.在此方法中,IdentityServer充当一个或多个外部身份提供商的网关. 该架构具有以下优点: 您的应用程序只需要了解一个令牌服务(网关),并且屏蔽了有关连接到外部提供程 ...

  7. 第26章 联合注销 - Identity Server 4 中文文档(v1.0.0)

    联合注销是指用户使用外部身份提供程序登录IdentityServer,然后用户通过IdentityServer未知的工作流程注销该外部身份提供程序的情况.当用户注销时,对IdentityServer进 ...

  8. 第65章 博客帖子 - Identity Server 4 中文文档(v1.0.0)

    第65章 博客帖子 65.1 团队帖子 65.1.1 2019 IdentityServer中的范围和声明设计 尝试使用IdentityServer4的设备流程 OAuth2中隐含流的状态 另一种保护 ...

  9. 第2章 术语 - Identity Server 4 中文文档(v1.0.0)

    规范.文档和对象模型等都使用特定的术语来表述. 2.1 IdentityServer IdentityServer是OpenID Connect提供程序 - 它实现OpenID Connect和OAu ...

随机推荐

  1. centos7.5安装python3.7

    系统状态 CentOS Linux release 7.5.1804 (Core) mini版安装系统 Python-3.7.0.tgz 官方下载源码包 安装系统依赖包 # 编译必备 yum inst ...

  2. 多路分支----switch语句

    switch-case与if-else有相似的作用,都是表达分支的方式. 语法形式: switch(type){ case 常量1: do something; break; case 常量2: do ...

  3. python中的单向链表实现

    引子 数据结构指的是是数据的组织的方式.从单个数据到一维结构(线性表),二维结构(树),三维结构(图),都是组织数据的不同方式. 为什么需要链表? 顺序表的构建需要预先知道数据大小来申请连续的存储空间 ...

  4. Linux shell编程 -test

    test 命令的格式非常简单 test condition condition 是test命令要测试的一系列参数和值.当用在if-then 语句中时,test 命令看起来是这样的 if test co ...

  5. Ubuntu上安装使用WeChat、TIM

    WeChat可以直接到软件商店安装,不过是网页版...(其实个人感觉还行,就是什么都不能设置就挺蛋疼的,字体大小.背景什么的) 以下是网上找到的教程,在此总结一下: 下载地址:https://gith ...

  6. c# 钩子类

    using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using S ...

  7. TCP与UDP区别总结

    TCP与UDP区别总结:1.TCP面向连接(如打电话要先拨号建立连接);UDP是无连接的,即发送数据之前不需要建立连接2.TCP提供可靠的服务.也就是说,通过TCP连接传送的数据,无差错,不丢失,不重 ...

  8. Linux安装Gradle

    Linux安装Gradle   Gradle 是以 Groovy 语言为基础,面向Java应用为主.基于DSL(领域特定语言)语法的自动化构建工具.在github上,gradle项目很多,有的是gra ...

  9. 【逆元】HDU-1576

    逆元: 同余方程 ax≡1(mod n),gcd(a,n) = 1 时有解,这时称求出的 x 为 a 的对模n的乘法逆元.(注意:如果gcd(a,n)如果不等于1则无解),解法还是利用扩展欧几里得算法 ...

  10. ansible基础-理解篇

    1. 介绍 要说现在的部署工具,ansible可以说家喻户晓了. ansible是一个开源软件,用于软件供应.配置管理.应用部署.ansible可以通过SSH.remote PowerShell.其他 ...