如何使用身份 2.0 使用授权属性添加多个策略?
How to add multiple policies in action using Authorize attribute using identity 2.0?
我是 asp.net 核心 2.0 的身份 2.1.2,我有申请声明 table,它有声明类型和声明价值
即资产、资产编辑、资产、资产视图,其中声明类型与不同的声明值相同,我正在使用声明类型名称创建策略,这对我来说工作正常不知道如何在一个操作中添加多个策略。以下代码在启动文件中用于创建策略。
services.AddAuthorization(options =>
{
var dbContext = SqlServerDbContextOptionsExtensions.UseSqlServer(new DbContextOptionsBuilder<MyDBContext>(),
Configuration.GetConnectionString("TestIdentityClaimAuth")).Options;
var dbCon = new MyDBContext(dbContext);
//Getting the list of application claims.
var applicationClaims = dbCon.ApplicationClaims.ToList();
var strClaimValues = string.Empty;
List<ClaimVM> lstClaimTypeVM = new List<ClaimVM>();
IEnumerable<string> lstClaimValueVM = null;// new IEnumerable<string>();
lstClaimTypeVM = (from dbAppClaim
in dbCon.ApplicationClaims
select new ClaimVM
{
ClaimType = dbAppClaim.ClaimType
}).Distinct().ToList();
foreach (ClaimVM objClaimType in lstClaimTypeVM)
{
lstClaimValueVM = (from dbClaimValues in dbCon.ApplicationClaims
where dbClaimValues.ClaimType == objClaimType.ClaimType
select dbClaimValues.ClaimValue).ToList();
options.AddPolicy(objClaimType.ClaimType, policy => policy.RequireClaim(objClaimType.ClaimType, lstClaimValueVM));
lstClaimValueVM = null;
}
});
并且在我的控制器中使用这样的 Autherize 属性。
[Authorize(Policy = "Assets Edit")]
请提前给它遮光。
对于多个策略,您可以实施自己的 AuthorizeAttribute
。
MultiplePolicysAuthorizeAttribute
public class MultiplePolicysAuthorizeAttribute : TypeFilterAttribute
{
public MultiplePolicysAuthorizeAttribute(string policys, bool isAnd = false) : base(typeof(MultiplePolicysAuthorizeFilter))
{
Arguments = new object[] { policys, isAnd };
}
}
MultiplePolicysAuthorizeFilter
public class MultiplePolicysAuthorizeFilter : IAsyncAuthorizationFilter
{
private readonly IAuthorizationService _authorization;
public string Policys { get; private set; }
public bool IsAnd { get; private set; }
public MultiplePolicysAuthorizeFilter(string policys, bool isAnd, IAuthorizationService authorization)
{
Policys = policys;
IsAnd = isAnd;
_authorization = authorization;
}
public async Task OnAuthorizationAsync(AuthorizationFilterContext context)
{
var policys = Policys.Split(";").ToList();
if (IsAnd)
{
foreach (var policy in policys)
{
var authorized = await _authorization.AuthorizeAsync(context.HttpContext.User, policy);
if (!authorized.Succeeded)
{
context.Result = new ForbidResult();
return;
}
}
}
else
{
foreach (var policy in policys)
{
var authorized = await _authorization.AuthorizeAsync(context.HttpContext.User, policy);
if (authorized.Succeeded)
{
return;
}
}
context.Result = new ForbidResult();
return;
}
}
}
只需要其中一项保单
[MultiplePolicysAuthorize("Assets View;Assets Edit;Assets Delete")]
只需要所有政策
[MultiplePolicysAuthorize("Assets View;Assets Edit;Assets Delete", true)]
如果您只想应用多个策略,您可以这样做:
[Authorize(Policy = "Asset")]
[Authorize(Policy = "Edit")]
public class MyController : Controller {
}
编辑:澄清一下,这是附加的 - 您必须满足这两项政策要求。
您可以使用 make multiple requirements class 实现 IAuthorizationRequirement
,并将 AuthorizationHandler
的多个需求处理程序注册到 DI 容器。
因此您只需使用 AuthorizationPolicyBuilder
中的 AddRequirement
将它们添加到您的政策中
public AuthorizationPolicyBuilder AddRequirements(params IAuthorizationRequirement[] requirements);
Startup.cs:
services.AddScoped<IAuthorizationHandler, FooHandler>();
services.AddScoped<IAuthorizationHandler, BooHandler>();
services.AddAuthorization(authorizationOptions =>
{
authorizationOptions.AddPolicy(
"FooAndBooPolicy",
policyBuilder =>
{
policyBuilder.RequireAuthenticatedUser();
policyBuilder.AddRequirements(new FooRequirement(), new BooRequirement());
});
});
Requirements.cs:
public class FooRequirement : IAuthorizationRequirement { }
public class FooHandler : AuthorizationHandler<FooRequirement>
{
protected override Task HandleRequirementAsync(AuthorizationContext context, FooRequirement requirement)
{
if (context.User.HasClaim(c => c.Type == "Foo" && c.Value == true))
{
context.Succeed(requirement);
return Task.FromResult(0);
}
}
}
public class BooRequirement : IAuthorizationRequirement { }
public class BooHandler : AuthorizationHandler<BooRequirement>
{
protected override Task HandleRequirementAsync(AuthorizationContext context, BooRequirement requirement)
{
if (context.User.HasClaim(c => c.Type == "Boo" && c.Value == true))
{
context.Succeed(requirement);
return Task.FromResult(0);
}
}
}
我是 asp.net 核心 2.0 的身份 2.1.2,我有申请声明 table,它有声明类型和声明价值 即资产、资产编辑、资产、资产视图,其中声明类型与不同的声明值相同,我正在使用声明类型名称创建策略,这对我来说工作正常不知道如何在一个操作中添加多个策略。以下代码在启动文件中用于创建策略。
services.AddAuthorization(options =>
{
var dbContext = SqlServerDbContextOptionsExtensions.UseSqlServer(new DbContextOptionsBuilder<MyDBContext>(),
Configuration.GetConnectionString("TestIdentityClaimAuth")).Options;
var dbCon = new MyDBContext(dbContext);
//Getting the list of application claims.
var applicationClaims = dbCon.ApplicationClaims.ToList();
var strClaimValues = string.Empty;
List<ClaimVM> lstClaimTypeVM = new List<ClaimVM>();
IEnumerable<string> lstClaimValueVM = null;// new IEnumerable<string>();
lstClaimTypeVM = (from dbAppClaim
in dbCon.ApplicationClaims
select new ClaimVM
{
ClaimType = dbAppClaim.ClaimType
}).Distinct().ToList();
foreach (ClaimVM objClaimType in lstClaimTypeVM)
{
lstClaimValueVM = (from dbClaimValues in dbCon.ApplicationClaims
where dbClaimValues.ClaimType == objClaimType.ClaimType
select dbClaimValues.ClaimValue).ToList();
options.AddPolicy(objClaimType.ClaimType, policy => policy.RequireClaim(objClaimType.ClaimType, lstClaimValueVM));
lstClaimValueVM = null;
}
});
并且在我的控制器中使用这样的 Autherize 属性。
[Authorize(Policy = "Assets Edit")]
请提前给它遮光。
对于多个策略,您可以实施自己的 AuthorizeAttribute
。
MultiplePolicysAuthorizeAttribute
public class MultiplePolicysAuthorizeAttribute : TypeFilterAttribute { public MultiplePolicysAuthorizeAttribute(string policys, bool isAnd = false) : base(typeof(MultiplePolicysAuthorizeFilter)) { Arguments = new object[] { policys, isAnd }; } }
MultiplePolicysAuthorizeFilter
public class MultiplePolicysAuthorizeFilter : IAsyncAuthorizationFilter { private readonly IAuthorizationService _authorization; public string Policys { get; private set; } public bool IsAnd { get; private set; } public MultiplePolicysAuthorizeFilter(string policys, bool isAnd, IAuthorizationService authorization) { Policys = policys; IsAnd = isAnd; _authorization = authorization; } public async Task OnAuthorizationAsync(AuthorizationFilterContext context) { var policys = Policys.Split(";").ToList(); if (IsAnd) { foreach (var policy in policys) { var authorized = await _authorization.AuthorizeAsync(context.HttpContext.User, policy); if (!authorized.Succeeded) { context.Result = new ForbidResult(); return; } } } else { foreach (var policy in policys) { var authorized = await _authorization.AuthorizeAsync(context.HttpContext.User, policy); if (authorized.Succeeded) { return; } } context.Result = new ForbidResult(); return; } } }
只需要其中一项保单
[MultiplePolicysAuthorize("Assets View;Assets Edit;Assets Delete")]
只需要所有政策
[MultiplePolicysAuthorize("Assets View;Assets Edit;Assets Delete", true)]
如果您只想应用多个策略,您可以这样做:
[Authorize(Policy = "Asset")]
[Authorize(Policy = "Edit")]
public class MyController : Controller {
}
编辑:澄清一下,这是附加的 - 您必须满足这两项政策要求。
您可以使用 make multiple requirements class 实现 IAuthorizationRequirement
,并将 AuthorizationHandler
的多个需求处理程序注册到 DI 容器。
因此您只需使用 AuthorizationPolicyBuilder
AddRequirement
将它们添加到您的政策中
public AuthorizationPolicyBuilder AddRequirements(params IAuthorizationRequirement[] requirements);
Startup.cs:
services.AddScoped<IAuthorizationHandler, FooHandler>();
services.AddScoped<IAuthorizationHandler, BooHandler>();
services.AddAuthorization(authorizationOptions =>
{
authorizationOptions.AddPolicy(
"FooAndBooPolicy",
policyBuilder =>
{
policyBuilder.RequireAuthenticatedUser();
policyBuilder.AddRequirements(new FooRequirement(), new BooRequirement());
});
});
Requirements.cs:
public class FooRequirement : IAuthorizationRequirement { }
public class FooHandler : AuthorizationHandler<FooRequirement>
{
protected override Task HandleRequirementAsync(AuthorizationContext context, FooRequirement requirement)
{
if (context.User.HasClaim(c => c.Type == "Foo" && c.Value == true))
{
context.Succeed(requirement);
return Task.FromResult(0);
}
}
}
public class BooRequirement : IAuthorizationRequirement { }
public class BooHandler : AuthorizationHandler<BooRequirement>
{
protected override Task HandleRequirementAsync(AuthorizationContext context, BooRequirement requirement)
{
if (context.User.HasClaim(c => c.Type == "Boo" && c.Value == true))
{
context.Succeed(requirement);
return Task.FromResult(0);
}
}
}