OAuth 客户端 for C# (.NET):IdentityModel 库与 OAuth 2.0 集成

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

用于 C# (.NET) 中 OAuth 2.0 和 OpenID Connect 的 IdentityModel 库



在 .NET 平台上开发现代 Web 应用程序、移动客户端或服务器端 API 时,几乎总是需要与外部身份验证提供商(Google、GitHub、Microsoft 等)或您自己的授权服务器进行集成。IdentityModel 是一个轻量级但功能强大的 C# 库,它提供了一个便捷的 OAuth 客户端,用于处理 OAuth 2.0 和 OpenID Connect 协议。它实际上是 .NET 生态系统中实现授权流程的事实标准。



在本文中,我们将详细介绍如何使用 IdentityModel 创建 OAuth 客户端、获取访问令牌以及刷新令牌。代码示例将使用 C# (.NET 6+)。



安装与配置



首先,通过 NuGet 包管理器安装包:



dotnet add package IdentityModel


或者通过包管理器控制台:



Install-Package IdentityModel


安装后,您将可以访问 HttpClient 扩展方法、DiscoveryClient、TokenClient 类以及其他辅助工具。



基本场景:通过客户端凭证获取令牌



此流程用于服务器到服务器的身份验证,即客户端(您的应用程序)代表自身而非用户请求令牌。



OAuth 客户端配置示例:



using IdentityModel.Client;using System.Net.Http;using System.Threading.Tasks;

public async Task<string> GetAccessTokenAsync(){ var client = new HttpClient();

// 1. 从授权服务器获取发现文档 var disco = await client.GetDiscoveryDocumentAsync("https://your-auth-server.com"); if (disco.IsError) { throw new Exception($"获取发现文档时出错: {disco.Error}"); }

// 2. 使用 client_id 和 client_secret 请求令牌 var tokenResponse = await client.RequestClientCredentialsTokenAsync( new ClientCredentialsTokenRequest { Address = disco.TokenEndpoint, ClientId = "your-client-id", ClientSecret = "your-client-secret", Scope = "api1 api2" // 请求的权限范围 });

if (tokenResponse.IsError) { throw new Exception($"获取令牌时出错: {tokenResponse.Error}"); }

return tokenResponse.AccessToken;}


在此示例中,我们使用了 IdentityModel.Client 命名空间中的扩展方法。该库会自动处理 JSON 序列化、标头和响应解析。



授权码流程(涉及用户交互)



对于具有用户界面的应用程序(ASP.NET Core MVC、Blazor、桌面应用),通常使用授权码。IdentityModel 可与 Microsoft.AspNetCore.Authentication.OpenIdConnect 集成,但也提供用于手动实现的底层工具。



重定向后使用授权码获取令牌的示例:



public async Task<TokenResponse> ExchangeCodeForTokenAsync(string authorizationCode, string redirectUri){    var client = new HttpClient();    var disco = await client.GetDiscoveryDocumentAsync("https://your-auth-server.com");

var tokenResponse = await client.RequestAuthorizationCodeTokenAsync( new AuthorizationCodeTokenRequest { Address = disco.TokenEndpoint, ClientId = "your-client-id", ClientSecret = "your-client-secret", Code = authorizationCode, RedirectUri = redirectUri });

return tokenResponse;}


刷新令牌



访问令牌通常有效期较短(例如 1 小时)。

推荐