ASP.NET Core 2.1中的策略和声明


一腔诗意
2025-03-16 12:21:59 (2天前)
  1. 一个


调节器
</跨度>
/方法和拥有这些声明的任何人都可以访问。问题是:

1)我如何创建一个

政策
</跨度>
在生产中并允许其访问某个地方?这是可能的?或者我正在创建一个API,我对索赔/政策有一些疑问。使用开发中的声明注册策略相对容易,我创建了一个

政策
</跨度>
与X声称并添加

政策
</跨度>
到了

2 条回复
  1. 0# 不易青年。 | 2019-08-31 10-32



    一旦用户访问网站,用户就获得了一系列声明。声明属于角色或用户。但政策是一组r

    ü
    </强>
    les,它与角色或用户没有任何关系。策略是从任何资源验证的,而不仅仅是2个声明表,它取决于您的代码。这是基于策略的授权的完整示例:

    https://docs.microsoft.com/en-us/aspnet/core/security/authorization/policies?view=aspnetcore-2.1




    1)如何在生产中创建策略并授予其权限
    访问某个地方?这是可能的?或者我唯一要做的事情
    将X声明添加到用户并且就足够了吗?




    3个问题:是的,是的,不是。



    由于Identity Framework中不存在ClaimAuthorizeAttribute,因此您有两个选项:





    1. imeplement ClaimAuthorizeAttribute:

      1. <a href="https://github.com/jayway/JayLabs.Owin.OAuthAuthorization/blob/master/src/JayLabs.Owin.OAuthAuthorization/ClaimAuthorizeAttribute.cs" rel="nofollow noreferrer">
      2. https://github.com/jayway/JayLabs.Owin.OAuthAuthorization/blob/master/src/JayLabs.Owin.OAuthAuthorization/ClaimAuthorizeAttribute.cs
      3. </A>
      4. </p>
      5. </LI>
      6. <LI>
      7. <P>
      8. 使用
      9. <code>
      10. Policy
      11. </code>
      12. 申请索赔(由我推荐)。
      13. </p>
      14. <pre>
      15. <code>
      16. public void ConfigureServices(IServiceCollection services)

      {
      services.AddAuthorization(options =>
      {
      options.AddPolicy(“EmployeeOnly”, policy =>
      {
      policy.RequireAssertion(context =>
      {
      //Here you can get many resouces from context, i get a claim here for example
      var yourvalue = context.User.Claims.FirstOrDefault(x => x.Type == “yourType”)?.Value;
      //here you can access DB or any other API to do anything if you don’t mind performance issues.
      var user = new DefaultContext().AspNetUsers.FirstOrDefaultAsync(x =>
      x.UserName == yourvalue);
      //return a boolen to end validation.
      return user != null;
      });
      });
      });
      }

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

      1. </code>
      2. </pre>
      3. </LI>

      </醇>


      以下是动态应用策略的完整解决方案:

      1. <a href="https://www.jerriepelser.com/blog/creating-dynamic-authorization-policies-aspnet-core/" rel="nofollow noreferrer">
      2. https://www.jerriepelser.com/blog/creating-dynamic-authorization-policies-aspnet-core/
      3. </A>




      2)在足够的情况下,应该创建一个表来存储声明
      (仅限索赔)拥有一份索赔清单,然后将其分配给用户
      (aspNetUserClaims表)?




      是和否,你应该有桌子,但它没有分配给用户,而是分配给存储政策要求的其他地方(它是

      AspNetPolicyRequirement

      在我的下面的代码中)。




      3)如果我在生产中创建角色并分配声明然后分配
      该角色对用户而言足以访问控制器/
      上面提到的方法?或登录时,我需要明确地
      捕获角色的声明并将其添加到用户?




      2个问题:是的,是的。
      必须将自定义声明明确分配给用户才能在登录时使用功能,除非您希望每次需要时都从DB访问它。



      回到你的第一个问题。



      如果您想按条件启用/禁用策略,则可以很容易地执行此操作

      database




      Setps:



      首先注入IHostingEnvironment

      Startup.cs




      1. public class Startup
        {
        private readonly IHostingEnvironment _environment;

      2. public Startup(IHostingEnvironment environment, ...)
      3. {
      4.     _environment = environment;
      5.     ....
      6. }
      7. ....
      8. }

      9. </code>


      然后添加以下代码

      public void ConfigureServices(IServiceCollection services)




      1. if (_environment.IsProduction())
        {
        services.AddAuthorization(options =>
        {
        options.AddPolicy(“AtLeast21”, policy =>
        policy.Requirements.Add(new MinimumAgeRequirement(21)));
        });
        }

      2. </code>


      要么




      1. services.AddAuthorization(options =>
        {
        if (_environment.IsProduction())
        {
        options.AddPolicy(“AtLeast21”, policy =>
        policy.Requirements.Add(new MinimumAgeRequirement(21)));
        }

      2. });

      3. </code>


      下一步:没有现成的

      AspNetUserPolicy

      要么

      WhateverPolicy

      表现在,我不认为它将存在于框架级别。如果您的政策仅来自索赔,没有任何其他政策,您可以使用2个索赔表来注册政策,但我不推荐它,因为它是反设计的

      Policy




      通常,它可能是以下设计:




      1. /** Object: Table [dbo].[AspNetPolicy]**/

      2. CREATE TABLE [dbo].AspNetPolicy NOT NULL,
        [Name] nvarchar NOT NULL,
        [Enabled] [bit] NOT NULL,
        CONSTRAINT [PK_AspNetPolicy] PRIMARY KEY CLUSTERED
        (
        [Id] ASC
        )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
        ) ON [PRIMARY]
        GO
        /** Object: Table [dbo].[AspNetPolicyRequirement]**/
        CREATE TABLE [dbo].AspNetPolicyRequirement NOT NULL,
        [Enabled] [bit] NOT NULL,
        CONSTRAINT [PK_AspNetPolicyRequirement] PRIMARY KEY CLUSTERED
        (
        [Id] ASC
        )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
        ) ON [PRIMARY]
        GO
        ALTER TABLE [dbo].[AspNetPolicy] ADD CONSTRAINT [DF_AspNetPolicy_Enabled] DEFAULT ((1)) FOR [Enabled]
        GO
        ALTER TABLE [dbo].[AspNetPolicyRequirement] ADD CONSTRAINT [DF_AspNetPolicyRequirement_Enabled] DEFAULT ((1)) FOR [Enabled]
        GO
        ALTER TABLE [dbo].[AspNetPolicyRequirement] WITH CHECK ADD CONSTRAINT [FK_AspNetPolicyRequirement_AspNetPolicy] FOREIGN KEY([AspNetPolicyId])
        REFERENCES [dbo].[AspNetPolicy] ([Id])
        GO
        ALTER TABLE [dbo].[AspNetPolicyRequirement] CHECK CONSTRAINT [FK_AspNetPolicyRequirement_AspNetPolicy]
        GO

      3. </code>


      那么你的实体将是:




      1. public partial class AspNetPolicy
        {
        public AspNetPolicy()
        {
        AspNetPolicyRequirement = new HashSet();
        }

      2. public int Id { get; set; }
      3. [Required]
      4. [StringLength(50)]
      5. public string Name { get; set; }
      6. [Required]
      7. public bool Enabled { get; set; } = true;
      8. [InverseProperty("AspNetPolicy")]
      9. public ICollection<AspNetPolicyRequirement> AspNetPolicyRequirement { get; set; }
      10. }
        public partial class AspNetPolicyRequirement
        {
        public int Id { get; set; }
        public int AspNetPolicyId { get; set; }
        public RequirementType RequirementType { get; set; }
        [Required]
        [StringLength(150)]
        public string RequirementName { get; set; }
        [Required]
        public bool Enabled { get; set; } = true;

      11. [ForeignKey("AspNetPolicyId")]
      12. [InverseProperty("AspNetPolicyRequirement")]
      13. public AspNetPolicy AspNetPolicy { get; set; }
      14. }
        public enum RequirementType
        {
        Custom = 0,
        Claim = 1,
        Role = 2,
        UserName = 3,
        AuthenticatedUser = 4,
        Assertion = 5,
        }

      15. </code>


      要通过以下代码启用策略:




      1. private void ConfigurePolicies(IServiceCollection services)
        {
        //get data by your way, here is only an example.
        var policies = new DefaultContext().AspNetPolicy
        .Include(x => x.AspNetPolicyRequirement)
        .Where(x => x.Enabled)
        .ToList();

      2. //map them to real policies
      3. services.AddAuthorization(options =>
      4. {
      5.     policies.ForEach(aspNetPolicy =>
      6.     {
      7.         options.AddPolicy(aspNetPolicy.Name, policy =>
      8.         {
      9.             foreach (var aspNetPolicyRequirement in aspNetPolicy.AspNetPolicyRequirement.Where(x=>x.Enabled))
      10.             {
      11.                 switch (aspNetPolicyRequirement.RequirementType)
      12.                 {
      13.                     case RequirementType.Claim:
      14.                     {
      15.                         policy.RequireClaim(aspNetPolicyRequirement.RequirementName);
      16.                         break;
      17.                     }
      18.                     case RequirementType.UserName:
      19.                     {
      20.                         policy.RequireUserName(aspNetPolicyRequirement.RequirementName);
      21.                         break;
      22.                     }
      23.                     case RequirementType.Role:
      24.                     {
      25.                         policy.RequireRole(aspNetPolicyRequirement.RequirementName);
      26.                         break;
      27.                     }
      28.                     case RequirementType.AuthenticatedUser:
      29.                     {
      30.                         policy.RequireAuthenticatedUser();
      31.                         break;
      32.                     }
      33.                     case RequirementType.Assertion:
      34.                     {
      35.                         //policy.RequireAssertion(...);//To Do
      36.                         break;
      37.                     }
      38.                 }
      39.             }
      40.         });
      41.     });
      42. });
      43. }

      44. </code>


      你必须按照自己的设计做其余的工作。


登录 后才能参与评论