zoukankan      html  css  js  c++  java
  • asp.net core 权限认证

    一、简单授权

    ASP.NET Core 中的授权通过 AuthorizeAttribute 和其各种参数来控制。 在其页面中,通过 [Authorize] 属性应用于控制器、操作或 Razor 页面,限制对已通过身份验证的用户的访问。

    示例如下:

    [Authorize] 
    public class AccountController : Controller { 
       public ActionResult Login() { 
       
       } 
       public ActionResult Logout() {
    
       }
     }

    如果要对操作(而不是控制器)应用授权,请将属性应用于 AuthorizeAttribute 操作本身

    示例如下:

    public class AccountController : Controller { 
    public ActionResult Login() { 
    
    } 
    
    [Authorize] 
    public ActionResult Logout() { 
    
      } 
    }

    你还可以使用属性,以 AllowAnonymous 允许未通过身份验证的用户访问各个操作。 例如:

    [Authorize] 
    public class AccountController : Controller { 
    
      [AllowAnonymous] 
      public ActionResult Login() { 
    
      } 
      public ActionResult Logout() { 
      } 
    }

    二、基于角色的授权

    基于角色的授权检查是声明性 — 的,开发人员将其嵌入到代码中、控制器或控制器内的操作,指定当前用户必须是其成员的角色才能访问请求的资源。

    例如,以下代码将访问权限限制为属于角色成员的用户的任何操作:

    [Authorize(Roles = "Administrator")] 
    public class AdministrationController : Controller { }

    多角色可以定义如下:

    [Authorize(Roles = "HRManager,Finance")] 
    public class SalaryController : Controller { }

    如果应用多个属性,则访问用户必须是所有指定角色的成员;下面的示例要求用户必须是 PowerUser 和角色的成员 ControlPanelUser

    [Authorize(Roles = "PowerUser")]
    [Authorize(Roles = "ControlPanelUser")] 
    public class ControlPanelController : Controller { }

    三、基于策略的授权

    基于策略的授权,其实就是要求用户必须满足指定的策略要求,这个策略一般都是用户的一些基本信息,如名字、角色或者其他,我们首先要在在配置函数中,添加一个策略如下:

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddControllersWithViews();
        services.AddRazorPages();
    
        services.AddAuthorization(options =>
        {
            options.AddPolicy("EmployeeOnly", policy => policy.RequireClaim("EmployeeNumber"));
        });
    }

    如以上代码,要求用户的claim信息中包含EmployeeNumber属性

         var claims = new List<Claim>()
         {
          new Claim(ClaimTypes.Name,username),
          new Claim("UserId",currentUser.UID.ToString()),
          new Claim(ClaimTypes.Role, roleName),
          new Claim("EmployeeNumber",“1"),         
       };

    那么在控制器中,只需要以下代码,并能实现对权限的控制

    [Authorize(Policy = "EmployeeOnly")]
    public IActionResult VacationBalance()
    {
        return View();
    }

    基于策略的授权,

    policy函数具有以下一些常用的函数:

    AddAuthenticationSchemes(String[])
    将指定的身份验证添加 schemes 到 AuthenticationSchemes 此实例的。

    AddRequirements(IAuthorizationRequirement[])
    将指定的添加 requirements 到 Requirements 此实例的。

    Build()
    AuthorizationPolicy根据此实例中的要求生成一个新的。

    Combine(AuthorizationPolicy)
    将指定的合并 policy 到当前实例中。

    RequireAssertion(Func<AuthorizationHandlerContext,Boolean>)
    将添加 AssertionRequirement 到当前实例中。

    RequireAssertion(Func<AuthorizationHandlerContext,Task<Boolean>>)
    将添加 AssertionRequirement 到当前实例中。

    RequireAuthenticatedUser()
    该实例强制对当前用户进行身份验证。

    RequireClaim(String)
    要求当前用户具有指定的声明。

    RequireClaim(String, IEnumerable<String>)
    这要求当前用户具有指定的声明,并且声明值必须是允许的值之一。

    RequireClaim(String, String[])
    这要求当前用户具有指定的声明,并且声明值必须是允许的值之一。

    RequireRole(IEnumerable<String>)
    该实例强制当前用户必须至少有一个指定的角色。

    RequireRole(String[])
    该实例强制当前用户必须至少有一个指定的角色。

    RequireUserName(String)
    强制当前用户与指定的名称匹配。

    除以上功能之外,用于可以自定义策略,实现对页面的授权,其定义策略的基本方法如下:

    1、实现IAuthorizationRequirement接口,定义一个策略规范

    using Microsoft.AspNetCore.Authorization;
    
    public class MinimumAgeRequirement : IAuthorizationRequirement
    {
        public int MinimumAge { get; }
    
        public MinimumAgeRequirement(int minimumAge)
        {
            MinimumAge = minimumAge;
        }
    }

    2、实现策略检查器,其负责对策略进行检查,以下代码请求用户年纪,并且进行策略比较,实现授权

    public class MinimumAgeHandler : AuthorizationHandler<MinimumAgeRequirement>
    {
        protected override Task HandleRequirementAsync(AuthorizationHandlerContext context,
                                                       MinimumAgeRequirement requirement)
        {
            if (!context.User.HasClaim(c => c.Type == ClaimTypes.DateOfBirth &&
                                            c.Issuer == "http://contoso.com"))
            {
                //TODO: Use the following if targeting a version of
                //.NET Framework older than 4.6:
                //      return Task.FromResult(0);
                return Task.CompletedTask;
            }
    
            var dateOfBirth = Convert.ToDateTime(
                context.User.FindFirst(c => c.Type == ClaimTypes.DateOfBirth && 
                                            c.Issuer == "http://contoso.com").Value);
    
            int calculatedAge = DateTime.Today.Year - dateOfBirth.Year;
            if (dateOfBirth > DateTime.Today.AddYears(-calculatedAge))
            {
                calculatedAge--;
            }
    
            if (calculatedAge >= requirement.MinimumAge)
            {
                context.Succeed(requirement);
            }
    
            //TODO: Use the following if targeting a version of
            //.NET Framework older than 4.6:
            //      return Task.FromResult(0);
            return Task.CompletedTask;
        }
    }

    3、在ConfigureServices中添加策略检查代码,如下所示:

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddControllersWithViews();
        services.AddRazorPages();
        services.AddAuthorization(options =>
        {
            options.AddPolicy("AtLeast21", policy =>
                policy.Requirements.Add(new MinimumAgeRequirement(21)));
        });
    //添加一个可以注入的对象 services.AddSingleton
    <IAuthorizationHandler, MinimumAgeHandler>(); }

    4、如果要实现多个授权策略,可以实现继承如下接口

    ublic class PermissionHandler : IAuthorizationHandler
    {
        public Task HandleAsync(AuthorizationHandlerContext context)
        {
            var pendingRequirements = context.PendingRequirements.ToList();
    
            foreach (var requirement in pendingRequirements)
            {
                if (requirement is ReadPermission)
                {
                    if (IsOwner(context.User, context.Resource) ||
                        IsSponsor(context.User, context.Resource))
                    {
                        context.Succeed(requirement);
                    }
                }
                else if (requirement is EditPermission ||
                         requirement is DeletePermission)
                {
                    if (IsOwner(context.User, context.Resource))
                    {
                        context.Succeed(requirement);
                    }
                }
            }
    
            //TODO: Use the following if targeting a version of
            //.NET Framework older than 4.6:
            //      return Task.FromResult(0);
            return Task.CompletedTask;
        }
    
        private bool IsOwner(ClaimsPrincipal user, object resource)
        {
            // Code omitted for brevity
    
            return true;
        }
    
        private bool IsSponsor(ClaimsPrincipal user, object resource)
        {
            // Code omitted for brevity
    
            return true;
        }

    四、策略授权提供程序IAuthorizationPolicyProvider 

    通常,在使用 基于策略的授权时,通过调用 AuthorizationOptions.AddPolicy 作为授权服务配置的一部分来注册策略。 在某些情况下,可能无法 (或理想的) 以这种方式注册所有的授权策略。 在这些情况下,可以使用自定义 IAuthorizationPolicyProvider 来控制如何提供授权策略

    internal class MinimumAgePolicyProvider : IAuthorizationPolicyProvider
    {
        const string POLICY_PREFIX = "MinimumAge";
    
        // Policies are looked up by string name, so expect 'parameters' (like age)
        // to be embedded in the policy names. This is abstracted away from developers
        // by the more strongly-typed attributes derived from AuthorizeAttribute
        // (like [MinimumAgeAuthorize()] in this sample)
        public Task<AuthorizationPolicy> GetPolicyAsync(string policyName)
        {
            if (policyName.StartsWith(POLICY_PREFIX, StringComparison.OrdinalIgnoreCase) &&
                int.TryParse(policyName.Substring(POLICY_PREFIX.Length), out var age))
            {
                var policy = new AuthorizationPolicyBuilder(CookieAuthenticationDefaults.AuthenticationScheme);
                policy.AddRequirements(new MinimumAgeRequirement(age));
                return Task.FromResult(policy.Build());
            }
    
            return Task.FromResult<AuthorizationPolicy>(null);
        }
    }
  • 相关阅读:
    JQuery Div scrollTop ScrollHeight
    [转]docker快速搭建redis集群、zookeeper集群、activeMQ、fastdfs分布式存储教程
    Debian8安装OpenMediaVault3组建家庭NAS
    单片机按键处理方式(一)——典型的按键处理方式
    基于STC12系列单片机的通用红外遥控信号分析程序(一)
    8051系列单片机软件精确延时研究(二)
    8051系列单片机软件精确延时研究(一)
    4个74HC595级联控制16x16点阵横向滚动带仿真(二)
    4个74HC595级联控制16x16点阵横向滚动带仿真(一)
    Ubuntu 16.04下8051单片机开发环境搭建
  • 原文地址:https://www.cnblogs.com/minhost/p/15112558.html
Copyright © 2011-2022 走看看