一、简介
    我们做微服务开发,或者说做分布式开发,有一项技术我们是避不开的,那就是WebAPI,在 Net6.0中,有两类 WebAPI,一类是极简 WebAPI,它砍掉了很多冗余的东西,更纯粹的是做 API的,也更适合做微服务的开发。另外一类就是我们通常使用的正常 API,这个没得说,也是我们使用最多的。
    我们开发的API必须做鉴权和授权操作,否则,就成了裸跑了,那对于系统来说是很危险的。总体来说,一般的WebAPI和MinimalAPI鉴权的过程都是差不多的,但是也有微小的差异。今天我们就来详细说一下,内容很简单,大家有了基础可以随意去扩展。

      开发环境详情:
          操作系统:Windows 10 Professional
          开发工具:Visual Studio 2022
          开发语言:C#
          开发平台:Asp.Net Core 6.0 WebAPI
          测试工具:PostMan

二、具体步骤
    我们在做具体的开发前,也要做一些准备工作,我们要做鉴权和授权,尤其是要使用 JWT 做鉴权和授权,这里面包含两个项目,一个是鉴权服务器,用于提供 JWTToken,另外一个项目是需要做鉴权和授权的具体 WebAPI 项目。有了准备,我们就可以开始了。

    1、第一个项目:PatrickLiu.Net6API.AuthenticationCenter,用于提供获取 Token 接口。
        

        (1)、Program.cs 源码如下,红色是重要代码:            

 1 using PatrickLiu.Net6API.Extensions;
2
3 var builder = WebApplication.CreateBuilder(args);
4
5 builder.Services.AddControllers();
6 builder.Services.AddEndpointsApiExplorer();
7 builder.Services.AddSwaggerGen();
8
9 builder.Services.Configure<JWTTokenOption>(builder.Configuration.GetSection("JWTTokenOption"));
10 builder.Services.AddTransient<IJWTService, JWTService>();
11
12 var app = builder.Build();
13
14 app.UseSwagger();
15 app.UseSwaggerUI();
16
17 app.MapControllers();
18
19 app.Run();

          (2)、AuthenticationController 源码如下:

 1 using Microsoft.AspNetCore.Mvc;
2 using Newtonsoft.Json;
3 using PatrickLiu.Net6API.Extensions;
4
5 namespace PatrickLiu.Net6API.AuthenticationCenter.Controllers
6 {
7 [ApiController]
8 [Route("api/[controller]/[action]")]
9 public class AuthenticationController : ControllerBase
10 {
11 private readonly IJWTService _jWTService;
12
13 /// <summary>
14 /// 实例化。
15 /// </summary>
16 /// <param name="jWTService">注入服务。</param>
17 public AuthenticationController(IJWTService jWTService)
18 {
19 _jWTService = jWTService;
20 }
21
22 /// <summary>
23 /// 根据用户名和密码获取 Token。
24 /// </summary>
25 /// <param name="userName">用户名。</param>
26 /// <param name="password">密码。</param>
27 /// <returns></returns>
28 [HttpPost]
29 public string Login(string userName, string password)
30 {
31 if (!string.IsNullOrEmpty(userName) && !string.IsNullOrEmpty(password))
32 {
33 if (string.Compare(userName, "PatrickLiu", true) == 0 && string.Compare(password, "liulei123456", true) == 0)
34 {
35 string token = _jWTService.GetToken(userName, password);
36 return JsonConvert.SerializeObject(new
37 {
38 Result = true,
39 Token = token
40 });
41 }
42 }
43 return string.Empty;
44 }
45 }
46 }

          (3)、appsettings.json 配置文件源码如下,红色字体要注意:

 1 {
2 "Logging": {
3 "LogLevel": {
4 "Default": "Information",
5 "Microsoft.AspNetCore": "Warning"
6 }
7 },
8 "AllowedHosts": "*",
9 "JWTTokenOption": {
10 "Audience": "PatrickLiu.com",
11 "Issuer": "PatrickLiu.com",
12 "SecurityKey": "12333456677655ffrrffff"
13 }
14 }

    2、还有一个公共项目,用于存放公共类型。项目类型:PatrickLiu.Net6API.Extensions,项目类型:Net 6.0类库。
        

        (1)、IJWTService 源码如下:

 1 namespace PatrickLiu.Net6API.Extensions
2 {
3 /// <summary>
4 /// 提供 Token 的服务。
5 /// </summary>
6 public interface IJWTService
7 {
8 /// <summary>
9 /// 获取 Token。
10 /// </summary>
11 /// <param name="userName">用户名</param>
12 /// <param name="password">密码</param>
13 /// <returns></returns>
14 string GetToken(string userName,string password);
15 }
16 }

        (2)、JWTService 源码如下:      

 1 using Microsoft.Extensions.Options;
2 using Microsoft.IdentityModel.Tokens;
3 using System.IdentityModel.Tokens.Jwt;
4 using System.Security.Claims;
5 using System.Security.Cryptography;
6 using System.Text;
7
8 namespace PatrickLiu.Net6API.Extensions
9 {
10 /// <summary>
11 /// 提供 Token 服务的实现。
12 /// </summary>
13 public sealed class JWTService : IJWTService
14 {
15 private readonly IOptionsMonitor<JWTTokenOption> _option;
16
17 /// <summary>
18 /// 实例化。
19 /// </summary>
20 /// <param name="option">注入选项。</param>
21 public JWTService(IOptionsMonitor<JWTTokenOption> option)
22 {
23 _option = option;
24 }
25
26 /// <summary>
27 /// 获取 Token。
28 /// </summary>
29 /// <param name="userName">用户名。</param>
30 /// <param name="password">密码</param>
31 /// <returns></returns>
32 public string GetToken(string userName, string password)
33 {
34 #region 有效载荷
35
36 var claims = new[] {
37 new Claim(ClaimTypes.Name, userName),
38 new Claim("NickName",userName),
39 new Claim(ClaimTypes.Role,"Administrator"),
40 new Claim("Password",password),
41 };
42
43 #endregion
44
45 SymmetricSecurityKey key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_option.CurrentValue.SecurityKey!));
46
47 SigningCredentials signingCredentials = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
48
49 JwtSecurityToken token = new JwtSecurityToken(
50 issuer: _option.CurrentValue.Issuer!,
51 audience: _option.CurrentValue.Audience!,
52 claims: claims,
53 expires: DateTime.Now.AddMinutes(5),
54 signingCredentials: signingCredentials
55 );
56
57 string returnToken = new JwtSecurityTokenHandler().WriteToken(token);
58
59 return returnToken;
60 }
61 }
62 }

        (3)、JWTTokenOption 源码如下:

 1 namespace PatrickLiu.Net6API.Extensions
2 {
3 /// <summary>
4 /// 用于接受配置数据实体类型。
5 /// </summary>
6 public sealed class JWTTokenOption
7 {
8 /// <summary>
9 /// 获取或者设置接受者。
10 /// </summary>
11 public string? Audience { get; set; }
12
13 /// <summary>
14 /// 获取或者设置加密 key。
15 /// </summary>
16 public string? SecurityKey { get; set; }
17
18 /// <summary>
19 /// 获取或者设置发布者
20 /// </summary>
21 public string? Issuer { get; set; }
22 }
23 }

        (4)、授权服务器运行起来如下:

          

          

    3、现在是普通WebAPI类型项目:

        (1)、我们先看一下项目截图,有一个直观感受,截图如下:
            

        (2)、如果想做WebAPI的JWT的鉴权和授权,必须通过 Nuget 加载的程序包,名称如下:
            Microsoft.AspNetCore.Authentication.JwtBearer
            Microsoft.IdentityModel.Tokens
        (3)、Program.cs源码如下,红色部分表示健全和授权的重要部分。

 1 using Microsoft.AspNetCore.Authentication.JwtBearer;
2 using Microsoft.IdentityModel.Tokens;
3 using PatrickLiu.Net6API.Extensions;
4 using System.Text;
5
6 var builder = WebApplication.CreateBuilder(args);
7
8 builder.Services.AddControllers();
9 builder.Services.AddEndpointsApiExplorer();
10 builder.Services.AddSwaggerGen();
11
12 #region 配置鉴权
13
14 //增加的鉴权逻辑,角色认证、策略认证都是支持的,和Net Core MVC 支持的一样。
15 JWTTokenOption tokenOption = new JWTTokenOption();
16 builder.Configuration.Bind("JWTTokenOption", tokenOption);
17 //builder.Services.Configure<JWTTokenOption>(builder.Configuration.GetSection("JWTTokenOption"));
18 builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
19 .AddJwtBearer(option =>
20 {
21 option.TokenValidationParameters = new TokenValidationParameters()
22 {
23 ValidateIssuer = true,//是否验证 Issuer(发行商)
24 ValidateAudience = true,//是否验证 Audience(受众者)
25 ValidateLifetime = true,//是否验证失效时间
26 ValidateIssuerSigningKey = true,//是否验证 Issuer 的签名键
27 ValidAudience=tokenOption.Audience,
28 ValidIssuer=tokenOption.Issuer,// ValidAudience,ValidIssuer这两项的值要和验证中心的只保持一致。
29 IssuerSigningKey=new SymmetricSecurityKey(Encoding.UTF8.GetBytes(tokenOption.SecurityKey!))
30 };
31 });
32
33 #endregion
34
35 var app = builder.Build();
36
37 app.UseSwagger();
38 app.UseSwaggerUI();
39
40 app.UseAuthentication();
41 app.UseAuthorization();42
43 app.MapControllers();
44
45 app.Run();

        (4)、要实现授权的Controller增加【Authorize】特性,红色部分要注意。

 1 using Microsoft.AspNetCore.Authentication.JwtBearer;
2 using Microsoft.AspNetCore.Authorization;
3 using Microsoft.AspNetCore.Mvc;
4
5 namespace PatrickLiu.Net6API.Resouces.Controllers
6 {
7 [Route("api/[controller]")]
8 [ApiController]
9 public class SecondController : ControllerBase
10 {
11 /// <summary>
12 /// 这里使用 JWT 进行授权检查。
13 /// </summary>
14 /// <returns></returns>
15 [HttpGet]
16 [Authorize(AuthenticationSchemes =JwtBearerDefaults.AuthenticationScheme)]
17 public object GetData()
18 {
19 return new
20 {
21 Id = 1234,
22 Name = "PatrickLiu"
23 };
24 }
25 }
26 }

        (5)、appsettings.json 配置文件,这里的配置要和【PatrickLiu.Net6API.AuthenticationCenter】项目配置一样,红色部分要注意。

 1 {
2 "Logging": {
3 "LogLevel": {
4 "Default": "Information",
5 "Microsoft.AspNetCore": "Warning"
6 }
7 },
8 "AllowedHosts": "*",
9 "JWTTokenOption": {
10 "Audience": "PatrickLiu.com",
11 "Issuer": "PatrickLiu.com",
12 "SecurityKey": "12333456677655ffrrffff"
13 }
14 }

    4、现在是Minimal WebAPI类型项目:
        其实,WebAPI和MinimalAPI鉴权和授权总体都是差不多,差别不大。
        (1)、我们先看一下项目截图,有一个直观感受,截图如下:
            
        (2)、如果想做WebAPI的JWT的鉴权和授权,必须通过 Nuget 加载的程序包,名称如下:
            Microsoft.AspNetCore.Authentication.JwtBearer
            Microsoft.IdentityModel.Tokens

        (3)、Program.cs 源码如下,红色标注要特别重要。

 1 using Microsoft.AspNetCore.Authentication.JwtBearer;
2 using Microsoft.IdentityModel.Tokens;
3 using PatrickLiu.Net6API.Extensions;
4 using PatrickLiu.Net6API.MinimalAPI.Extension;
5 using System.Text;
6
7 var builder = WebApplication.CreateBuilder(args);
8
9 builder.Services.AddEndpointsApiExplorer();
10 builder.Services.AddSwaggerGen();
11
12 #region 1、配置鉴权逻辑
13
14 //增加的鉴权逻辑,角色认证、策略认证都是支持的,和Net Core MVC 支持的一样。
15 JWTTokenOption tokenOption = new JWTTokenOption();
16 builder.Configuration.Bind("JWTTokenOption", tokenOption);
17 builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
18 .AddJwtBearer(option =>
19 {
20 option.TokenValidationParameters = new TokenValidationParameters()
21 {
22 ValidateIssuer = true,//是否验证 Issuer(发行商)
23 ValidateAudience = true,//是否验证 Audience(受众者)
24 ValidateLifetime = true,//是否验证失效时间
25 ValidateIssuerSigningKey = true,//是否验证 Issuer 的签名键
26 ValidAudience = tokenOption.Audience,
27 ValidIssuer = tokenOption.Issuer,// ValidAudience,ValidIssuer这两项的值要和验证中心的只保持一致。
28 IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(tokenOption.SecurityKey!))
29 };
30 });
31
32 #endregion
33
34 #region 2、配置授权逻辑
35
36 //在这里不支持增加授权信息,比如:builder.Services.AddAuthorization(JwtBearerDefaults.AuthenticationScheme);,这样写是不行的,
  我们可以扩展实现 IAuthorizeData 来达到同样的目的。
37 builder.Services.AddAuthorization();
38
39 #endregion
40
41 var app = builder.Build();
42
43 app.UseSwagger();
44 app.UseSwaggerUI();
45
46 #region 3、使用鉴权授权中间件
47
48 app.UseAuthentication();
49 app.UseAuthorization();
50
51 #endregion
52
53 #region 4、实现授权要求
54
55 app.MapGet("/User", (int id, string name) =>
56 {
57 return "Hello World!";
58 }).RequireAuthorization(new CustomAuthorizeData()
59 {
60 AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme
61 //可以增加角色授权
62 //,Roles="",
63 //可以增加策略授权。
64 //Policy=""
65 });
66
67 app.MapGet("/Products", (HttpContext context) =>
68 {
69 return new
70 {
71 Id = 123456,
72 Name = "IPhone14 Pro Max",
73 Price = 4839.23,
74 DateOfProduction = "2023/2/12 23:22"
75 };
76 });
77
78 #endregion
79
80 app.Run();

        (4)、扩展 IAuthorizeData 接口实现CustomAuthorizeData,可以实现对MinimalAPI授权。

 1 using Microsoft.AspNetCore.Authorization;
2
3 namespace PatrickLiu.Net6API.MinimalAPI.Extension
4 {
5 public sealed class CustomAuthorizeData : IAuthorizeData
6 {
7 public string? Policy { get; set; }
8 public string? Roles { get; set; }
9 public string? AuthenticationSchemes { get; set; }
10 }
11 }

        (5)、appsettings.json 配置文件源码如下,红色部分是重要代码。

 1 {
2 "Logging": {
3 "LogLevel": {
4 "Default": "Information",
5 "Microsoft.AspNetCore": "Warning"
6 }
7 },
8 "AllowedHosts": "*",
9 "JWTTokenOption": {
10 "Audience": "PatrickLiu.com",
11 "Issuer": "PatrickLiu.com",
12 "SecurityKey": "12333456677655ffrrffff"
13 }
14 }

三、结束语

      好了,今天就写到这里了,现在总结一下,如果想要给WebAPI或者MinimalAPI实现授权和鉴权,总体步骤是差不多的,第一步,都要启用连个中间件,就是授权和鉴权中间件(app.UseAuthorization()、app.UseAuthentication()),然后要配置鉴权的配置逻辑,差别就在授权方面,普通WebAPI直接通过 AuthorizeAttribute 特性标注在需要授权的方法或者 Controller 类型上就可以。普通WebAPI支持所有的角色授权、策略授权等方法,并且也支持所有的Filter。MinimalAPI要实现授权,要在GetXXX方法后面调用RequireAuthorization()来实现授权的内容。不忘初心,继续努力,老天不会辜负努力的人。

如何在 Net6.0 中对 WebAPI 进行 JWT 认证和授权的更多相关文章

  1. WebApi使用JWT认证(一)

    这是第一部:先实现NetFramework上的WebApi使用JWT认证 1.VS新建一个WebApi项目 2.项目右键----管理Nuget程序包----找到JWT,然后安装 3.Model文件夹下 ...

  2. WebApi使用JWT认证(二)

    这是第二部:实现NetCore上的WebApi使用JWT认证 1.NetCore新建一个WebApi的项目 2.打开AppSettings.json,添加Jwt的信息,这里为了演示而已 { " ...

  3. ASP.NET Core WebApi基于JWT实现接口授权验证

    一.ASP.Net Core WebApi JWT课程前言 我们知道,http协议本身是一种无状态的协议,而这就意味着如果用户向我们的应用提供了用户名和密码来进行用户认证,那么下一次请求时,用户还要再 ...

  4. ASP.NET Core 6.0 添加 JWT 认证和授权

    序言 本文将分别介绍 Authentication(认证) 和 Authorization(授权). 并以简单的例子在 ASP.NET Core 6.0 的 WebAPI 中分别实现这两个功能. 相关 ...

  5. 如何在.net4.0中使用.net4.5的async/await

    推荐文章: http://www.cnblogs.com/hj4444/p/3857771.html http://www.cnblogs.com/dozer/archive/2012/03/06/a ...

  6. .net6.0 中一个接口多个实现的服务注册与注入

    1.现有一个数据库操作接口 如下   它有两个数据操作实现 Sqlserver 和MySql的数据库操作实现类 现在我们需要 将这个两个类 注册到MVC中 注意这里注册的服务类型都是 IDataBas ...

  7. Hadoop-2.2.0中文文档—— Common - 服务层认证

    目的 此文档描写叙述了怎样为Hadoop配置和管理 Service Level Authorization . 预备条件 确保已经安装Hadoop,配置和设置都正确了. 很多其它细节,请看:* 首次使 ...

  8. SpringBoot2.0整合SpringSecurity实现WEB JWT认证

    相信很多做技术的朋友都做过前后端分离项目,项目分离后认证就靠JWT,费话不多说,直接上干活(写的不好还请多多见谅,大牛请绕行) 直接上代码,项目为Maven项目,结构如图: 包分类如下: com.ap ...

  9. .net core3.1中实现简单的jwt认证

    1.创建项目 使用visual studio创建一个名为JwtDemo的空项目,创建后如图 2.添加依赖项 在nuget包管理器中搜索 Microsoft.AspNetCore.Authenticat ...

  10. WebApi使用JWT认证

    https://www.cnblogs.com/wangyulong/p/8727683.html https://blog.csdn.net/kebi007/article/details/7286 ...

随机推荐

  1. 打车起步价8元(3KM以内) 超过3KM,超出的每公里1.2元 超过5KM,超出的每公里1.5元 请在键盘上接收公里数,得出总价。

    import java.util.Scanner; public class Taxi { public static void main(String []agrs){ Scanner s = ne ...

  2. HidController控件下载安装

    用Delphi 或 C++ 开发 USB 接口时要用到的 HidController控件,如果你找不到去哪下载参考这里. 下载地址:https://sourceforge.net/projects/j ...

  3. selenium webdriver 无法选中元素,修改元素属性可见

    <ul data-v-6529428e="" class="el-dropdown-menu el-popper filter-dropdown el-dropdo ...

  4. 鸿蒙hi3861V100开发板问题记录

    1.引脚复用 2.引脚复用方法: 1.看业务代码使用的是uart几,如使用的是uart2(实测可用uart1 tx为GPIO6, rx为GPIO5:uart2 tx为GPIO11,rx为GPIO12) ...

  5. Mysql explain 每个属性含义

    Mysql explain explain 常用于分析sql语句的执行效率,使用时在正常的select语句之前添加explain并执行就会返回执行信息,返回的执行信息如下:  id:id列的编号是se ...

  6. Verilog标识符与关键字

    Verilog标识符与关键字 1.标识符: Verilog HDL中的标识符是指用来声明数据,变量,端口,例化名等除关键字外的所有名称的组合.如:input a, 这里a就是一个标识符,用来代表一个输 ...

  7. Windows server 防火墙开放oracle监听端口

    Windows server 防火墙开放oracle监听端口 Windows server 2008 开放1521端口 Windows server 2003 开放监听程序例外先开防火墙,再开监听例外 ...

  8. 08.File类与IO流

    一.File 类 是文件和目录路径名的抽象表示,主要用于文件和目录的创建.查找和删除等操作. Java 把电脑中的文件和文件夹(目录)封装为了一个 File 类. File 类是与系统无关的类,任何操 ...

  9. C# 获取当前路径7种方法及输出

    //获取模块的完整路径.string path1 = System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName;D:\wor ...

  10. 如何用算法把一个十进制数转为十六进制数-C语言基础

    这一篇文章要探讨的是"如何用算法实现十进制转十六进制"并不涉及什么特别的知识点.属于C语言基础篇. 在翻找素材的时候,发现一篇以前写的挺有意思的代码,这篇代码里面涉及的知识点没有什 ...