ASP.NET Core中的授权(2) — 基于声明

程序认证身份之后就是授权,授权也有很多种

三种:基于角色, 基于声明,基于策略

此次授权的demo之git地址:https://github.com/xeekseven/AspNet-core-Example/tree/master/ANC-Authorize-Policy

基于声明:(用此可以替代基于角色了)

其实这个有点像自由版 基于角色 授权。其中的判断逻辑运算还是 equal,但是type和值都可以自己定义

  1. 首先配置Startup.cs服务
public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
        .AddCookie(options =>
        {
            options.AccessDeniedPath = new PathString("/Home/NotPermission");
            options.LoginPath = new PathString("/Home/Login");
            options.ExpireTimeSpan = TimeSpan.FromSeconds(10);
        });
        services.AddAuthorization(options =>
        {
            //声明一个名为Administrator的声明,判断角色的claimType为Role的值是否equal Administrator、SuperAdministrator
            options.AddPolicy("AdministratorOnly", policy => policy.RequireClaim("Role", "Administrator", "SuperAdministrator"));
            //使用非equal逻辑的声明策略 —— 声明一个生日日期大于某个日期的策略
            options.AddPolicy("DateOfBirthMoreThan2021", policy => policy.RequireAssertion(context => context.User.HasClaim(c =>
                c.Type == ClaimTypes.DateOfBirth && DateTime.Parse(c.Value) > DateTime.Parse("2021-01-15"))));
        });
        services.AddControllersWithViews();
        services.AddRazorPages();
    }

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        else
        {
            app.UseExceptionHandler("/Home/Error");
        }

        app.UseStaticFiles();
        
        app.UseAuthentication();
        app.UseRouting();

        app.UseAuthorization();
        app.UseCookiePolicy();

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapControllerRoute(
                name: "default",
                pattern: "{controller=Home}/{action=Index}/{id?}");
            endpoints.MapRazorPages();
        });
    }
}

1.1 简单的值equal逻辑的声明 —— RequireClaim

services.AddAuthorization(options =>
{
    //声明一个名为Administrator的声明,判断角色的claimType为Role的值是否equal Administrator、SuperAdministrator
    options.AddPolicy("AdministratorOnly", policy => policy.RequireClaim("Role", "Administrator", "SuperAdministrator"));
});

1.2 较复杂逻辑的声明策略(func方式) —— RequireAssertion

services.AddAuthorization(options =>
{
    //使用非equal逻辑的声明策略 —— 声明一个生日日期大于某个日期的策略
    options.AddPolicy("DateOfBirthMoreThan2021", policy => policy.RequireAssertion(context => context.User.HasClaim(c =>
        c.Type == ClaimTypes.DateOfBirth && DateTime.Parse(c.Value) > DateTime.Parse("2021-01-15"))));
});
  1. 使用声明来进行鉴权了。在需要鉴权的接口加上特性并指定特定的声明即可
[Authorize(Policy= "AdministratorOnly")]
public IActionResult Privacy()
{
    return View();
}

[Authorize(Policy = "DateOfBirthMoreThan2021")]
public IActionResult DateOfBirthView()
{
    return View();
}
  1. 然后是登录,
[HttpPost]
[AllowAnonymous]
public async Task Login(string username,string password)
{
    var returnUrl = HttpContext.Request.Query["ReturnUrl"];
    string roleType = "";
    string dateOfBirth = "2020-01-12";
    if (username == "admin"){
        roleType =  "Administrator";
        dateOfBirth = "2022-01-12";
    }
    else if(username == "custom"){
        roleType = "Custom";
        dateOfBirth = "2012-01-12";
    }
    if((username == "admin" && password == "admin") || (username == "custom" && password == "custom")){
        var claims = new List
        {
            new Claim(ClaimTypes.Name,username),
            new Claim(ClaimTypes.DateOfBirth,dateOfBirth),
            new Claim("Role",roleType)
        };
        var claimsIdentity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);
        await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, new ClaimsPrincipal(claimsIdentity), new AuthenticationProperties());
        
        if (!string.IsNullOrWhiteSpace(returnUrl))
        {
            return Redirect(returnUrl);
        }
        return Redirect("/Home/Index");
    }
    if (!string.IsNullOrWhiteSpace(returnUrl))
    {
        return Redirect(returnUrl);
    }
    return Redirect("/Home/Login");
}
  1. 总结就是:
  • 配置服务(Policy定义)、
  • 配置管道使用,
  • 登录时赋值(Type = Role,value=RoleValue),
  • 接口加上指定Policy的Authorize特性

前一篇 — ASP.NET Core中的授权(1) — 基于角色:https://www.jianshu.com/p/a8e663627ec9

下一篇 — ASP.NET Core中的授权(3) — 基于自定义策略:https://www.jianshu.com/p/0bdf572cc103

你可能感兴趣的:(ASP.NET Core中的授权(2) — 基于声明)