.NET Core的JWT认证的学习
程序员文章站
2022-06-20 17:39:20
今天学习下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
上一篇: 吃土豆增肥吗,答案一定跟你想的不一样
推荐阅读
-
【ASP.NET Core】AddMvc和AddMvcCore的区别
-
.NET CORE中比较两个文件内容是否相同的最快方法
-
ASP.NET:一段比较经典的多线程学习代码
-
.net core项目中常用的几款类库详解(值得收藏)
-
关于C#.net winform程序验证moss的集成身份认证实例
-
解决 .NET Core 中 GetHostAddressesAsync 引起的 EnyimMemcached 死锁问题
-
ASP.NET Core应用中与第三方IoC/DI框架的整合
-
值得收藏的asp.net基础学习笔记
-
Linux下部署.net core环境的步骤详解
-
ASP.NET Core发送邮件的方法