身份验证是这样一个过程:由用户提供凭据,然后将其与存储在操作系统、数据库、应用或资源中的凭据进行比较。 在授权过程中,如果凭据匹配,则用户身份验证成功,可执行已向其授权的操作。 授权指判断允许用户执行的操作的过程。也可以将身份验证理解为进入空间(例如服务器、数据库、应用或资源)的一种方式,而授权是用户可以对该空间(服务器、数据库或应用)内的哪些对象执行哪些操作。

微软官方文档

asp.net core支持多种授权,本篇重点说明JWT的基于角色授权方式。

基于JWT角色身份验证和授权,思路是在登录时分发加密的Token,在访问资源时带有这个Token,服务端要验证这个Token是不是自己分发的,如果是,再验证访问范围是否正确,本篇的范围就是那些资源是那种角色访问,得到Token的用户当前是那种角色,也就是角色和资源的匹配。

用asp.net core实现步骤:

1、appsettings.json中配置JWT参

2、添加身份认证和授权服务和中间件

3、定义生成Token的方法和验证Toekn参数的方法

4、登录时验证身份并分发Toekn

using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity;
using Microsoft.IdentityModel.Tokens;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;var builder = WebApplication.CreateBuilder();
//获取JWT参数,并注入到服务容器
var jwtConfig = new JWTConfig();
builder.Configuration.GetSection("JWTConfig").Bind(jwtConfig);
builder.Services.AddSingleton(jwtConfig);
//添加JJWT方式的身份认证和授权,
builder.Services.AddAuthorization().AddAuthentication(options =>{options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;}).AddJwtBearer(JwtBearerDefaults.AuthenticationScheme, opt =>{opt.RequireHttpsMetadata = false;opt.TokenValidationParameters = JwtToken.CreateTokenValidationParameters(jwtConfig);});var app = builder.Build();
//使用身份认证和授权的中间件
app.UseAuthentication();
app.UseAuthorization();app.MapGet("/hellosystem", (ILogger<Program> logger, HttpContext context) =>
{var message = $"hello,system,{context.User?.Identity?.Name}";logger.LogInformation(message);return message;
}).RequireAuthorization(new RoleData { Roles = "system" });app.MapGet("/helloadmin", (ILogger<Program> logger, HttpContext context) =>
{var message = $"hello,admin,{context.User?.Identity?.Name}";logger.LogInformation(message);return message;
}).RequireAuthorization(new RoleData { Roles = "admin" });app.MapGet("/helloall", (ILogger<Program> logger, HttpContext context) =>
{var message = $"hello,all roles,{context.User?.Identity?.Name}";logger.LogInformation(message);return message;
}).RequireAuthorization(new RoleData { Roles = "admin,system" });//登录成功,并分发Token
app.MapPost("/login", [AllowAnonymous] (ILogger<Program> logger, LoginModel login, JWTConfig jwtConfig) =>
{logger.LogInformation("login");if (login.UserName == "gsw" && login.Password == "111111"){var now = DateTime.UtcNow;var claims = new Claim[] {new Claim(ClaimTypes.Role, "admin"),new Claim(ClaimTypes.Name, "桂素伟"),new Claim(ClaimTypes.Sid, login.UserName),new Claim(ClaimTypes.Expiration, now.AddSeconds(jwtConfig.Expires).ToString())};var token = JwtToken.BuildJwtToken(claims, jwtConfig);return token;}else{return "username or password is error";}
});app.Run();
//登录实体
public class LoginModel
{public string? UserName { get; set; }public string? Password { get; set; }
}
//JWT配置
public class JWTConfig
{public string? Secret { get; set; }public string? Issuer { get; set; }public string? Audience { get; set; }public int Expires { get; set; }
}
//JWT操作类型
public class JwtToken
{//获取Tokenpublic static dynamic BuildJwtToken(Claim[] claims, JWTConfig jwtConfig){var now = DateTime.UtcNow;var jwt = new JwtSecurityToken(issuer: jwtConfig.Issuer,audience: jwtConfig.Audience,claims: claims,notBefore: now,expires: now.AddSeconds(jwtConfig.Expires),signingCredentials: GetSigningCredentials(jwtConfig));var encodedJwt = new JwtSecurityTokenHandler().WriteToken(jwt);var response = new{Status = true,AccessToken = encodedJwt,ExpiresIn = now.AddSeconds(jwtConfig.Expires),TokenType = "Bearer"};return response;}static SigningCredentials GetSigningCredentials(JWTConfig jwtConfig){var keyByteArray = Encoding.ASCII.GetBytes(jwtConfig?.Secret!);var signingKey = new SymmetricSecurityKey(keyByteArray);return new SigningCredentials(signingKey, SecurityAlgorithms.HmacSha256);}//验证Token的参数public static TokenValidationParameters CreateTokenValidationParameters(JWTConfig jwtConfig){var keyByteArray = Encoding.ASCII.GetBytes(jwtConfig?.Secret!);var signingKey = new SymmetricSecurityKey(keyByteArray);return new TokenValidationParameters{ValidateIssuerSigningKey = true,IssuerSigningKey = signingKey,ValidateIssuer = true,ValidIssuer = jwtConfig?.Issuer,ValidateAudience = true,ValidAudience = jwtConfig?.Audience,ClockSkew = TimeSpan.Zero,RequireExpirationTime = true,};}
}
//mini api添加验证授权的参数类型
public class RoleData : IAuthorizeData
{public string? Policy { get; set; }public string? Roles { get; set; }public string? AuthenticationSchemes { get; set; }
}

验证结果:

1、没有登录,返回401

2、登录,取token

3、正确访问

4、没有授权访问,返回403

.NET6之MiniAPI(九):基于角色的身份验证和授权相关推荐

  1. .NET6之MiniAPI(十):基于策略的身份验证和授权

    JWT不管是基于角色,还是自定义策略,实现的步骤都是大同小异的,基于自定义策略的步骤如下: 1.appsettings.json中配置JWT参 2.添加身份认证和授权服务和中间件,并设置为策略模式和策 ...

  2. 用户数据表设计借鉴 浅谈数据库用户表结构设计,第三方登录 基于 Token 的身份验证

    最近对用户数据表的设计比较感兴趣,看到了两篇比较好的文章. 浅谈数据库用户表结构设计,第三方登录 转载于: https://www.cnblogs.com/jiqing9006/p/5937733.h ...

  3. PHP无状态对象,(PHP)基于Token的身份验证中对无状态的理解

    假设我们设计的Token储存的信息为: 用户名.发行时间.过期时间.签名 在用户登录成功后,我们获取到用户的用户名.此时的时间戳,并将它们和我们设置的过期时间拼接在一起,组成一个字符串,假设为: $i ...

  4. 基于 Token 的身份验证:JSON Web Token

    最近了解下基于 Token 的身份验证,跟大伙分享下.很多大型网站也都在用,比如 Facebook,Twitter,Google+,Github 等等, 比起传统的身份验证方法,Token 扩展性更强 ...

  5. 基于Token进行身份验证

    1.基于服务器的验证 我们都是知道HTTP协议是无状态的,这种无状态意味着程序需要验证每一次请求,从而辨别客户端的身份.  在这之前,程序都是通过在服务端存储的登录信息来辨别请求的.这种方式一般都是通 ...

  6. 基于 Token 的身份验证方法

    基于 Token 的身份验证方法 使用基于 Token 的身份验证方法,在服务端不需要存储用户的登录记录.大概的流程是这样的:客户端使用用户名跟密码请求登录 服务端收到请求,去验证用户名与密码 验证成 ...

  7. 【转】基于Token的身份验证原理

    目录 1 发展史 2 Cookie 3 Session 3.1 cookie和session的区别 4 Token 4.1 传统方式--基于服务器的验证 4.2 基于服务器验证方式暴露的一些问题 4. ...

  8. 基于Token的身份验证——JWT

    原文:基于Token的身份验证--JWT 初次了解JWT,很基础,高手勿喷. 基于Token的身份验证用来替代传统的cookie+session身份验证方法中的session. JWT是啥? JWT就 ...

  9. node实现基于token的身份验证

    最近研究了下基于token的身份验证,并将这种机制整合在个人项目中.现在很多网站的认证方式都从传统的seesion+cookie转向token校验.对比传统的校验方式,token确实有更好的扩展性与安 ...

最新文章

  1. 2010-07-18 项目重构计划
  2. 结构体的嵌套 自身嵌套 相互嵌套
  3. Py之imblearn:imblearn/imbalanced-learn库的简介、安装、使用方法之详细攻略
  4. 3DSlicer33:Adding MRML
  5. android学习笔记53——自动朗读TTS
  6. 【CLRS】《算法导论》读书笔记(一):堆排序(Heapsort)
  7. Python装饰器学习笔记 1
  8. linux上创建RAID(磁盘阵列)与LVM(逻辑盘)
  9. Huffuman树(java)
  10. jdk线程的同步问题
  11. CF1067E Random Forest Rank
  12. oracle获取当前年上一年时间,Oracle获取一年中的所有日期和一个月中的所有日期...
  13. php中文件读写总结,PHP读取文件_2014.5.26的总结
  14. mysql源代码多少行_数据库是一个庞大的工程,本来想读读mysql的开源代码,可看到代码行数.doc...
  15. itools 苹果录屏大师 java_AirPlayer电脑版(itools苹果录屏大师)下载|AirPlayer电脑免费版...
  16. 多因子量化投资模型策略深度研究
  17. 网络爬虫基础-scrapy框架
  18. 分享从零开始学习网络设备配置--2.1 交换机基本配置
  19. SQL分组排序再取前N条记录
  20. 【学习记录】使用多协程和队列,爬取时光网电视剧TOP100的数据

热门文章

  1. adb devices 里面有很多 emulator-XXXX的解决方法
  2. eclise配置tomcat出现服务Tomcat version 6.0 only supports J2EE 1.2, 1.3, 1.4 and Java EE 5 Web modules...
  3. 如何识别是三层交换机还是二层交换机
  4. 将权限授予文件夹和程序集
  5. go run 和 go build 和 go install 命令区别
  6. 各主流浏览器内核介绍
  7. OPCServer Modbus使用和配置
  8. WindowsPhone8可缩放图片控件的实现
  9. 达内TTS6.0课件oop_day01
  10. Linux 下 MySQL 启动与关闭 说明