.NET Core的JWT认证的学习
程序员文章站
2023-11-14 09:38:16
今天学习下JWT,遇到了两个坑爹问题,这里记录下。在 ASP.NET Core 中,授权的设置方式有两种,可以使用角色,也可以使用策略,这里也将简单举例角色、策略的使用。 JWT这里不做介绍,如果想了解更多,请看https://www.jianshu.com/p/a12fc67c9e05,https ......
今天学习下jwt,遇到了两个坑爹问题,这里记录下。在 asp.net core 中,授权的设置方式有两种,可以使用角色,也可以使用策略,这里也将简单举例角色、策略的使用。
jwt这里不做介绍,如果想了解更多,请看https://www.jianshu.com/p/a12fc67c9e05,https://www.cnblogs.com/createmyself/p/11123023.html ,这两篇都讲解的很好,这里只写实际的使用和遇到的问题。
1. jwt的secretkey必须16位以上
jwt中key必须16位以上,否则长度不够会抛出异常,异常代码如下
system.argumentoutofrangeexception hresult=0x80131502 message=idx10603: decryption failed. keys tried: '[pii is hidden. for more details, see https://aka.ms/identitymodel/pii.]'. exceptions caught: '[pii is hidden. for more details, see https://aka.ms/identitymodel/pii.]'. token: '[pii is hidden. for more details, see https://aka.ms/identitymodel/pii.]' source=microsoft.identitymodel.tokens stacktrace: at microsoft.identitymodel.tokens.symmetricsignatureprovider..ctor(securitykey key, string algorithm, boolean willcreatesignatures) ....................
2.获取token之后,一直401unauthorized
在startup.cs中的configure中添加app.useauthentication();新创建.net core项目的时候,会自动添加授权app.useauthorization();但是jwt其实是一种认证,准确;来说是登录的过程,需要用户名和密码的认证。
例如:你要登陆论坛,输入用户名张三,密码1234,密码正确,证明你张三确实是张三,这就是 认证authentication;那么是否有删除添加等的操作,这就是授权authorization
3.jwttoken的获取
//appsettings.json中增加配置信息 "jwtsettings": { "issuer": "https://localhost:44378/", "audience": "https://localhost:44378/", "secretkey": "1234567890123456" }
// startup.cs中增加jwt的设置 services.addauthentication(options => { //认证middleware配置 options.defaultauthenticatescheme = jwtbearerdefaults.authenticationscheme; options.defaultchallengescheme = jwtbearerdefaults.authenticationscheme; }) .addjwtbearer(o => { //主要是jwt token参数设置 o.tokenvalidationparameters = new tokenvalidationparameters { //token颁发机构 validissuer = jwtsettings.issuer, //颁发给谁 validaudience = jwtsettings.audience, //这里的key要进行加密,需要引用microsoft.identitymodel.tokens issuersigningkey = new symmetricsecuritykey(encoding.utf8.getbytes(jwtsettings.secretkey)), validateissuersigningkey = true, //是否验证token有效期,使用当前时间与token的claims中的notbefore和expires对比 validatelifetime = true, //允许的服务器时间偏移量 clockskew = timespan.zero }; });
// controller中获取token [httppost] public iactionresult token(loginmodel login) { _logger.loginformation($"获取token:user:{login.user}"); if (string.isnullorempty(login.user) || string.isnullorempty(login.password))//判断账号密码是否正确 { return badrequest(); } var claim = new list<claim>{ new claim(claimtypes.name,login.user), new claim(claimtypes.role,"test") }; //建立增加策略的授权 if (login.user == "test") claim.add(new claim("test", "test")); if (login.user == "test1") claim.add(new claim("test", "test1")); if (login.user == "test2") claim.add(new claim("test", "test2")); if (login.user == "test3") claim.add(new claim("test", "test3")); //对称秘钥 var key = new symmetricsecuritykey(encoding.utf8.getbytes(_jwtsettings.secretkey)); //签名证书(秘钥,加密算法) var creds = new signingcredentials(key, securityalgorithms.hmacsha256); //生成token [注意]需要nuget添加microsoft.aspnetcore.authentication.jwtbearer包,并引用system.identitymodel.tokens.jwt命名空间 var token = new jwtsecuritytoken(_jwtsettings.issuer, _jwtsettings.audience, claim, datetime.now, datetime.now.addminutes(30), creds); return ok(new { token = new jwtsecuritytokenhandler().writetoken(token) }); }
4.基于角色的授权
[httpget] [authorize(roles ="test")] public actionresult<string> authvalue() { var name = user.findfirst(claimtypes.name)?.value; var role = user.findfirst(claimtypes.role)?.value; _logger.loginformation($"权限登录,用户名:{name},角色:{role}"); return $"权限登录,用户名:{name},角色:{role}"; }
roles角色如果有多个,可以以逗号隔开。
5.基于策略的授权
//startup.cs中添加策略
services.addauthorization(options => { options.addpolicy("onlytestaccess", policy => policy.requireclaim("test", new string[] { "test1", "test2" })); options.addpolicy("departmentaccess", policy => policy.requireclaim("department")); });
// 方法上增加策略
[httpget] [authorize(policy = "onlytestaccess")] public actionresult<string> authextensionvalue() { var name = user.findfirst(claimtypes.name)?.value; var role = user.findfirst(claimtypes.role)?.value; _logger.loginformation($"基于策略的登录,用户名:{name},角色:{role}"); return $"基于策略的登录,用户名:{name},角色:{role}"; }
6.运行的截图
7.github上的源码
https://github.com/jasonhua95/samll-project/tree/master/jwtapidemo
推荐阅读
-
从零开始搭建前后端分离的NetCore2.2(EF Core CodeFirst+Autofac)+Vue的项目框架之七使用JWT生成Token(个人见解)
-
Docker中如何调试剖析.net core 的程序。
-
张高兴的 .NET Core IoT 入门指南:(五)串口通信入门
-
Asp.net Core MVC中怎么把二级域名绑定到特定的控制器上
-
Mbp,一个用于学习.net core的开发框架
-
Asp.Net Core中服务的生命周期选项区别与用法详解
-
建议收藏备用:.net core使用QRCoder生成普通二维码和带Logo的二维码详细使用教程,源码已更新至开源模板
-
.NET Core的JWT认证的学习
-
三分钟学会.NET Core Jwt 策略授权认证
-
asp.net core 自定义基于 HttpContext 的 Serilog Enricher