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

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();//登录,生成tokenapp.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