我正在创建一个API,并且对声明/保单有一些疑问。在开发中使用声明注册策略相对容易,我创建了一个带有X声明的策略,并将该策略添加到控制器/方法中,拥有这些声明的任何人都可以访问。问题是:
1)如何在生产环境中创建策略并授予其访问特定位置的权限?这是可能的?还是我唯一要做的就是向用户添加X声明,就足够了吗?
2)在足够的情况下,应该创建一个表来存储声明(仅声明)以具有声明列表,然后将其分配给用户(aspNetUserClaims表)吗?
3)如果我在生产中创建角色并分配声明,然后将该角色分配给用户,是否足以访问上述控制器/方法?还是在登录时明确需要捕获角色声明并将其添加到用户?
提前谢谢!问候!
答案 0 :(得分:3)
用户访问网站后,该用户就会收到一系列声明。声明属于角色或用户。但是策略是一组规则,它与角色或用户没有任何关系。可以从任何资源(不仅是2个索赔表)中验证策略,它还取决于您的代码。这是基于策略的授权的完整示例:https://docs.microsoft.com/en-us/aspnet/core/security/authorization/policies?view=aspnetcore-2.1
1)如何在生产环境中创建策略并将其授予 进入某个地方?这是可能的?还是我唯一要做的 向用户添加X声明就足够了吗?
3个问题:是,是,否。
由于Identity Framework中不存在ClaimAuthorizeAttribute,因此您有2个选项:
implement ClaimAuthorizeAttribute: https://github.com/jayway/JayLabs.Owin.OAuthAuthorization/blob/master/src/JayLabs.Owin.OAuthAuthorization/ClaimAuthorizeAttribute.cs
使用std
提出索赔(我建议)。
Policy
这里是动态应用策略的完整解决方案: https://www.jerriepelser.com/blog/creating-dynamic-authorization-policies-aspnet-core/
2)在足够的情况下,应创建一个表来存储声明 (仅声明)具有声明列表,然后将其分配给用户 (aspNetUserClaims表)?
是&否,您应该有表,但是它没有分配给用户,而是存储策略要求的其他地方(在我的以下代码中为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();
}
)。
3)如果我在生产中创建角色并分配债权,然后分配 该角色对用户而言,足以访问控制器/ 上面提到的方法?或在登录时明确需要 捕获角色的声明并将其添加到用户?
2个问题:是,是。 必须将自定义声明明确分配给用户,以便在登录时使用功能,除非您希望每次需要从数据库访问它。
回到您的第一个问题。
如果您想按条件启用/禁用策略,可以很容易地从AspNetPolicyRequirement
开始。
设置:
首先在database
中注入IHostingEnvironment
Startup.cs
然后在public class Startup
{
private readonly IHostingEnvironment _environment;
public Startup(IHostingEnvironment environment, ...)
{
_environment = environment;
....
}
....
}
public void ConfigureServices(IServiceCollection services)
或
if (_environment.IsProduction())
{
services.AddAuthorization(options =>
{
options.AddPolicy("AtLeast21", policy =>
policy.Requirements.Add(new MinimumAgeRequirement(21)));
});
}
下一步:目前没有现有的services.AddAuthorization(options =>
{
if (_environment.IsProduction())
{
options.AddPolicy("AtLeast21", policy =>
policy.Requirements.Add(new MinimumAgeRequirement(21)));
}
});
或AspNetUserPolicy
表,而且我认为它不会在框架级别存在。如果您的保单仅来自索赔,没有其他任何保单,则只能使用2个索赔表来注册保单,但我不建议这样做,因为它是WhateverPolicy
的反设计。
通常,它可能是以下设计:
Policy
那么您的实体将是:
/****** Object: Table [dbo].[AspNetPolicy]******/
CREATE TABLE [dbo].[AspNetPolicy](
[Id] [int] IDENTITY(1,1) NOT NULL,
[Name] [nvarchar](150) 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](
[Id] [int] NOT NULL,
[AspNetPolicyId] [int] NOT NULL,
[RequirementType] [int] NOT NULL,
[RequirementName] [nvarchar](150) 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
要通过以下代码启用策略:
public partial class AspNetPolicy
{
public AspNetPolicy()
{
AspNetPolicyRequirement = new HashSet<AspNetPolicyRequirement>();
}
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,
}
您必须按照自己的设计完成其余工作。