Program.cs
#region 授权
builder.Services.AddAuthorization(option =>
{
    //添加自定义授权策略
    option.AddPolicy("MyPolicy",p => p.RequireClaim(ClaimTypes.NameIdentifier,"1"));
});
#endregion
TestController.cs 应用自定义授权策略
[ApiController]
[Route("api/[controller]")]
public class TestController : ControllerBase
{
    [Authorize("MyPolicy")]
    [HttpGet]
    public async Task<string> Get()
    {
        return await Task.FromResult(DateTime.Now.ToString());
    }
}
TokenAuthenticationHandler.cs
    public Task<AuthenticateResult> AuthenticateAsync()
    {
        string token = _context.Request.Headers["Authorization"];
        if (token == "test")
        {
            ClaimsIdentity identity = new ClaimsIdentity("Ctm");
            identity.AddClaims(new List<Claim>(){
                new Claim(ClaimTypes.Name,"admin"),
                new Claim(ClaimTypes.NameIdentifier,"6")
            });
            var claimsPrincipal = new ClaimsPrincipal(identity);
            return Task.FromResult(AuthenticateResult.Success(new AuthenticationTicket(claimsPrincipal, null, _scheme.Name)));
        }
        return Task.FromResult(AuthenticateResult.Fail("token错误,请重新登录"));
    }
    /// <summary>
    /// 没有权限访问
    /// </summary>
    /// <param name="properties"></param>
    /// <returns></returns>
    /// <exception cref="NotImplementedException"></exception>
    public Task ForbidAsync(AuthenticationProperties? properties)
    {
        _context.Response.StatusCode = 403;
        return Task.CompletedTask;
    }
此处鉴权给的值是6,授权用的1,尝试访问
 
重要概念
基于策略的授权中有一个很重要的概念是Requirements,每一个Requirement都代表一个授权条件。
 Requirement需要继承接口IAuthorizationRequirement。
已经内置了一些常用的实现:
 AssertionRequirement :使用最原始的断言形式来声明授权策略。
DenyAnonymousAuthorizationRequirement :用于表示禁止匿名用户访问的授权策略,并在AuthorizationOptions中将其设置为默认策略。
ClaimsAuthorizationRequirement :用于表示判断Cliams中是否包含预期的Claims的授权策略。
RolesAuthorizationRequirement :用于表示使用ClaimsPrincipal.IsInRole来判断是否包含预期的Role的授权策略。
NameAuthorizationRequirement:用于表示使用ClaimsPrincipal.Identities.Name来判断是否包含预期的Name的授权策略。
OperationAuthorizationRequirement:用于表示基于操作的授权策略。
当内置的Requirement不能满足需求时,可以定义自己的Requirement.
自定义Requirement
builder.Services.AddAuthorization(option =>
{
    option.AddPolicy("MyPolicy",p => p.Requirements.Add(new MyAuthorizationHandler("1")));
});
MyAuthorizationHandler.cs
public class MyAuthorizationHandler : AuthorizationHandler<MyAuthorizationHandler>, IAuthorizationRequirement
{
    private readonly string _userId;
    public MyAuthorizationHandler(string userId)
    {
        _userId = userId;
    }
    protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, MyAuthorizationHandler requirement)
    {
        if (context.User.HasClaim(c => c.Type == ClaimTypes.NameIdentifier)
        && context.User.Claims.FirstOrDefault(c => c.Type.Equals(ClaimTypes.NameIdentifier)).Value == _userId)
        {
            context.Succeed(requirement);
        }
        else
        {
            context.Fail();
        }
        return Task.CompletedTask;
    }
}
多授权方案
builder.Services.AddAuthorization(option =>
{
    option.AddPolicy("MyPolicy",p => p.Requirements.Add(new MyAuthorizationHandler("1")));
    option.AddPolicy("MyPolicy1", p => p.Requirements.Add(new MyAuthorizationHandler1("admin")));
});
MyAuthorizationHandler1.cs
public class MyAuthorizationHandler1 : AuthorizationHandler<MyAuthorizationHandler1>, IAuthorizationRequirement
{
    private readonly string _userName;
    public MyAuthorizationHandler1(string userName)
    {
        _userName = userName;
    }
    protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, MyAuthorizationHandler1 requirement)
    {
        if (context.User.HasClaim(c => c.Type == ClaimTypes.Name)
        && context.User.Claims.FirstOrDefault(c => c.Type.Equals(ClaimTypes.Name)).Value == _userName)
        {
            context.Succeed(requirement);
        }
        else
        {
            context.Fail();
        }
        return Task.CompletedTask;
    }
}
TestController.cs
[ApiController]
[Route("api/[controller]")]
public class TestController : ControllerBase
{
    [Authorize(Policy = "MyPolicy")]
    [Authorize(Policy = "MyPolicy1")]
    [HttpGet]
    public async Task<string> Get()
    {
        return await Task.FromResult(DateTime.Now.ToString());
    }
}
鉴权方案 TokenAuthenticationHandler.cs
public class TokenAuthenticationHandler : IAuthenticationHandler
{
    private AuthenticationScheme _scheme;
    private HttpContext _context;
    /// <summary>
    /// 鉴权初始化
    /// </summary>
    /// <param name="scheme">鉴权架构名称</param>
    /// <param name="context">HttpContext</param>
    /// <returns></returns>
    /// <exception cref="NotImplementedException"></exception>
    public Task InitializeAsync(AuthenticationScheme scheme, HttpContext context)
    {
        _scheme = scheme;
        _context = context;
        return Task.CompletedTask;
    }
    public Task<AuthenticateResult> AuthenticateAsync()
    {
        string token = _context.Request.Headers["Authorization"];
        if (token == "test")
        {
            ClaimsIdentity identity = new ClaimsIdentity("Ctm");
            identity.AddClaims(new List<Claim>(){
                new Claim(ClaimTypes.Name,"admin"),
                new Claim(ClaimTypes.NameIdentifier,"1")
            });
            var claimsPrincipal = new ClaimsPrincipal(identity);
            return Task.FromResult(AuthenticateResult.Success(new AuthenticationTicket(claimsPrincipal, null, _scheme.Name)));
        }
        return Task.FromResult(AuthenticateResult.Fail("token错误,请重新登录"));
    }
    /// <summary>
    /// 未登录
    /// </summary>
    /// <param name="properties"></param>
    /// <returns></returns>
    /// <exception cref="NotImplementedException"></exception>
    public Task ChallengeAsync(AuthenticationProperties? properties)
    {
        _context.Response.Redirect("/api/Login/NoLogin");
        return Task.CompletedTask;
    }
    /// <summary>
    /// 没有权限访问
    /// </summary>
    /// <param name="properties"></param>
    /// <returns></returns>
    /// <exception cref="NotImplementedException"></exception>
    public Task ForbidAsync(AuthenticationProperties? properties)
    {
        _context.Response.StatusCode = 403;
        return Task.CompletedTask;
    }
}
多授权方案,每个授权策略都需要通过
那么也可以使用多鉴权架构,Cookie可用于web浏览器,token用于终端API调用
改造效果:
多鉴权方案
Program.cs
//注册鉴权架构
#region Cookie
builder.Services.AddAuthentication("Cookies").AddCookie(o =>{
    o.LoginPath = "/api/Login/NoLogin";
});
#region  自定义Token验证
builder.Services.AddAuthentication(option =>
{
    //把自定义的鉴权方案添加到鉴权架构中
    option.AddScheme<TokenAuthenticationHandler>("token", "myToken");
    option.DefaultAuthenticateScheme = "token";
    option.DefaultChallengeScheme = "token";
    option.DefaultForbidScheme = "token";
});
#endregion
#endregion
#region 授权
// builder.Services.AddAuthorization(option =>
// {
//     option.AddPolicy("MyPolicy",p => p.RequireClaim(ClaimTypes.NameIdentifier,"1"));
// });
builder.Services.AddAuthorization(option =>
{
    option.AddPolicy("MyPolicy",p => p.Requirements.Add(new MyAuthorizationHandler("1")));
    // option.AddPolicy("MyPolicy1", p => p.Requirements.Add(new MyAuthorizationHandler1("admin")));
});
#endregion
TestController.cs
[ApiController]
[Route("api/[controller]")]
public class TestController : ControllerBase
{
    [Authorize(Policy = "MyPolicy",AuthenticationSchemes = $"token,Cookies")]
    [HttpGet]
    public async Task<string> Get()
    {
        return await Task.FromResult(DateTime.Now.ToString());
    }
}
授权绑定鉴权
//注册鉴权架构
#region Cookie
builder.Services.AddAuthentication("Cookies").AddCookie(o =>{
    o.LoginPath = "/api/Login/NoLogin";
});
#region  自定义Token验证
builder.Services.AddAuthentication(option =>
{
    //把自定义的鉴权方案添加到鉴权架构中
    option.AddScheme<TokenAuthenticationHandler>("token", "myToken");
    //option.DefaultAuthenticateScheme = "token";
    option.DefaultChallengeScheme = "token";
    option.DefaultForbidScheme = "token";
});
#endregion
#endregion
builder.Services.AddAuthorization(option =>
{
    option.AddPolicy("MyPolicy",p =>p.AddAuthenticationSchemes("token").Requirements.Add(new MyAuthorizationHandler("1")));
    option.AddPolicy("MyPolicy1", p =>p.AddAuthenticationSchemes("Cookies").Requirements.Add(new MyAuthorizationHandler1("admin")));
});
                    © 版权声明
本站所有资源来自于网络,仅供学习与参考,请勿用于商业用途,否则产生的一切后果将由您(转载者)自己承担!
如有侵犯您的版权,请及时联系3500663466#qq.com(#换@),我们将第一时间删除本站数据。
如有侵犯您的版权,请及时联系3500663466#qq.com(#换@),我们将第一时间删除本站数据。
THE END
    

















暂无评论内容