引言:为什么现代应用需要 OAuth 2.0 和 JWT?
在现代 Web 开发中,数据安全和访问管理变得至关重要。每天有数百万用户通过 Google、Facebook 或企业系统登录应用,而无需直接提供密码。正是在这里,OAuth 2.0 协议和 JWT(JSON Web 令牌)技术发挥了作用。
OAuth 2.0 是委托访问的行业标准。它允许应用在不泄露用户凭据的情况下,获取对用户资源的有限访问权限。而 JWT 则是一种紧凑且自包含的令牌格式,包含了验证身份和授权所需的所有信息。
在本文中,我们将实际讲解如何使用 ASP.NET Core 在 C# 中实现 OAuth 2.0 和 JWT 授权。您将学习如何配置授权服务器、生成令牌以及保护您的 API 端点。所有代码示例均可直接用于实际项目。
1. 使用 IdentityServer4 配置授权服务器
为了实现 OAuth 2.0,我们将使用流行的 IdentityServer4 库——这是一个用于 ASP.NET Core 的框架,实现了 OpenID Connect 和 OAuth 2.0 协议。让我们从创建一个最小的授权服务器开始。
步骤 1:安装包并创建项目
创建一个新的 ASP.NET Core Web 应用程序(空模板)并安装必要的 NuGet 包:
dotnet add package IdentityServer4dotnet add package Microsoft.AspNetCore.Authentication.JwtBearer步骤 2:配置客户端和资源
定义测试用户、客户端和受保护资源。创建 Config.cs 类:
public static class Config{ public static IEnumerable<IdentityResource> IdentityResources => new[] { new IdentityResources.OpenId(), new IdentityResources.Profile() };
public static IEnumerable<ApiScope> ApiScopes => new[] { new ApiScope("api1", "My API") };
public static IEnumerable<Client> Clients => new[] { new Client { ClientId = "client", AllowedGrantTypes = GrantTypes.ClientCredentials, ClientSecrets = { new Secret("secret".Sha256()) }, AllowedScopes = { "api1" } } };}步骤 3:在 Startup.cs 中注册服务
在 ConfigureServices 方法中配置 IdentityServer:
public void ConfigureServices(IServiceCollection services){ services.AddIdentityServer() .AddInMemoryIdentityResources(Config.IdentityResources) .AddInMemoryApiScopes(Config.ApiScopes) .AddInMemoryClients(Config.Clients) .AddTestUsers(TestUsers.Users);
services.AddAuthentication() .AddJwtBearer("Bearer", options => { options.Authority = "https://localhost:5001"; options.TokenValidationParameters = new TokenValidationParameters { ValidateAudience = false }; });}在 Configure 方法中,添加对 app.UseIdentityServer() 的调用。
2. 实现 JWT 令牌:生成与验证
JWT 令牌由三部分组成:头部(header)、载荷(payload)和签名(signature)。在 .NET 中,JWT 的生成和验证通过内置机制完成。
手动生成 JWT 令牌
有时需要手动创建令牌,例如用于测试。使用以下代码:
using System.IdentityModel.Tokens.Jwt;using Microsoft.IdentityModel.Tokens;using System.Security.Claims;using System.Text;
public string GenerateJwtToken(string userI