Preview5对策略验证的方式没有改变,只不过内置了Token的生成,和《​​.NET6之MiniAPI(十):基于策略的身份验证和授权​​》的验证方式基本相同,都是生成和验证使用的验证参数要一致,用继承AuthorizationHandler的子类来作每次请求的验证。

  在具体的路由上,用RequireAuthorization("Permission")来配置策略名称,以达到请求转向验证。

  不多说了,看代码实现,可以《​​.NET6之MiniAPI(十):基于策略的身份验证和授权​​》作个比较。

using Microsoft.AspNetCore.Authorization;
using Microsoft.IdentityModel.Tokens;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;

var builder = WebApplication.CreateBuilder(args);

#region 添加策略验证参数
builder.Authentication.AddJwtBearer(opt =>
{
opt.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes("1234567890abcdefg")),
ValidateIssuer = true,
ValidIssuer = "http://localhost:5274",
ValidateAudience = true,
ValidAudience = "http://localhost:5274",
ClockSkew = TimeSpan.Zero,
RequireExpirationTime = true,
}; ;
});

//添加策略名和注与策略验证服务
builder.Services
.AddAuthorization(options =>
{
//添加策略名称
options.AddPolicy("Permission", policyBuilder => policyBuilder.AddRequirements(new PermissionRequirement()));
})
.AddSingleton(new List<Permission> { new Permission { RoleName = "admin", Url = "/Policy", Method = "get" } })
.AddSingleton<IAuthorizationHandler, PermissionHandler>();

var app = builder.Build();
//登录,生成token
app.MapGet("/login", () =>
{
//用JWTSecurityTokenHandler生成token
return new JwtSecurityTokenHandler().WriteToken(
new JwtSecurityToken(
issuer: "http://localhost:5274",
audience: "http://localhost:5274",
claims: new Claim[] {
new Claim(ClaimTypes.Role, "admin"),
new Claim(ClaimTypes.Name, "桂素伟")
},
notBefore: DateTime.UtcNow,
expires: DateTime.UtcNow.AddSeconds(500000),
signingCredentials: new SigningCredentials(
new SymmetricSecurityKey(Encoding.ASCII.GetBytes("1234567890abcdefg")),
SecurityAlgorithms.HmacSha256)
)
);
});
app.MapGet("/policy", (ClaimsPrincipal user) => $"Hello 用户:{user.Identity?.Name}, 角色:{user.Claims?.Where(s => s.Type == ClaimTypes.Role).First().Value}. This is a policy!").RequireAuthorization("Permission");
app.Run();


#region 策略验证功能
public class PermissionRequirement : IAuthorizationRequirement
{
}
//权限的实体集合
public class Permission
{
public string? RoleName { get; set; }
public string? Url { get; set; }
public string? Method { get; set; }
}
//权限验证类
public class PermissionHandler : AuthorizationHandler<PermissionRequirement>
{
private readonly List<Permission> _userPermissions;
public PermissionHandler(List<Permission> permissions)
{
_userPermissions = permissions;
}
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, PermissionRequirement requirement)
{
if (context.Resource is DefaultHttpContext)
{
var httpContext = context.Resource as DefaultHttpContext;
var questPath = httpContext?.Request?.Path;
var method = httpContext?.Request?.Method;
var isAuthenticated = context?.User?.Identity?.IsAuthenticated;
if (isAuthenticated.HasValue && isAuthenticated.Value)
{
var role = context?.User?.Claims?.SingleOrDefault(s => s.Type == ClaimTypes.Role)?.Value;
if (_userPermissions.Where(w => w.RoleName == role && w.Method?.ToUpper() == method?.ToUpper() && w.Url?.ToLower() == questPath).Count() > 0)
{
context?.Succeed(requirement);
}
else
{
context?.Fail();
}
}
}
return Task.CompletedTask;
}
}
#endregion

  想要更快更方便的了解相关知识,可以关注微信公众号 

.NET7之MiniAPI(特别篇) :Preview5优化了JWT验证(下)_Preview5