今天学习下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": ""
}
// 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(), 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

 

.NET Core的JWT认证的学习的更多相关文章

  1. Asp.Net Core基于JWT认证的数据接口网关Demo

    近日,应一位朋友的邀请写了个Asp.Net Core基于JWT认证的数据接口网关Demo.朋友自己开了个公司,接到的一个升级项目,客户要求用Aps.Net Core做数据网关服务且基于JWT认证实现对 ...

  2. Dotnet core使用JWT认证授权最佳实践(二)

    最近,团队的小伙伴们在做项目时,需要用到JWT认证.遂根据自己的经验,整理成了这篇文章,用来帮助理清JWT认证的原理和代码编写操作. 第一部分:Dotnet core使用JWT认证授权最佳实践(一) ...

  3. Dotnet core使用JWT认证授权最佳实践(一)

    最近,团队的小伙伴们在做项目时,需要用到JWT认证.遂根据自己的经验,整理成了这篇文章,用来帮助理清JWT认证的原理和代码编写操作. 一.JWT JSON Web Token (JWT)是一个开放标准 ...

  4. 把旧系统迁移到.Net Core 2.0 日记 (18) --JWT 认证(Json Web Token)

    我们最常用的认证系统是Cookie认证,通常用一般需要人工登录的系统,用户访问授权范围的url时,会自动Redirect到Account/Login,登录后把认证结果存在cookie里. 系统只要找到 ...

  5. 10分钟简单学习net core集成jwt权限认证,快速接入项目落地使用

    什么是JWT JSON Web Token(JWT)是目前最流行的跨域身份验证.分布式登录.单点登录等解决方案. JWT的官网地址:https://jwt.io/ 通俗地来讲,JWT是能代表用户身份的 ...

  6. 【ASP.NET Core学习】使用JWT认证授权

    概述 认证授权是很多系统的基本功能 , 在以前PC的时代 , 通常是基于cookies-session这样的方式实现认证授权 , 在那个时候通常系统的用户量都不会很大, 所以这种方式也一直很好运行, ...

  7. .net core webapi jwt 更为清爽的认证

    原文:.net core webapi jwt 更为清爽的认证 我的方式非主流,控制却可以更加灵活,喜欢的朋友,不妨花一点时间学习一下 jwt认证分为两部分,第一部分是加密解密,第二部分是灵活的应用于 ...

  8. sau交流学习社区--songEagle开发系列:Vue.js + Koa.js项目中使用JWT认证

    一.前言 JWT(JSON Web Token),是为了在网络环境间传递声明而执行的一种基于JSON的开放标准(RFC 7519). JWT不是一个新鲜的东西,网上相关的介绍已经非常多了.不是很了解的 ...

  9. ASP.NET Core 基于JWT的认证(二)

    ASP.NET Core 基于JWT的认证(二) 上一节我们对 Jwt 的一些基础知识进行了一个简单的介绍,这一节我们将详细的讲解,本次我们将详细的介绍一下 Jwt在 .Net Core 上的实际运用 ...

随机推荐

  1. 【Luogu P1631】序列合并

    Luogu P1631 题意很好懂,不作分析 很容易想出一个解法是求出每一个和,排序后取前n个. 当然这种做法妥妥的会MLE+TLE 我们会发现实质上这种做法的缺点在于存入了大量不需要的数据. 那么该 ...

  2. day 33 线程锁

    Python的GIL锁 - Python内置的一个全局解释器锁,锁的作用就是保证同一时刻一个进程中只有一个线程可以被cpu调度. 为什么有这把GIL锁? 答:Python语言的创始人在开发这门语言时, ...

  3. ctf中关于图片的隐写随笔(不全)

    ①JPG图片的结束符,十六进制常为FFD9 ②binwalk的原理是:检查常见的文件头信息,如果不符合,一定有隐藏信息.③JPG是有损压缩,PNG是无损压缩,BMP是不压缩. 隐写的基本原理:图片查看 ...

  4. 剑指Offer-32.丑数(C++/Java)

    题目: 把只包含质因子2.3和5的数称作丑数(Ugly Number).例如6.8都是丑数,但14不是,因为它包含质因子7. 习惯上我们把1当做是第一个丑数.求按从小到大的顺序的第N个丑数. 分析: ...

  5. 查找节点(getAttribute())

    getAttribute():方法将返回一个给定元素的一个给定属性节点的值: attributeValue = element.getAttribute(attributeName); 给定属性的名字 ...

  6. 设置属性节点(setAttribute())

    setAttribute():方法将为给定元素节点添加一个新的属性值或是改变它的现有属性值: element.setAttribute(attriibuteName,attributeValue); ...

  7. RestTemplate 中文乱码

    @Configuration public class RestTemplateWithoutLoadBalance { @Bean("normalRestTemplate") p ...

  8. Netty学习——Google Protobuf的初步了解

    学习参考的官网: https://developers.google.com/protocol-buffers/docs/javatutorial 简单指南详解:这个文档写的简直是太详细了. 本篇从下 ...

  9. hello gulp,使用gulp的第一天。

    昨天花了一天的时间,学习了一下gulp,今天整理一下,也分享给朋友们. 首先当然是去gulp的官网逛一圈了: http://gulpjs.com/ 中文站地址: http://www.gulpjs.c ...

  10. Lua的面向对象,封装,继承,多态

    概述 我们总所周知对象是由属性和方法组成的,要用lua要描述一个对象,也必然要有这两个特性,属性和方法.lua的基本结构是table,所以Lua的类,其实都是table,因为它可以存储普通的变量又可以 ...