当前位置: 首页 > news >正文

ASP.NET Core Web API用户身份验证

一、JWT介绍

ASP.NET Core Web API用户身份验证的方法有很多,本文只介绍JWT方法。JWT实现了服务端无状态,在分布式服务、会话一致性、单点登录等方面凸显优势,不占用服务端资源。简单来说,JWT的验证过程如下所示:

(1)通过用户名和密码获取一个Token。

(2)访问API时,加上这个Token。

Token包含过期时间、用户角色等信息,可以在多种场合灵活使用。

二、基本认证

2.1 场景描述

在基本认证的场景中,我们假设有一个Controller,代码如下所示:

[ApiController]
[Route("test")]
public class TestController : ControllerBase
{[HttpGet]public string Get(){return "success";}
}

这个Controller非常简单,就是访问之后返回"success"这个字符串。

现在,我们希望用户登录之后(提供用户名和密码)才能使用此API。

2.2 开发步骤

1、在NuGet中添加Microsoft.AspNetCore.Authentication.JwtBearer。

2、在Program.cs中,对builder.Services添加认证服务:

builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(opt =>{opt.TokenValidationParameters = new TokenValidationParameters(){ValidateIssuer = false,ValidateAudience = false,ValidateLifetime = false,ValidateIssuerSigningKey = false};});

在上面的参数中,可以根据使用场景进行灵活配置,这个后面会介绍。在此,使用最简单的配置。

3、同样在Program.cs中,添加以下语句:

app.UseAuthentication();

需要注意的是,此句需要在页面路由之前,例如是app.UseHttpsRedirection();之前,如下所示:

app.UseAuthentication();app.UseHttpsRedirection();app.UseAuthorization();app.MapControllers();app.Run();

4、在需要认证的Controller或某个具体方法上加上[Authorize]标记。例如我们在一开始介绍的API上加上标记:

[Authorize]
[HttpGet]
public string Get()
{return "success";
}

此时,如果再去访问此API,就会返回401没有权限的错误。

5、创建登录的Controller,也就是通过用户名和密码获取Token。

[Route("api/auth")]
[ApiController]
public class AuthController : ControllerBase
{[HttpPost]public string Gettoken(string username, string password){if (username == "admin" && password == "123456"){var claims = new[]{new Claim(ClaimTypes.Name, username)};var jwttoken = new JwtSecurityToken(claims: claims);var token = new JwtSecurityTokenHandler().WriteToken(jwttoken);return token;}return "用户不存在或密码错误";}
}

上面的用户认证简单的做了字符串比对,实际上可以通过查数据库的方法验证用户是否合法。

至此,用户验证的后端就开发完成了。

三、前端访问API

3.1 通过Swagger测试

很多时候,我们使用Swagger来测试API,但默认的Swagger配置没有用户验证,需要进行添加。

打开Program.cs,把builder.Services.AddSwaggerGen();这一句修改为:

builder.Services.AddSwaggerGen(c =>
{c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme(){In = ParameterLocation.Header,Type = SecuritySchemeType.ApiKey,Description = "Bearer Token",Name = "Authorization",BearerFormat = "JWT",Scheme = "Bearer"});c.AddSecurityRequirement(new OpenApiSecurityRequirement() {{new OpenApiSecurityScheme(){Reference=new OpenApiReference(){Type=ReferenceType.SecurityScheme,Id="Bearer"}},new string[]{ }}});
});

此时,打开Swagger,就会看到右上角有一个Authorize的按钮,如下图所示:

点击按钮,会要求输入一个Token。我们从上面写的登录Controller(AuthController)获取。如下图所示:

 最下面的响应字符串就是我们要的Token。把这个Token填入到上面弹出的对话框中,注意需要在字符串前加上“Bearer ”。如下图所示:

此时,再去访问TestController,就会返回成功结果。

3.2 前端访问方法

 在无用户验证要求的时候,前端访问TestController的代码如下所示:

fetch("https://localhost:28911/test", {method: "GET"
}).then(resp => {return resp.text();
}).then(data => {console.log(data);
}).catch(err => {console.log(err)
});

API前加上[Authorize]之后,上述调用也会返回401错误。上述调用需要把Token加入到Header中。

fetch("https://localhost:28911/test", {method: "GET",headers: {"Authorization": "Bearer eyJhbGciOiJ...太长,Token后面省略"}
}).then(resp => {return resp.text();
}).then(data => {console.log(data);
}).catch(err => {console.log(err)
});

此时,即可再次成功获取结果。

四、常见用户身份验证场景

4.1 Token有效期

一般情况下,通过用户名和密码得到了Token之后,我们不希望这个Token是永久有效的。也就是说,过了一段时间之后,Token失效,用户需要重新登录。

需要增加有效期,有几处地方需要修改。

首先是Program.cs中,原来的配置如下所示:

builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(opt =>{opt.TokenValidationParameters = new TokenValidationParameters(){ValidateIssuer = false,ValidateAudience = false,ValidateLifetime = false,ValidateIssuerSigningKey = false};});

需要把ValidateLifetime改为true:

builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(opt =>{opt.TokenValidationParameters = new TokenValidationParameters(){ValidateIssuer = false,ValidateAudience = false,ValidateLifetime = true,ClockSkew = TimeSpan.FromSeconds(30),};});

然后在AuthController的Gettoken方法里,加上有效期:

var claims = new[]{new Claim(JwtRegisteredClaimNames.Nbf,new DateTimeOffset(DateTime.Now).ToUnixTimeSeconds().ToString()) ,new Claim(JwtRegisteredClaimNames.Exp,new DateTimeOffset(DateTime.Now.AddMinutes(30)).ToUnixTimeSeconds().ToString()),new Claim(ClaimTypes.Name, username)
};

上面配置的有效期是30分钟。

至此,当获得一个新的Token之后,经过30分钟,这个Token就无法使用了。

4.2 第三方验证

很多网站上提供QQ登录、微信登录、微博登录等功能,我们以微信登录进行说明。如果我们需要使用微信登录,需要到微信开发者平台注册,拿到一个叫AppKey的东西。这个AppKey相当于一个私钥,是不能让别人看到的。因为我们要使用微信的登录验证服务,这个服务不能向任何人提供,而且需要区分是哪个第三方在使用服务。

为了实现上述功能,认证时加入了一个IssUser的概念,也就是哪些APP可以调用服务。

在Program.cs中,修改配置:

builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(opt =>{opt.TokenValidationParameters = new TokenValidationParameters(){ValidateIssuer = true,ValidateAudience = false,ValidateLifetime = false,ValidateIssuerSigningKey = true,ValidIssuer = "App名称",IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("App私钥"))};});

然后,在Gettoken时,进行修改:

var claims = new[]{new Claim(ClaimTypes.Name, username)
};
var m5dkey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("App私钥"));
var creds = new SigningCredentials(m5dkey, SecurityAlgorithms.HmacSha256);
var jwttoken = new JwtSecurityToken(issuer: "App名称",claims: claims,expires: DateTime.Now.AddMinutes(30),signingCredentials: creds
);
var token = new JwtSecurityTokenHandler().WriteToken(jwttoken);
return token;

4.3 角色或权限

很多时候,用户登录之后,并不是可以访问所有的API。用户可以分出不同的角色,不同的角色可以访问不同的资源。

要做到这一点,首先在Gettoken时,把用户的角色加入到Token中。

var claims = new[]{new Claim(ClaimTypes.Name, username),new Claim("Role", "admin")
};

然后,在API前,指明此资源需要什么角色。

[Authorize(Roles = "admin")]
[HttpGet]
public string Get()
{return "success";
}

这样,按角色分配资源的功能就完成了。

相关文章:

ASP.NET Core Web API用户身份验证

一、JWT介绍 ASP.NET Core Web API用户身份验证的方法有很多,本文只介绍JWT方法。JWT实现了服务端无状态,在分布式服务、会话一致性、单点登录等方面凸显优势,不占用服务端资源。简单来说,JWT的验证过程如下所示: &a…...

785. 快速排序

785. 快速排序 给定你一个长度为 n n n 的整数数列。 请你使用快速排序对这个数列按照从小到大进行排序。 并将排好序的数列按顺序输出。 输入格式 输入共两行,第一行包含整数 n n n。 第二行包含 n n n 个整数(所有整数均在 1 ∼ 1 0 9 1 \th…...

C6678学习-IPC

文章目录 1、简介2、模块MultiProc静态设置(cfg设置)动态设置 IPCNotifyMessageQShareRegion 1、简介 IPC: Inter-Processor Communication 处理器间通信,指提供多处理器环境中的处理器之间的通信、相同处理器不同线程间的通信。包括数据传递…...

利用 Delte-Sigma ADC简化电路设计

很多时候在电路中选择合适的 ADC可以很大程度上简化前端的电路。这里我们一起来看一个电阻电桥的例子: 这里用到了一只仪表放大器和一只运算放大器,他们实际上主要完成了三个功能: 1. 抑制了 2.5V的共模信号; 2. 将-1…...

如何在 Windows 11 启用 Hyper-V

准备在本机玩一下k8s,需要先启用 Hyper-V,谁知道这一打开,没有 Hyper-V选项: 1、查看功能截图: 2、以下文件保存记事本,然后重命名为*.bat pushd "%~dp0" dir /b %SystemRoot%\servicing\Packa…...

哈希表企业应用-DNA的字符串检测

DNA的字符串检测-引言 若干年后, ikun DNA 检测部成立,专门对 这些ikun的解析检测 突然发现已经完全控制不了 因为学生已经会了 而且是太会了 所以DNA采用 以下视频测试: ikun必进曲 ikun必经曲 ikun必阶曲 如何感受到了吧!,如果你现在唱跳并且还Rap 还有打篮球 还有铁山靠 那…...

Kafka运维与监控

Kafka运维与监控 Kafka运维与监控一、简介二、运维1.安装和部署安装部署 2.优化参数配置配置文件高级配置分区和副本设置分区数量设置副本数量设置 网络参数调优传输机制设置连接数和缓冲区大小设置 消息压缩和传输设置消息压缩设置消息传输设置 磁盘设置和文件系统分区磁盘容量…...

【Redis—哨兵机制】

文章目录 概念哨兵机制如何工作的监控(如何判断主节点真的故障了)哪个哨兵进行主从故障转移?故障转移流程哨兵集群 概念 当进行主从复制时,如果主节点挂掉了,那么没有主节点来服务客户端的写操作请求了,也…...

MySQL学习笔记第七天

第07章单行函数 2. 数值函数 2.4 指数函数、对数函数 函数用法POW(x,y)&#xff0c;POWER(X,Y)返回x的y次方EXP(X)返回e的x次方&#xff0c;其中e是一个常数&#xff0c;2.718281828459045LN(X)&#xff0c;LOG(X)返回以e为底的X的对数&#xff0c;当x<0时&#xff0c;返…...

中级软件设计师备考---程序设计语言和法律法规知识

目录 需要掌握的程序语言特点法律法规知识---保护期限法律法规知识---知识产权人确定法律法规知识---侵权判定标准化基础知识 需要掌握的程序语言特点 Fortran语言&#xff1a;科学计算、执行效率高Pascal语言&#xff1a;为教学而开发的、表达能力强&#xff0c;演化出了Delp…...

Leetcode434. 字符串中的单词数

Every day a leetcode 题目来源&#xff1a;434. 字符串中的单词数 解法1&#xff1a;istringstream 我们知道&#xff0c;C默认通过空格&#xff08;或回车&#xff09;来分割字符串输入&#xff0c;即区分不同的字符串输入。 istringstream类用于执行C风格的串流的输入操…...

C++ cmake工程引入qt6和Quick 教程

目录标题 前言QML简介锻炼C水平 cmake修改方法方式一&#xff08;qt6_add_resources&#xff09;方式二 (qt_add_qml_module ) 其他相关知识为什么会有_other_files&#xff1f;qt_standard_project_setup() 函数qt_add_qml_module() 和 qt6_add_resources()的方式差异const QU…...

JavaEE - 网络编程

一、网络编程基础 为什么需要网络编程&#xff1f; 用户在浏览器中&#xff0c;打开在线视频网站&#xff0c;如优酷看视频&#xff0c;实质是通过网络&#xff0c;获取到网络上的一个视频资源。 与本地打开视频文件类似&#xff0c;只是视频文件这个资源的来源是网络。 相比本…...

【Android车载系列】第11章 系统服务-SystemServer自定义服务

1 编写自定义系统服务 1.1 AIDL接口定义 系统源码目录/frameworks/base/core/java/android/app/下新建AIDL接口IYvanManager.aidl package android.app;/** * 目录&#xff1a;/frameworks/base/core/java/android/app/IYvanManager.aidl */ interface IYvanManager{String …...

Lerna

Lerna Lerna是一个优化基于gitnpm的多pagkage项目的管理工具 解决的痛点 痛点一:重复操作 多Package本地link多Package依赖安装多Package单元测试多Package代码提交多Package代码发布 痛点二:版本一致性 发布时版本一 致性发布后相互依赖版本升级 package越多&#xff0c;管…...

迁移学习 pytorch

迁移学习(Transfer Learning)是通过使用一个预训练模型来快速训练一个新的网络模型,通常应用于数据集较小或计算资源较少的情况下。在 PyTorch 中,由于 torchvision 库中已经内置了一些经典的预训练模型,因此我们可以通过简单的调用函数来实现迁移学习。 下面是一个基于 …...

【python】keras包:深度学习( RNN循环神经网络 Recurrent Neural Networks)

RNN循环神经网络 应用&#xff1a; 物体移动位置预测、股价预测、序列文本生成、语言翻译、从语句中自动识别人名、 问题总结 这类问题&#xff0c;都需要通过历史数据&#xff0c;对未来数据进行预判 序列模型 两大特点 输入&#xff08;输出&#xff09;元素具有顺序关系…...

vue框架快速入门

vue 1、第一个Vue程序1.1、什么是Vue程序1.2、为什么要使用MVVM1.3、Vue1.4、第一个vue程序 2、基础语法2.1、v-bind2.2、v-if&#xff0c; v-else2.3、v-for2.4、v-on 3、Vue表单双绑、组件3.1、什么是双向数据绑定3.2、在表单中使用双向数据绑定3.3、什么是组件 4、Axios异步…...

Java连接顺丰开放平台

今天使用Java去访问顺丰的开放平台时&#xff0c;JSON转换一直不成功&#xff0c;最终发现是 可以看到这里是 "apiResultData": "{\"success\": .........它是以 " 开头的&#xff01;&#xff01;&#xff01;如果是对象的话&#xff0c;那么…...

前端三剑客 - HTML

前言 前面都是一些基础的铺垫&#xff0c;现在就正式进入到web开发环节了。 我们的目标就是通过学习 JavaEE初阶&#xff0c;搭建出一个网站出来。 一个网站分成两个部分&#xff1a; 前端&#xff08;客户端&#xff09; 后端&#xff08;服务器&#xff09; 通常这里的客户端…...

Qwen2.5-VL-7B-Instruct本地部署指南:ClawdBot实现

Qwen2.5-VL-7B-Instruct本地部署指南&#xff1a;ClawdBot实现 1. 引言 想不想在本地电脑上搭建一个能看懂图片、理解视频的AI助手&#xff1f;今天咱们就来聊聊怎么把Qwen2.5-VL-7B-Instruct这个强大的视觉语言模型部署到本地环境&#xff0c;并且集成到ClawdBot中。 这个模…...

nuScenes多传感器融合:毫米波雷达点云与图像时空对齐实战

1. 多传感器融合的核心挑战 自动驾驶系统就像一位全天候工作的司机&#xff0c;需要同时处理来自不同"感官"的信息。毫米波雷达擅长测距和测速&#xff0c;摄像头则能识别颜色和纹理&#xff0c;但要让它们像人类感官一样协同工作&#xff0c;首先要解决时空对齐的问…...

Phi-3-mini-4k-instruct-gguf多场景落地:客服话术优化、会议纪要提炼、周报生成实战

Phi-3-mini-4k-instruct-gguf多场景落地&#xff1a;客服话术优化、会议纪要提炼、周报生成实战 1. 轻量级文本生成利器介绍 Phi-3-mini-4k-instruct-gguf是微软推出的轻量级文本生成模型&#xff0c;特别适合处理日常办公场景中的文本任务。这个模型体积小巧但能力出众&…...

Windows自定义部署神器:从零开始的安装介质制作指南

Windows自定义部署神器&#xff1a;从零开始的安装介质制作指南 【免费下载链接】MediaCreationTool.bat Universal MCT wrapper script for all Windows 10/11 versions from 1507 to 21H2! 项目地址: https://gitcode.com/gh_mirrors/me/MediaCreationTool.bat 你是否…...

Bootstrap 下拉菜单:全面解析与应用指南

Bootstrap 下拉菜单&#xff1a;全面解析与应用指南 引言 Bootstrap 是一个流行的前端框架&#xff0c;它提供了丰富的组件和工具来帮助开发者快速构建响应式、美观的网页。其中&#xff0c;下拉菜单是 Bootstrap 中一个常用且重要的组件&#xff0c;它能够帮助用户在有限的空间…...

5步释放Win11潜能:用Win11Debloat让系统性能提升60%的实战指南

5步释放Win11潜能&#xff1a;用Win11Debloat让系统性能提升60%的实战指南 【免费下载链接】Win11Debloat A simple, lightweight PowerShell script that allows you to remove pre-installed apps, disable telemetry, as well as perform various other changes to declutte…...

在树莓派4B上编译运行Speedtest-CLI:手把手解决curl和expat库的交叉编译难题

树莓派4B实战&#xff1a;从零构建Speedtest-CLI测速工具全流程指南 1. 环境准备与工具链配置 在树莓派4B上构建Speedtest-CLI测速工具&#xff0c;首先需要搭建完整的交叉编译环境。不同于x86平台的直接编译&#xff0c;ARM架构下的开发需要特别注意工具链的选择和配置。 必备…...

基于cv_unet_image-colorization的Python爬虫实战:自动化图像数据集着色

基于cv_unet_image-colorization的Python爬虫实战&#xff1a;自动化图像数据集着色 为计算机视觉项目快速构建高质量的彩色图像数据集 在计算机视觉项目中&#xff0c;获取高质量的标注数据集往往是最耗时耗力的环节。特别是当我们需要大量彩色图像数据时&#xff0c;手动收集…...

别让import.*拖慢你的Spring Boot项目!IDEA优化导入配置详解

别让import.*拖慢你的Spring Boot项目&#xff01;IDEA优化导入配置详解 在微服务架构盛行的今天&#xff0c;Spring Boot项目的启动速度已经成为开发者关注的焦点。一个常见的性能陷阱就隐藏在那些看似无害的import.*语句中——它们会强制JVM加载整个包的类&#xff0c;即使你…...

LeetCode 11. Container With Most Water 题解

LeetCode 11. Container With Most Water 题解 题目描述 给你 n 个非负整数 a1&#xff0c;a2&#xff0c;...&#xff0c;an&#xff0c;每个数代表坐标中的一个点 (i, ai) 。在坐标内画 n 条垂直线&#xff0c;垂直线 i 的两个端点分别为 (i, ai) 和 (i, 0) 。找出其中的两条…...