.NET6之MiniAPI:基于角色的身份验证和授权
Posted dotNET跨平台
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了.NET6之MiniAPI:基于角色的身份验证和授权相关的知识,希望对你有一定的参考价值。
身份验证是这样一个过程:由用户提供凭据,然后将其与存储在操作系统、数据库、应用或资源中的凭据进行比较。 在授权过程中,如果凭据匹配,则用户身份验证成功,可执行已向其授权的操作。 授权指判断允许用户执行的操作的过程。也可以将身份验证理解为进入空间(例如服务器、数据库、应用或资源)的一种方式,而授权是用户可以对该空间(服务器、数据库或应用)内的哪些对象执行哪些操作。
微软官方文档
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
//获取Token
public 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:基于角色的身份验证和授权的主要内容,如果未能解决你的问题,请参考以下文章
.NET7之MiniAPI(特别篇) :Preview5优化了JWT验证(下)
.NET6之MiniAPI(二十):实体验证FluentValidation