前言

学习ASP.NETCore,原链接

https://www.cnblogs.com/laozhang-is-phi/p/9511869.html

原教程是Core2.2,后期也升级到了Core3.0,但是文章中和GitHub的代码感觉有些乱,一直对应不上,

我创建的项目是Core3.0,而在Swagger中使用JWT一直访问401,此处做个笔记,供以后学习时查看。

参考博文,原链接

https://www.cnblogs.com/CreateMyself/p/11123023.html

步骤

默认映射方式给移除掉

  1. JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();

Swagger响应头

这里需要Nuget引用Swashbuckle.AspNetCore.Filters,oauth2需要写死,SecurityRequirementsOperationFilter中默认securitySchemaName="oauth2";

未添加该配置时,Bearer一直无法加入到JWT发起的Http请求的头部,无论怎么请求都会是401;

用Postman在Authorization添加了Bearer,就会正常响应,

  1. #region Token绑定到ConfigureServices
  2. // 在header中添加token,传递到后台
  3. c.OperationFilter<SecurityRequirementsOperationFilter>();
  4.  
  5. c.AddSecurityDefinition("oauth2", new OpenApiSecurityScheme
  6. {
  7. Description = "JWT授权(数据将在请求头中进行传输) 直接在下框中输入Bearer {token}(注意两者之间是一个空格)\"",
  8. Name = "Authorization",//jwt默认的参数名称
  9. In = ParameterLocation.Header,//jwt默认存放Authorization信息的位置(请求头中)
  10. Type = SecuritySchemeType.ApiKey
  11. });
  12. #endregion

启用权限授权认证服务

  1. //JWT服务配置
  2. //读取配置文件
  3. var audienceConfig = Configuration.GetSection("Audience");
  4. var symmetricKeyAsBase64 = audienceConfig["Secret"];
  5.  
  6. services.AddAuthentication(x =>
  7. {
  8. x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
  9. x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
  10. })
  11. .AddJwtBearer(o =>
  12. {
  13. o.TokenValidationParameters = new TokenValidationParameters
  14. {
  15. ValidateIssuerSigningKey = true,
  16. IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(symmetricKeyAsBase64)),//参数配置在下边
  17.  
  18. ValidateIssuer = true,
  19. ValidIssuer = audienceConfig["Issuer"],//发行人
  20.  
  21. ValidateAudience = true,
  22. ValidAudience = audienceConfig["Audience"],//订阅人
  23.  
  24. ValidateLifetime = true,
  25.  
  26. //ClockSkew = TimeSpan.Zero,//这个是缓冲过期时间,也就是说,即使我们配置了过期时间,这里也要考虑进去,过期时间+缓冲,默认好像是7分钟,你可以直接设置为0
  27. ClockSkew = TimeSpan.Zero,
  28.  
  29. RequireExpirationTime = true,
  30. };
  31. });

Configure配置

这里的顺序,必须严格遵守

  1. public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
  2. {
  3. if (env.IsDevelopment())
  4. {
  5. app.UseDeveloperExceptionPage();
  6. }
  7.  
  8. app.UseRouting();
  9.  
  10. //启用认证中间件,
  11. app.UseAuthentication();
  12. //启用授权中间件,
  13. app.UseAuthorization();
  14.  
  15. #region swagger
  16. // Enable middleware to serve generated Swagger as a JSON endpoint.
  17. app.UseSwagger();
  18.  
  19. // Enable middleware to serve swagger-ui (HTML, JS, CSS, etc.),
  20. // specifying the Swagger JSON endpoint.
  21. app.UseSwaggerUI(c =>
  22. {
  23. c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1");
  24. });
  25. #endregion
  26.  
  27. app.UseEndpoints(endpoints =>
  28. {
  29. //endpoints.MapControllers();
  30.  
  31. endpoints.MapControllerRoute(
  32. name: "default",
  33. pattern: "{controller=Home}/{action=Index}/{id?}");
  34. });
  35. }

授权方法

这里的区别,jwt对象,多加了audience和expires属性。

audience:就是配置的值,

expires:JWT过期时间,经过测试,JWT过期时间=expires + ClockSkew。并不是claims中的JwtRegisteredClaimNames.Exp去控制的过期时间

  1. public static string IssueJWT(TokenModel tokenModel, TimeSpan expiresSliding, TimeSpan expiresAbsoulte)
  2. {
  3. var Issuer = "Blog.Core";
  4. var Audience = "wr";
  5. var Secret = "sdfsdfsrty45634kkhllghtdgdfss345t678fs";
  6.  
  7. var dateTime = DateTime.UtcNow;
  8.  
  9. var claims = new Claim[]
  10. {
  11. //下边为Claim的默认配置
  12. new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
  13. new Claim(JwtRegisteredClaimNames.Iat, $"{new DateTimeOffset(DateTime.Now).ToUnixTimeSeconds()}"),
  14. new Claim(JwtRegisteredClaimNames.Nbf,$"{new DateTimeOffset(DateTime.Now).ToUnixTimeSeconds()}") ,
  15. //这个就是过期时间,目前是过期100秒,可自定义,注意JWT有自己的缓冲过期时间
  16. new Claim (JwtRegisteredClaimNames.Exp,$"{new DateTimeOffset(DateTime.Now.AddSeconds(180)).ToUnixTimeSeconds()}"),
  17. new Claim(JwtRegisteredClaimNames.Iss,Issuer),
  18. new Claim(JwtRegisteredClaimNames.Aud,Audience),
  19. //这个Role是官方UseAuthentication要要验证的Role,我们就不用手动设置Role这个属性了
  20. new Claim(ClaimTypes.Role,tokenModel.Role),
  21. new Claim(ClaimTypes.Name, tokenModel.Uname),
  22. new Claim(JwtRegisteredClaimNames.Email, tokenModel.EMail),
  23. new Claim(JwtRegisteredClaimNames.Sub,tokenModel.Sub),
  24. };
  25.  
  26. //秘钥
  27. var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Secret));
  28.  
  29. var jwt = new JwtSecurityToken(
  30. issuer: Issuer,
  31. audience: Audience,
  32. claims: claims,
  33. expires: DateTime.Now.AddMinutes(1),
  34. signingCredentials: new SigningCredentials(key, SecurityAlgorithms.HmacSha256)
  35. );
  36. var encodedJwt = new JwtSecurityTokenHandler().WriteToken(jwt);
  37.  
  38. return encodedJwt;
  39. }

appsetting.json

  1. "Audience": {
  2. "Secret": "sdfsdfsrty45634kkhllghtdgdfss345t678fs", //不要太短,16位+
  3. "SecretFile": "C:\\my-file\\blog.core.audience.secret.txt", //安全。内容就是Secret
  4. "Issuer": "Blog.Core",
  5. "Audience": "wr"
  6. }

Postman测试

Authorization => Bearer Token => Token,这里输入登录时生成的Token值,不需要带Bearer 前缀

Postman 示例

Swagger示例

Fiddler监视

Roles配置权限

用户的Role,与访问接口配置的Roles不一致,也就是没有访问权限,访问时会响应为403

总结

调用接口一直401

JWT配置需要验证的东西,

一直401,可能是JWT中未包含上面配置的全部参数

相比较之前,又传递了audience和expires参数,这样访问接口验证必传参数才能通过。

授权

三种方式

(1)基于角色

(2)基于Claim声明

(3)基于自定义的类

目前,前2个都测试通过的,第三个需要配合创建其他的东西,未实现。

  1. services.AddAuthorization(options =>
  2. {
  3. //1.基于角色
  4. options.AddPolicy("Client", policy => policy.RequireRole("Client").Build());
  5. options.AddPolicy("Admin", policy => policy.RequireRole("Admin").Build());
  6. //Client或者Admin
  7. options.AddPolicy("ClientOrAdmin", policy => policy.RequireRole("Client", "Admin").Build());
  8. //Client并且Admin
  9. options.AddPolicy("ClientAndAdmin", policy => policy.RequireRole("Client").RequireRole("Admin").Build());
  10.  
  11. //2.基于声明
  12. options.AddPolicy("AdminClaim2", policy => policy.RequireClaim(ClaimTypes.Name, "Yasuo", "Leesnn").Build());
  13.  
  14. //3.基于需要Requirement
  15. //options.AddPolicy("AdminRequirement", policy => policy.Requirements.Add(new AdminRequirement() { UName = "Kate" }));
  16. });
  1. /// <summary>
  2. /// 获取数据,需要授权
  3. /// </summary>
  4. /// <param name="name"></param>
  5. /// <returns></returns>
  6. [Authorize(Policy = "AdminClaim2")]
  7. [HttpPost("{name}")]
  8. public string PostUser(string name)
  9. {
  10. var sub = User.FindFirst(d => d.Type == "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name")?.Value;
  11.  
  12. name += "---" + sub ?? "";
  13.  
  14. return name + DateTime.Now.ToLongTimeString();
  15. }

Core3.0中Swagger使用JWT的更多相关文章

  1. 在.net core3.0中使用SignalR实现实时通信

    最近用.net core3.0重构网站,老大想做个站内信功能,就是有些耗时的后台任务的结果需要推送给用户.一开始我想简单点,客户端每隔1分钟调用一下我的接口,看看是不是有新消息,有的话就告诉用户有新推 ...

  2. Core3.0使用Swagger接口文档

    前言 此方法为百度搜索结果,原文链接找不到了 步骤 1.引用Nuget Swashbuckle.AspNetCore 2.Startup.cs配置 //注册swagger服务,定义1个或者多个swag ...

  3. ASP.NET Core3.0 中的运行时编译

    运行时编译 通过 Razor 文件的运行时编译补充生成时编译. 当 .cshtml 文件的内容发生更改时,ASP.NET Core MVC 将重新编译 Razor 文件 . 通过 Razor 文件的运 ...

  4. .Net core3.0 集成swagger5.0上传文件

    .Net core 3.0已经更新了,相信有挺多博主大佬们都更新了如何在.Net core3.0使用swagger,这里就不详细说了. 我们知道,如果.net core 2.x使用swagger上传文 ...

  5. asp.net core 2.0 web api基于JWT自定义策略授权

    JWT(json web token)是一种基于json的身份验证机制,流程如下: 通过登录,来获取Token,再在之后每次请求的Header中追加Authorization为Token的凭据,服务端 ...

  6. 兼容 .NET Core3.0, Natasha 框架实现 隔离域与热编译操作

    关于 Natasha    动态构建已经成为了封装者们的家常便饭,从现有的开发趋势来看,普通反射性能之低,会迫使开发者转向EMIT/表达式树等构建方式,但是无论是EMIT还是表达式树,都会依赖于反射的 ...

  7. asp.net core 3.0 中使用 swagger

    asp.net core 3.0 中使用 swagger Intro 上次更新了 asp.net core 3.0 简单的记录了一下 swagger 的使用,那个项目的 api 比较简单,都是匿名接口 ...

  8. .Net Core3.0 WebApi 项目框架搭建 四:JWT权限验证

    .Net Core3.0 WebApi 项目框架搭建:目录 什么是JWT 根据维基百科定义,JWT(读作 [/dʒɒt/]),即JSON Web Tokens,是一种基于JSON的.用于在网络上声明某 ...

  9. .Net Core3.0 WebApi 项目框架搭建 二:API 文档神器 Swagger

    .Net Core3.0 WebApi 项目框架搭建:目录 为什么使用Swagger 随着互联网技术的发展,现在的网站架构基本都由原来的后端渲染,变成了:前端渲染.后端分离的形态,而且前端技术和后端技 ...

随机推荐

  1. 一篇文章彻底搞懂Java的大Class到底是什么

    作者在之前工作中,面试过很多求职者,发现有很多面试者对Java的 Class 搞不明白,理解的不到位,一知半解,一到用的时候,就不太会用. 因为自己本身以前刚学安卓的时候,甚至做安卓2,3年后,也是对 ...

  2. 《我想进大厂》之Spring夺命连环10问

    1.说说Spring 里用到了哪些设计模式? 单例模式:Spring 中的 Bean 默认情况下都是单例的.无需多说. 工厂模式:工厂模式主要是通过 BeanFactory 和 Application ...

  3. 我是如何使计算提速>150倍的

    我是如何使计算提速>150倍的 我的原始文档:https://www.yuque.com/lart/blog/lwgt38 书接上文<我是如何使计算时间提速25.6倍>. 上篇文章提 ...

  4. Day 1-决胜IT十八招-前言

    走资讯这一行转眼间八年多了,从大学的时候,我有长达十年的时间思索在从事软体开發这一行到底怎麽存活下来,这思考下来,为自己总算找到一个出口来,这十八招只是其一的绝学,见阵这一行干软体开發的变化也很大,从 ...

  5. JS 使用xlsx.core.js 数据导出到excel

    /* 通用导出数据 需要引入 xlsx.core.js * data:数据 * th:表头 * filename:导出表格名称 */ var data = []; var th = [ [" ...

  6. C#(一)基础篇—类型与变量

    于今日起学习巩固C#基础 2020-12-01 本随笔用于个人回忆理解,记录当天学习过程,内容多从书中整理与自我学习了解,如有问题麻烦指正 以后有时间会单独分版块叙述 不管什么语言,都从一个Hello ...

  7. Spring Security + JJWT 实现 JWT 认证和授权

    关于 JJWT 的使用,可以参考之前的文章:JJWT 使用示例 一.鉴权过滤器 @Component public class JwtAuthenticationTokenFilter extends ...

  8. 第8.4节 Python类中不是构造方法却胜似构造方法的__new方法__深入剖析:语法释义

    一.    引言 在本博前面的内容都对构造方法__init__进行了介绍,也在前面章节引入了__new__方法,但老猿认为__new__方法比构造方法__init__更应该属于构造方法.这是因为在Py ...

  9. PyQt学习问题:Model/View中中EditKeyPressed常量平台编辑键(the platform edit key )是什么?

    老猿在学习PyQt的Model/View设计时,发现是否允许对视图中的数据项进行编辑的函数setEditTriggers的参数QAbstractItemView.EditTriggers是几个常量的组 ...

  10. PyQt(Python+Qt)学习随笔:窗口对象尺寸调整相关的函数resize、showMaximized、showNormal、showMinimized

    resize(width,height) resize可以直接调整窗口的尺寸,调整效果类似于鼠标直接拉伸或缩小窗口,但窗口大小的最大值.最小值受窗口的sizePolicy.sizeHint.minim ...