翼度科技»论坛 编程开发 .net 查看内容

在NET8中使用简化的 AddJwtBearer 认证

5

主题

5

帖子

15

积分

新手上路

Rank: 1

积分
15
开发环境

系统版本: win10
.NET SDK:  NET8
开发工具:vscode
参考引用:使用 dotnet user-jwts 管理开发中的 JSON Web 令牌
注意:以下示例中的端口、token等需替换成你的环境中的信息
创建项目

运行以下命令来创建一个空的 Web 项目,并添加 Microsoft.AspNetCore.Authentication.JwtBearer NuGet 包:
  1. dotnet new web -o MyJWT
  2. cd MyJWT
  3. dotnet add package Microsoft.AspNetCore.Authentication.JwtBearer
复制代码
将 Program.cs 的内容替换为以下代码(略微改动):
  1. using System.Security.Claims;
  2. var builder = WebApplication.CreateBuilder(args);
  3. builder.Services.AddAuthorization();
  4. // 默认的Scheme是Bearer
  5. // builder.Services.AddAuthentication("Bearer").AddJwtBearer();
  6. builder.Services.AddAuthentication().AddJwtBearer();
  7. var app = builder.Build();
  8. app.UseAuthorization();
  9. app.MapGet("/", () => "Hello, World!");
  10. app.MapGet("/secret", (ClaimsPrincipal user) => $"Hello {user.Identity?.Name}. My secret")
  11.     .RequireAuthorization();
  12. app.Run();
复制代码
运行项目并访问接口返回以下内容
  1. PS D:\Learn\MyJWT> curl.exe -i http:///localhost:5276
  2. HTTP/1.1 200 OK
  3. Content-Type: text/plain; charset=utf-8
  4. Date: Mon, 04 Dec 2023 00:43:03 GMT   
  5. Server: Kestrel
  6. Transfer-Encoding: chunked
  7. Hello, World!
复制代码
创建 JWT
  1. PS D:\Learn\MyJWT> dotnet user-jwts create
  2. New JWT saved with ID 'c28b968'.
  3. Name: Lingpeng
  4. Token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1bmlxdWVfbmFtZSI6IkxpbmdwZW5nIiwic3ViIjoiTGluZ3BlbmciLCJqdGkiOiJjMjhiOTY4IiwiYXVkIjpbImh0dHA6Ly9sb2NhbGhvc3Q6Mjk3NTQiLCJodHRwczovL2xvY2FsaG9zdDo0NDM2MCIsImh0dHA6Ly9sb2NhbGhvc3Q6NTI3NiIsImh0dHBzOi8vbG9jYWxob3N0OjcyNTMiXSwibmJmIjoxNzAxNjQ5Nzk2LCJleHAiOjE3MDk1MTIxOTYsImlhdCI6MTcwMTY0OTc5NiwiaXNzIjoiZG90bmV0LXVzZXItand0cyJ9.l52s9_7oNjIKL96TysgdE0k970fUS9FoLTu2xRs-IPo
复制代码
这个命令做了3件事:

  • 更新项目的 appsettings.Development.json,添加了Authentication节点
  • 更新项目的 MyJWT.csproj,添加了UserSecretsId 配置
  • 创建了机密文件 %APPDATA%\Microsoft\UserSecrets\\user-jwts.json与%APPDATA%\Microsoft\UserSecrets\\secrets.json,机密管理参考
我们看下这两个机密文件
user-jwts.json
  1. {
  2.     "c28b968": {
  3.         "Id": "c28b968",
  4.         "Scheme": "Bearer",
  5.         "Name": "Lingpeng",
  6.         "Audience": "http://localhost:29754, https://localhost:44360, http://localhost:5276, https://localhost:7253",
  7.         "NotBefore": "2023-12-04T00:29:56+00:00",
  8.         "Expires": "2024-03-04T00:29:56+00:00",
  9.         "Issued": "2023-12-04T00:29:56+00:00",
  10.         "Token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1bmlxdWVfbmFtZSI6IkxpbmdwZW5nIiwic3ViIjoiTGluZ3BlbmciLCJqdGkiOiJjMjhiOTY4IiwiYXVkIjpbImh0dHA6Ly9sb2NhbGhvc3Q6Mjk3NTQiLCJodHRwczovL2xvY2FsaG9zdDo0NDM2MCIsImh0dHA6Ly9sb2NhbGhvc3Q6NTI3NiIsImh0dHBzOi8vbG9jYWxob3N0OjcyNTMiXSwibmJmIjoxNzAxNjQ5Nzk2LCJleHAiOjE3MDk1MTIxOTYsImlhdCI6MTcwMTY0OTc5NiwiaXNzIjoiZG90bmV0LXVzZXItand0cyJ9.l52s9_7oNjIKL96TysgdE0k970fUS9FoLTu2xRs-IPo",
  11.         "Scopes": [],
  12.         "Roles": [],
  13.         "CustomClaims": {}
  14.     }
  15. }
复制代码
secrets.json
  1. {
  2.     "Authentication:Schemes:Bearer:SigningKeys": [
  3.         {
  4.             "Id": "ff20683d",
  5.             "Issuer": "dotnet-user-jwts",
  6.             "Value": "lDOFmIuEDelFKU0zAaLoT2qYOFDRZGDDTv5FyTa36V8=",
  7.             "Length": 32
  8.         }
  9.     ]
  10. }
复制代码
测试JWT

我们重新运行程序,用直接访问与携带token两种方式访问/secret接口
  1. PS D:\Learn\MyJWT> curl.exe -i http://localhost:5276/secret
  2. HTTP/1.1 401 Unauthorized
  3. Content-Length: 0
  4. Date: Mon, 04 Dec 2023 00:43:25 GMT
  5. Server: Kestrel
  6. WWW-Authenticate: Bearer
  7. PS D:\Learn\MyJWT>
  8. PS D:\Learn\MyJWT>
  9. PS D:\Learn\MyJWT> curl.exe -i -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1bmlxdWVfbmFtZSI6IkxpbmdwZW5nIiwic3ViIjoiTGluZ3BlbmciLCJqdGkiOiJjMjhiOTY4IiwiYXVkIjpbImh0dHA6Ly9sb2NhbGhvc3Q6Mjk3NTQiLCJodHRwczovL2xvY2FsaG9zdDo0NDM2MCIsImh0dHA6Ly9sb2NhbGhvc3Q6NTI3NiIsImh0dHBzOi8vbG9jYWxob3N0OjcyNTMiXSwibmJmIjoxNzAxNjQ5Nzk2LCJleHAiOjE3MDk1MTIxOTYsImlhdCI6MTcwMTY0OTc5NiwiaXNzIjoiZG90bmV0LXVzZXItand0cyJ9.l52s9_7oNjIKL96TysgdE0k970fUS9FoLTu2xRs-IPo" http://localhost:5276/secret
  10. HTTP/1.1 200 OK
  11. Content-Type: text/plain; charset=utf-8
  12. Date: Mon, 04 Dec 2023 00:45:42 GMT
  13. Server: Kestrel
  14. Transfer-Encoding: chunked
  15. Hello Lingpeng. My secret
复制代码
至此我们已经实现了JwtBearer的初步使用
一点点改动

示例采用了机密管理,我们也可以把机密文件中的内容迁移至项目中(推荐用机密管理),我们修改MyJWT.csproj与appsettings.Development.json如下
  1. <Project Sdk="Microsoft.NET.Sdk.Web">
  2.   <PropertyGroup>
  3.     <TargetFramework>net8.0</TargetFramework>
  4.     <Nullable>enable</Nullable>
  5.     <ImplicitUsings>enable</ImplicitUsings>
  6.    
  7.   </PropertyGroup>
  8.   <ItemGroup>
  9.     <PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="8.0.0" />
  10.   </ItemGroup>
  11. </Project>
复制代码
  1. {
  2.   "Logging": {
  3.     "LogLevel": {
  4.       "Default": "Information",
  5.       "Microsoft.AspNetCore": "Warning"
  6.     }
  7.   },
  8.   "Authentication": {
  9.     "Schemes": {
  10.       "Bearer": {
  11.         "ValidAudiences": [
  12.           "http://localhost:29754",
  13.           "https://localhost:44360",
  14.           "http://localhost:5276",
  15.           "https://localhost:7253"
  16.         ],
  17.         "ValidIssuer": "dotnet-user-jwts",
  18.         "SigningKeys": [
  19.           {
  20.             "Id": "ff20683d",
  21.             "Issuer": "dotnet-user-jwts",
  22.             "Value": "lDOFmIuEDelFKU0zAaLoT2qYOFDRZGDDTv5FyTa36V8=",
  23.             "Length": 32
  24.           }
  25.         ]
  26.       }
  27.     }
  28.   }
  29. }
复制代码
修改完成后实现相同的功能
JWT Token生成示例
  1. app.MapGet("/login", (string UserName, string Password, [FromServices] IOptionsMonitor<JwtBearerOptions> optionsMonitor) =>
  2. {
  3.     // 1. 密码验证
  4.     // TODO
  5.     // 2. 生成  
  6.     var parameters = optionsMonitor.Get(JwtBearerDefaults.AuthenticationScheme).TokenValidationParameters;
  7.     var signingKey = parameters.IssuerSigningKeys.First();
  8.     var signingCredentials = new SigningCredentials(signingKey, SecurityAlgorithms.HmacSha256Signature);
  9.     var header = new JwtHeader(signingCredentials);
  10.     var payload = new JwtPayload {
  11.         { JwtRegisteredClaimNames.UniqueName, UserName },
  12.         { JwtRegisteredClaimNames.Iss, parameters.ValidIssuers.First() },
  13.         { JwtRegisteredClaimNames.Aud, parameters.ValidAudiences },
  14.         { JwtRegisteredClaimNames.Iat, DateTimeOffset.UtcNow.ToUnixTimeSeconds() },
  15.         { JwtRegisteredClaimNames.Nbf, DateTimeOffset.UtcNow.ToUnixTimeSeconds() },
  16.         { JwtRegisteredClaimNames.Exp, DateTimeOffset.UtcNow.AddMinutes(30).ToUnixTimeSeconds() }
  17.     };
  18.     var jwtSecurityToken = new JwtSecurityToken(header, payload);
  19.     var jwtSecurityTokenHandler = new JwtSecurityTokenHandler();
  20.     var token = jwtSecurityTokenHandler.WriteToken(jwtSecurityToken);
  21.     return token;
  22. });
复制代码
进行一下验证
  1. PS D:\Learn\MyJWT> curl.exe -i "http://localhost:5276/login?username=admin&password=1111"
  2. HTTP/1.1 200 OK
  3. Content-Type: text/plain; charset=utf-8
  4. Date: Mon, 04 Dec 2023 05:03:36 GMT
  5. Server: Kestrel
  6. Transfer-Encoding: chunked
  7. eyJhbGciOiJodHRwOi8vd3d3LnczLm9yZy8yMDAxLzA0L3htbGRzaWctbW9yZSNobWFjLXNoYTI1NiIsInR5cCI6IkpXVCJ9.eyJ1bmlxdWVfbmFtZSI6ImFkbWluIiwiaXNzIjoiZG90bmV0LXVzZXItand0cyIsImF1ZCI6WyJodHRwOi8vbG9jYWxob3N0OjI5NzU0IiwiaHR0cHM6Ly9sb2NhbGhvc3Q6NDQzNjAiLCJodHRwOi8vbG9jYWxob3N0OjUyNzYiLCJodHRwczovL2xvY2FsaG9zdDo3MjUzIl0sImlhdCI6MTcwMTY2NjIxNiwibmJmIjoxNzAxNjY2MjE2LCJleHAiOjE3MDE2NjgwMTZ9.P9t7vIFfM7cddRPs4OQUTVVdo57nWTLt_ea2UynGUpo
  8. PS D:\Learn\MyJWT>
  9. PS D:\Learn\MyJWT>
  10. PS D:\Learn\MyJWT> curl.exe -i -H "Authorization: Bearer eyJhbGciOiJodHRwOi8vd3d3LnczLm9yZy8yMDAxLzA0L3htbGRzaWctbW9yZSNobWFjLXNoYTI1NiIsInR5cCI6IkpXVCJ9.eyJ1bmlxdWVfbmFtZSI6ImFkbWluIiwiaXNzIjoiZG90bmV0LXVzZXItand0cyIsImF1ZCI6WyJodHRwOi8vbG9jYWxob3N0OjI5NzU0IiwiaHR0cHM6Ly9sb2NhbGhvc3Q6NDQzNjAiLCJodHRwOi8vbG9jYWxob3N0OjUyNzYiLCJodHRwczovL2xvY2FsaG9zdDo3MjUzIl0sImlhdCI6MTcwMTY2NjIxNiwibmJmIjoxNzAxNjY2MjE2LCJleHAiOjE3MDE2NjgwMTZ9.P9t7vIFfM7cddRPs4OQUTVVdo57nWTLt_ea2UynGUpo" http://localhost:5276/secret
  11. HTTP/1.1 200 OK
  12. Content-Type: text/plain; charset=utf-8
  13. Date: Mon, 04 Dec 2023 05:03:50 GMT
  14. Server: Kestrel
  15. Transfer-Encoding: chunked
  16. Hello admin. My secret
复制代码
来源:https://www.cnblogs.com/lludcmmcdull/archive/2023/12/04/17874175.html
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!

举报 回复 使用道具