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

Posted dotNET跨平台

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了.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();
//登录,生成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验证(下)的主要内容,如果未能解决你的问题,请参考以下文章

.NET7之MiniAPI(特别篇):.NET7 Preview3

.NET7之MiniAPI(特别篇) :Preview6 缓存和限流

.NET7之MiniAPI(特别篇) .NET Preview5参数绑定

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

MiniAPI:.NET7 Preview4之MiniAPI更新总览

.NET7 Preview4 之OpenAPI swagger改进