一、简介
    我们做微服务开发,或者说做分布式开发,有一项技术我们是避不开的,那就是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. C#读取XML字符串及将XML字符串反序列化为对象

    在开发中遇到调用接口范围XML格式结果情况,获取结果中我们需要的信息则可能需要这两种数据处理: 1.如何将xml字符串转换为xml对象,及查询想要的节点: 通过XmlDocument对象加载xml字符 ...

  2. jquery的网络引用地址

    http://apps.bdimg.com/libs/jquery/1.6.4/jquery.js http://apps.bdimg.com/libs/jquery/1.6.4/jquery.min ...

  3. Unity多线程使用(线程池)

    1.在C#中使用线程池需要以下这个类库using System.Threading 2.开单个线程(unity程序停止前 线程一定要关闭) private Thread tempThread; voi ...

  4. 【Windows】查询端口占用并中止进程

    netstat -aon|findstr 7000 tasklist|findstr 14828 taskkill /pid 14828 /t /f

  5. pythonn全栈学习笔记--logging模块学习(四)

    一.logging相关配置 1 import logging 2 """ 3 asctime:运行时间 4 name:主模块名称 5 levelname:日志级别 INF ...

  6. How to use lspci, lsscsi, lsusb, and lsblk to get Linux system devices information

    There are many utilities available to check Linux system hardware information. Some commands report ...

  7. jvm中的年轻代 老年代 持久代 gc ----------转载

    jvm中的年轻代 老年代 持久代 gc 虚拟机中的共划分为三个代:年轻代(Young Generation).老年代(Old Generation)和持久代(Permanent Generation) ...

  8. nodejs express 服务代理

    //方法1 var proxy = require('express-http-proxy'); app.use('/map', proxy('https://test.baidu.com/', { ...

  9. 简述ECMAScript6的新特性

    1.增加块级作用域 2.增加let const 3.解构赋值 4.函数参数拓展(函数参数可以使用默认值,不定参数及拓展参数) 5.增加class类支持 6.增加箭头函数 7.增加模块和模块加载(ES6 ...

  10. iOS开发--APP性能检测方案汇总

    1 . CPU 占用率 CPU作为手机的中央处理器,可以说是手机最关键的组成部分,所有应用程序都需要它来调度运行,资源有限.所以当我们的APP因设计不当,使 CPU 持续以高负载运行,将会出现APP卡 ...