ASP.NET Core中提供了多种身份证认证模式,几种常见的身份认证模式有以下几种。本文将详细介绍一下OpenID Connect身份认证在ASP.NET Core中如何使用(三方以Gitee为例)。
| 认证模式 |
介绍 |
| Cookie |
最常见的身份认证方式之一。用户登录成功后,服务器会生成一个加密的 Cookie 并发送给客户端,客户端在后续请求中携带该 Cookie 来验证用户身份。 |
| JWT |
JSON Web Token)是一种基于 JSON 的开放标准(RFC 7519),用于在网络上安全地传输声明。JWT 认证通过在客户端和服务器之间传递加密的 Token 来验证用户身份。 |
| OAuth |
一种开放标准,用于授权第三方应用程序访问用户数据。ASP.NET Core 提供了 OAuth 认证机制,允许应用程序通过 OAuth 协议与第三方身份提供者进行集成。 |
| OpenID Connect |
建立在 OAuth 2.0 协议之上的身份认证协议,用于验证用户身份。ASP.NET Core 提供了对 OpenID Connect 的支持,可以与支持 OpenID Connect 的身份提供者集成。 |
| Windows |
ASP.NET Core 支持 Windows 身份认证,允许用户使用他们的 Windows 凭据登录到应用程序。 |
OpenID Connect
OpenID Connect(ODIC)是基于OAuth2.0之上的扩展,在OAuth2.0之上新增了身份验证的功能。
ODIC的应用场景通常如下:

ODIC由一个必选的核心规范以及多个可选的扩展规范组成,通常会支持以下规范:
- Core:必选。定义OIDC的核心功能,在OAuth 2.0之上构建身份认证,以及如何使用Claims来传递用户的信息。
- Discovery:可选。发现服务,使客户端可以动态的获取OIDC服务相关的元数据描述信息(比如支持那些规范,接口地址是什么等等)。
- Dynamic Registration:可选。动态注册服务,使客户端可以动态的注册到OIDC的OP(这个缩写后面会解释)。
- OAuth 2.0 Multiple Response Types:可选。针对OAuth2的扩展,提供几个新的response_type。
- OAuth 2.0 Form Post Response Mode:可选。针对OAuth2的扩展,OAuth2回传信息给客户端是通过URL的querystring和fragment这两种方式,这个扩展标准提供了一基于form表单的形式把数据post给客户端的机制。
- Session Management:可选。Session管理,用于规范OIDC服务如何管理Session信息。
- Front-Channel Logout:可选。基于前端的注销机制,使得RP(这个缩写后面会解释)可以不使用OP的iframe来退出。
- Back-Channel Logout:可选。基于后端的注销机制,定义了RP和OP直接如何通信来完成注销。
官方OIDC组成结构图如下:

- EU:End User:一个人类用户。
- RP:Relying Party ,用来代指OAuth2中的受信任的客户端,身份认证和授权信息的消费方;
- OP:OpenID Provider,有能力提供EU认证的服务(比如OAuth2中的授权服务),用来为RP提供EU的身份认证信息;
- ID Token:JWT格式的数据,包含EU身份认证的信息。
- UserInfo Endpoint:用户信息接口(受OAuth2保护),当RP使用Access Token访问时,返回授权用户的信息,此接口必须使用HTTPS。
OIDC工作流程
OIDC的流程由以下5个步骤构成:
- RP发送一个认证请求给OP;
- OP对EU进行身份认证,然后提供授权;
- OP把ID Token和Access Token(需要的话)返回给RP;
- RP使用Access Token发送一个请求UserInfo EndPoint;
- UserInfo EndPoint返回EU的Claims。
AuthN=Authentication,表示认证;AuthZ=Authorization,代表授权。
具体流程请查看Core规范文档提供的工作流程图:

授权类型
OIDC与OAuth2一样中定义了四种授权方式:
授权码模式(Authorization Code Grant)
客户端重定向用户到授权服务器,用户登录并授权后,授权服务器将重定向用户回客户端,并提供授权码。客户端使用授权码向授权服务器请求访问令牌。
适用于 Web 应用程序,客户端能够保护授权码的安全性。

Demo(由identityserver4+Microsoft.AspNetCore.Authentication实现)
来自identityserver4文档:使用 ASP.NET Core 的交互式应用程序 — IdentityServer4 1.0.0 文档。
项目结构如下:

授权中间件生命周期如下:

授权中间件(Microsoft.AspNetCore.Authentication.Gitee)————参考ASP.NET Core源码实现
- 在项目文件中添加Microsoft.AspNetCore.App引用。
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<FrameworkReference Include="Microsoft.AspNetCore.App" />
</ItemGroup>
</Project>
- 添加Gitee身份认证默认参数
GiteeDefaults.cs
namespace Microsoft.AspNetCore.Authentication.Gitee;
/// <summary>
/// Gitee身份认证默认参数
/// </summary>
public static class GiteeDefaults
{
/// <summary>
/// Gitee默认身份认证方案
/// </summary>
public const string AuthenticationScheme = "Gitee";
/// <summary>
/// Gitee默认身份认证显示名称
/// </summary>
public static readonly string DisplayName = "Gitee";
/// <summary>
/// Gitee进行身份验证的API地址
/// </summary>
/// <remarks>
/// 详情查看文档 <see href="https://gitee.com/api/v5/oauth_doc"/>.
/// </remarks>
public static readonly string AuthorizationEndpoint = "https://gitee.com/oauth/authorize";
/// <summary>
/// Gitee获取访问令牌的API地址
/// </summary>
public static readonly string TokenEndpoint = "https://gitee.com/oauth/token";
/// <summary>
/// Gitee获取用户信息的API地址
/// </summary>
public static readonly string UserInformationEndpoint = "https://gitee.com/api/v5/user";
}
- 添加Gitee默认配置
GiteeOptions.cs
using Microsoft.AspNetCore.Authentication.OAuth;
using Microsoft.AspNetCore.Http;
using System.Security.Claims;
namespace Microsoft.AspNetCore.Authentication.Gitee;
/// <summary>
/// GiteeHandler配置
/// </summary>
public class GiteeOptions : OAuthOptions
{
/// <summary>
/// 初始化一个新实例
/// </summary>
public GiteeOptions()
{
//登陆后回调地址
CallbackPath = new PathString("/signin");
AuthorizationEndpoint = GiteeDefaults.AuthorizationEndpoint;
TokenEndpoint = GiteeDefaults.TokenEndpoint;
UserInformationEndpoint = GiteeDefaults.UserInformationEndpoint;
Scope.Add("user_info");
Scope.Add("projects");
Scope.Add("pull_requests");
Scope.Add("issues");
Scope.Add("notes");
Scope.Add("keys");
Scope.Add(


3365

被折叠的 条评论
为什么被折叠?



