一旦用户访问网站,用户就获得了一系列声明。声明属于角色或用户。但政策是一组r
的
ü
</强>
les,它与角色或用户没有任何关系。策略是从任何资源验证的,而不仅仅是2个声明表,它取决于您的代码。这是基于策略的授权的完整示例:
https://docs.microsoft.com/en-us/aspnet/core/security/authorization/policies?view=aspnetcore-2.1
1)如何在生产中创建策略并授予其权限
访问某个地方?这是可能的?或者我唯一要做的事情
将X声明添加到用户并且就足够了吗?
3个问题:是的,是的,不是。
由于Identity Framework中不存在ClaimAuthorizeAttribute,因此您有两个选项:
imeplement ClaimAuthorizeAttribute:<a href="https://github.com/jayway/JayLabs.Owin.OAuthAuthorization/blob/master/src/JayLabs.Owin.OAuthAuthorization/ClaimAuthorizeAttribute.cs" rel="nofollow noreferrer">
https://github.com/jayway/JayLabs.Owin.OAuthAuthorization/blob/master/src/JayLabs.Owin.OAuthAuthorization/ClaimAuthorizeAttribute.cs
</A>
</p>
</LI>
<LI>
<P>
使用
<code>
Policy
</code>
申请索赔(由我推荐)。
</p>
<pre>
<code>
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();
}</code>
</pre>
</LI>
</醇>
以下是动态应用策略的完整解决方案:<a href="https://www.jerriepelser.com/blog/creating-dynamic-authorization-policies-aspnet-core/" rel="nofollow noreferrer">
https://www.jerriepelser.com/blog/creating-dynamic-authorization-policies-aspnet-core/
</A>
2)在足够的情况下,应该创建一个表来存储声明
(仅限索赔)拥有一份索赔清单,然后将其分配给用户
(aspNetUserClaims表)?
是和否,你应该有桌子,但它没有分配给用户,而是分配给存储政策要求的其他地方(它是
AspNetPolicyRequirement
在我的下面的代码中)。
3)如果我在生产中创建角色并分配声明然后分配
该角色对用户而言足以访问控制器/
上面提到的方法?或登录时,我需要明确地
捕获角色的声明并将其添加到用户?
2个问题:是的,是的。
必须将自定义声明明确分配给用户才能在登录时使用功能,除非您希望每次需要时都从DB访问它。
回到你的第一个问题。
如果您想按条件启用/禁用策略,则可以很容易地执行此操作
database
。
Setps:
首先注入IHostingEnvironment
Startup.cs
public class Startup
{
private readonly IHostingEnvironment _environment;public Startup(IHostingEnvironment environment, ...)
{
_environment = environment;
....
}
....
}
</code>
然后添加以下代码
public void ConfigureServices(IServiceCollection services)
if (_environment.IsProduction())
{
services.AddAuthorization(options =>
{
options.AddPolicy(“AtLeast21”, policy =>
policy.Requirements.Add(new MinimumAgeRequirement(21)));
});
}</code>
要么
services.AddAuthorization(options =>
{
if (_environment.IsProduction())
{
options.AddPolicy(“AtLeast21”, policy =>
policy.Requirements.Add(new MinimumAgeRequirement(21)));
}});
</code>
下一步:没有现成的
AspNetUserPolicy
要么
WhateverPolicy
表现在,我不认为它将存在于框架级别。如果您的政策仅来自索赔,没有任何其他政策,您可以使用2个索赔表来注册政策,但我不推荐它,因为它是反设计的
Policy
。
通常,它可能是以下设计:
/** Object: Table [dbo].[AspNetPolicy]**/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</code>
那么你的实体将是:
public partial class AspNetPolicy
{
public AspNetPolicy()
{
AspNetPolicyRequirement = new HashSet();
}public int Id { get; set; }
[Required]
[StringLength(50)]
public string Name { get; set; }
[Required]
public bool Enabled { get; set; } = true;
[InverseProperty("AspNetPolicy")]
public ICollection<AspNetPolicyRequirement> AspNetPolicyRequirement { get; set; }
}
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;[ForeignKey("AspNetPolicyId")]
[InverseProperty("AspNetPolicyRequirement")]
public AspNetPolicy AspNetPolicy { get; set; }
}
public enum RequirementType
{
Custom = 0,
Claim = 1,
Role = 2,
UserName = 3,
AuthenticatedUser = 4,
Assertion = 5,
}</code>
要通过以下代码启用策略:
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();//map them to real policies
services.AddAuthorization(options =>
{
policies.ForEach(aspNetPolicy =>
{
options.AddPolicy(aspNetPolicy.Name, policy =>
{
foreach (var aspNetPolicyRequirement in aspNetPolicy.AspNetPolicyRequirement.Where(x=>x.Enabled))
{
switch (aspNetPolicyRequirement.RequirementType)
{
case RequirementType.Claim:
{
policy.RequireClaim(aspNetPolicyRequirement.RequirementName);
break;
}
case RequirementType.UserName:
{
policy.RequireUserName(aspNetPolicyRequirement.RequirementName);
break;
}
case RequirementType.Role:
{
policy.RequireRole(aspNetPolicyRequirement.RequirementName);
break;
}
case RequirementType.AuthenticatedUser:
{
policy.RequireAuthenticatedUser();
break;
}
case RequirementType.Assertion:
{
//policy.RequireAssertion(...);//To Do
break;
}
}
}
});
});
});
}
</code>
你必须按照自己的设计做其余的工作。