龙空技术网

在ASP.NET Core 6中如何实现JWT认证

启辰8 489

前言:

今天看官们对“aspnetweb启动不了”可能比较关心,各位老铁们都想要剖析一些“aspnetweb启动不了”的相关文章。那么小编同时在网摘上网罗了一些关于“aspnetweb启动不了””的相关知识,希望小伙伴们能喜欢,小伙伴们快快来了解一下吧!

使用 JSON Web 令牌进行身份验证和授权,可以轻松保护 ASP.NET Core 6 中的 API 端点。 只需按照以下步骤操作。

ASP.NET Core 6 引入了一种简化的托管模型,使我们能够构建具有最少依赖性的轻量级 API。 自然地,您将经常需要在您的应用程序中保护此类 API 的端点。 这篇文章的目的是让您在这方面抢先一步。

我们已经讨论了如何开始使用最小的 API,如何在最小的 API 中使用日志记录和依赖注入,以及如何在早期的文章中测试最小的 API。 本文讨论了如何使用 JWT 身份验证(即基于 JSON Web 令牌的身份验证)来保护我们最小的 API 端点。

要使用 JWT 身份验证保护最小 API,我们将遵循以下步骤:

在 Visual Studio 2022 中创建一个最小的 API 项目。在 Program.cs 文件中创建 API 端点。将 Microsoft.AspNetCore.Authentication.JwtBearer NuGet 包添加到我们的项目中。在 Program.cs 文件中实现 JWT 身份验证。创建一个名为 User 的用户模型类来存储用户的登录凭据。在 appsettings.json 文件中指定一个密钥。在 Program.cs 文件中指定 JWT 身份验证设置。在 Program.cs 文件中将授权服务中间件添加到我们的应用程序。在 Program.cs 文件中创建并验证 JSON Web 令牌。

请注意,本文中显示的所有代码示例(用户模型类除外)都应该是 Program.cs 的一部分。 User 模型类应该是 User.cs 文件的一部分。

要使用本文中提供的代码示例,您应该在系统中安装 Visual Studio 2022。

在 Visual Studio 2022 中创建 ASP.NET Core 6 最小 Web API 项目(minimal)

首先,让我们在 Visual Studio 中创建一个 ASP.NET Core 6 项目。 按照这些步骤将在 Visual Studio 2022 中创建一个新的 ASP.NET Core 6 Web API 项目:

启动 Visual Studio 2022 IDE。单击“创建新项目”。在“创建新项目”窗口中,从显示的模板列表中选择“ASP.NET Core Web API”。点击下一步。在“配置新项目”窗口中,指定新项目的名称和位置。根据您的喜好,可选择选中“将解决方案和项目放在同一目录中”复选框。点击下一步。在接下来显示的“附加信息”窗口中,取消选中显示“使用控制器...”的复选框,因为我们将在此示例中使用最少的 API。 将“身份验证类型”保留为“无”(默认)。确保未选中“启用 Docker”、“配置 HTTPS”和“启用开放 API 支持”复选框,因为我们不会在此处使用这些功能。单击创建。

我们将使用这个 ASP.NET Core 6 Web API 项目来创建一个最小的 API 端点,并在本文的后续部分中为其实现 JWT 身份验证。

在 ASP.NET Core 6 中创建 HTTP Get 端点

当你在 Visual Studio 2022 中创建一个新的最小 Web API 项目时,将使用几行默认代码创建一个 Program.cs 文件。 您可以使用以下代码片段替换默认代码,以保持简单并仍然提供一种测试 API 的方法。

var builder = WebApplication.CreateBuilder(args);var app = builder.Build();app.MapGet("/security/getMessage",() => "Hello World!").RequireAuthorization();app.Run();

请注意此处使用 RequireAuthorization 扩展方法。 这有助于您使用授权策略保护您的路由,并强制您在调用此端点时提供身份验证信息。 授权中间件将使用此信息来验证对当前执行上下文的请求。

如果您在没有授权信息的情况下执行此端点,您将遇到 HTTP 401 Unauthorized 错误,如图 1 所示。

图1

安装 JwtBearer NuGet 包

现在将 Microsoft.AspNetCore.Authentication.JwtBearer NuGet 包添加到您的项目中。 为此,请在“解决方案资源管理器”窗口中选择项目,然后右键单击并选择“管理 NuGet 包”。 在 NuGet 包管理器窗口中,搜索 Microsoft.AspNetCore.Authentication.JwtBearer 包并安装它。

或者,您可以通过 NuGet 包管理器控制台输入如下所示的命令来安装包。

PM> Install-Package Microsoft.AspNetCore.Authentication.JwtBearer
在 appsettings.json 文件中指定密钥

接下来,在 appsettings.json 文件中为 Issuer、Audience 和 Key 设置信息。 此信息稍后将用于生成 JSON Web Token。 请注意,您可以为该部分指定任意名称; 为了方便起见,我将使用名称“Jwt”。

在 appsettings.json 文件中添加以下信息。

  "Jwt": {    "Issuer": ";,    "Audience": ";,    "Key": "This is a sample secret key - please don't use in production environment.'"  }
在 Program.cs 文件中指定身份验证设置

Program.cs 文件中的 AddAuthenication 方法用于在应用程序启动时配置 JWT 身份验证。 它将身份验证方案指定为 JwtBearer。 此外,调用 AddJwtBearer 方法有助于配置令牌参数。

从 appsettings.json 配置文件中读取 Issuer、Audience 和 Key 值。 TokenValidationParameters 实例用于指示是否应验证 Issuer、Audience、Key 和 Lifetime 信息。

builder.Services.AddAuthentication(options =>{    options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;    options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;    options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;}).AddJwtBearer(o =>{    o.TokenValidationParameters = new TokenValidationParameters    {        ValidIssuer = builder.Configuration["Jwt:Issuer"],        ValidAudience = builder.Configuration["Jwt:Audience"],        IssuerSigningKey = new SymmetricSecurityKey        (Encoding.UTF8.GetBytes(builder.Configuration["Jwt:Key"])),        ValidateIssuer = true,        ValidateAudience = true,        ValidateLifetime = false,        ValidateIssuerSigningKey = true    };});

要向您的应用程序添加授权服务, Program.cs 还应包含以下代码片段。

builder.Services.AddAuthorization();

Program.cs 还应包括以下方法以启用身份验证和授权功能。

app.UseAuthentication();app.UseAuthorization();
在 ASP.NET Core 6 中创建用户模型

我们需要一个类来存储一个或多个用户的登录凭据。 在具有相同名称且扩展名为 .cs 的文件中创建一个名为 User 的类。 然后插入以下代码。

public class User{    public string UserName { get; set; }    public string Password { get; set; }}

此类将用于接受用户凭据作为输入。

创建端点以生成 JSON Web 令牌

最后,我们需要编写必要的代码来生成和验证我们将用于授权调用 API 的 JWT。 在响应对 API 的初始请求生成令牌后,您可以复制它并在所有后续请求中使用它进行授权。

现在,在 Program.cs 文件中编写以下代码以创建一个新的 HTTP Post 端点,该端点将为经过身份验证的用户创建 JWT。

app.MapPost("/security/createToken",[AllowAnonymous] (User user) =>{    if (user.UserName == "joydip" && user.Password == "joydip123")    {        var issuer = builder.Configuration["Jwt:Issuer"];        var audience = builder.Configuration["Jwt:Audience"];        var key = Encoding.ASCII.GetBytes        (builder.Configuration["Jwt:Key"]);        var tokenDescriptor = new SecurityTokenDescriptor        {            Subject = new ClaimsIdentity(new[]            {                new Claim("Id", Guid.NewGuid().ToString()),                new Claim(JwtRegisteredClaimNames.Sub, user.UserName),                new Claim(JwtRegisteredClaimNames.Email, user.UserName),                new Claim(JwtRegisteredClaimNames.Jti,                Guid.NewGuid().ToString())             }),            Expires = DateTime.UtcNow.AddMinutes(5),            Issuer = issuer,            Audience = audience,            SigningCredentials = new SigningCredentials            (new SymmetricSecurityKey(key),            SecurityAlgorithms.HmacSha512Signature)        };        var tokenHandler = new JwtSecurityTokenHandler();        var token = tokenHandler.CreateToken(tokenDescriptor);        var jwtToken = tokenHandler.WriteToken(token);        var stringToken = tokenHandler.WriteToken(token);        return Results.Ok(stringToken);    }    return Results.Unauthorized();});

User 类的实例用于接受传递给此端点的用户名和密码。 请注意 AllowAnonymous 属性。 这用于指定我们不需要在此端点进行授权检查。 从配置文件中读取 Issuer、Audience 和 Key。 这些中的每一个都用于创建我们指定的令牌将在五分钟后过期。

Program.cs 的完整源代码

下面是 Program.cs 文件的完整源代码,供大家参考。

using Microsoft.AspNetCore.Authentication.JwtBearer;using Microsoft.AspNetCore.Authorization;using Microsoft.IdentityModel.Tokens;using System.IdentityModel.Tokens.Jwt;using System.Security.Claims;using System.Text;var builder = WebApplication.CreateBuilder(args);builder.Services.AddAuthentication(options =>{    options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;    options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;    options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;}).AddJwtBearer(o =>{    o.TokenValidationParameters = new TokenValidationParameters    {        ValidIssuer = builder.Configuration["Jwt:Issuer"],        ValidAudience = builder.Configuration["Jwt:Audience"],        IssuerSigningKey = new SymmetricSecurityKey            (Encoding.UTF8.GetBytes(builder.Configuration["Jwt:Key"])),        ValidateIssuer = true,        ValidateAudience = true,        ValidateLifetime = false,        ValidateIssuerSigningKey = true    };});builder.Services.AddAuthorization();var app = builder.Build();app.UseHttpsRedirection();app.MapGet("/security/getMessage", () => "Hello World!").RequireAuthorization();app.MapPost("/security/createToken",[AllowAnonymous] (User user) =>{    if (user.UserName == "joydip" && user.Password == "joydip123")    {        var issuer = builder.Configuration["Jwt:Issuer"];        var audience = builder.Configuration["Jwt:Audience"];        var key = Encoding.ASCII.GetBytes        (builder.Configuration["Jwt:Key"]);        var tokenDescriptor = new SecurityTokenDescriptor        {            Subject = new ClaimsIdentity(new[]            {                new Claim("Id", Guid.NewGuid().ToString()),                new Claim(JwtRegisteredClaimNames.Sub, user.UserName),                new Claim(JwtRegisteredClaimNames.Email, user.UserName),                new Claim(JwtRegisteredClaimNames.Jti,                Guid.NewGuid().ToString())             }),            Expires = DateTime.UtcNow.AddMinutes(5),            Issuer = issuer,            Audience = audience,            SigningCredentials = new SigningCredentials            (new SymmetricSecurityKey(key),            SecurityAlgorithms.HmacSha512Signature)        };        var tokenHandler = new JwtSecurityTokenHandler();        var token = tokenHandler.CreateToken(tokenDescriptor);        var jwtToken = tokenHandler.WriteToken(token);        var stringToken = tokenHandler.WriteToken(token);        return Results.Ok(stringToken);    }    return Results.Unauthorized();});app.UseAuthentication();app.UseAuthorization();app.Run();
JWT 认证实战

当您使用 Postman 将用户凭据发布到 createToken 端点时,您将能够看到生成的令牌。

请注意,我们已经在请求正文中传递了用户凭据,即用户名和密码。

现在,调用我们之前创建的 HTTP Get 端点,并将生成的令牌作为请求标头中的不记名令牌传递。 如果您生成的令牌有效,您将看到图 3 中显示的消息。

图3

正如您在图 3 中所见,文本消息“Hello World!” 显示是因为我们传递的令牌有效。 还要注意 HTTP 200 OK 响应(以绿色矩形突出显示)。

跟上 Microsoft .NET 和软件开发的最新发展

在此示例中,我们对用户名和密码进行了硬编码以保持简单。 当然,您永远不应该在生产环境中对用户凭证进行硬编码。 一个不错的选择是使用 ASP.NET Core 6 Identity 来管理用户帐户。

为了在这里测试我们的最小 API 实现,我们使用了 Postman,这是当今最流行的 API 测试工具之一。 要测试最少的 API 端点,您还可以使用 Swagger,这是一个工具包,可以轻松提供 API 的图形表示。

标签: #aspnetweb启动不了