C# asp.net core-将多个参数传递给自定义授权策略提供程序
我正在尝试在asp.net core中设置自定义策略提供程序。我需要将几个自定义授权属性传递给提供商,但如何做到这一点还很困难 我有它的设置,以接受一个枚举数组,目前工作正常。但是,我想在authorization属性中添加另外两个枚举数组作为附加的可选参数 属性的当前状态:C# asp.net core-将多个参数传递给自定义授权策略提供程序,c#,asp.net-core,asp.net-identity,asp.net-authorization,C#,Asp.net Core,Asp.net Identity,Asp.net Authorization,我正在尝试在asp.net core中设置自定义策略提供程序。我需要将几个自定义授权属性传递给提供商,但如何做到这一点还很困难 我有它的设置,以接受一个枚举数组,目前工作正常。但是,我想在authorization属性中添加另外两个枚举数组作为附加的可选参数 属性的当前状态: [LEMClaimAuthorize(new ELocation[] { ELocation.Indy, ELocation.Columbus })] 希望它能像这样工作: [LEMClaimAuthorize(new
[LEMClaimAuthorize(new ELocation[] { ELocation.Indy, ELocation.Columbus })]
希望它能像这样工作:
[LEMClaimAuthorize(new ELocation[] { ELocation.Indy, ELocation.Columbus },
new EEntity[] { EEntity.JobTool })]
LemAuthorizeAttribute是:
public class LEMClaimAuthorizeAttribute : AuthorizeAttribute
{
const string POLICY_PREFIX = "LEMClaim";
public ELocation[] Locations
{
get
{
if (Enum.TryParse(typeof(ELocation[]), Policy.Substring(POLICY_PREFIX.Length), out var locations) )
{
return (ELocation[]) locations;
}
return default(ELocation[]);
}
set
{
int[] intVals = Array.ConvertAll(value, val => (int)val);
string arrayVal = string.Join(",", intVals);
Policy = $"{POLICY_PREFIX}{arrayVal}";
}
}
//remaining code omitted for brevity
}
自定义授权策略提供程序:
public class LEMClaimPolicyProvider : IAuthorizationPolicyProvider
{
const string POLICY_PREFIX = "LEMClaim";
public DefaultAuthorizationPolicyProvider FallbackPolicyProvider { get; }
public LEMClaimPolicyProvider(IOptions<AuthorizationOptions> options)
{
FallbackPolicyProvider = new DefaultAuthorizationPolicyProvider(options);
}
public Task<AuthorizationPolicy> GetDefaultPolicyAsync() => FallbackPolicyProvider.GetDefaultPolicyAsync();
public Task<AuthorizationPolicy> GetPolicyAsync(string policyName)
{
if (!policyName.StartsWith(POLICY_PREFIX, StringComparison.OrdinalIgnoreCase))
return FallbackPolicyProvider.GetPolicyAsync(policyName);
string val = policyName.Substring(POLICY_PREFIX.Length);
//CONVERT STRING TO INT[]
int[] ia = val.Split(',').Select(n => Convert.ToInt32(n)).ToArray();
ELocation[] locations = (ELocation[])(object)ia;
var policy = new AuthorizationPolicyBuilder();
policy.AddRequirements(new LEMClaimRequirement(locations));
return Task.FromResult(policy.Build());
}
}
公共类LEMClaimPolicyProvider:IAAuthorizationPolicyProvider
{
const string POLICY_PREFIX=“lemsclaim”;
public DefaultAuthorizationPolicyProvider FallbackPolicyProvider{get;}
公共lemclaimpolicProvider(选项)
{
FallbackPolicyProvider=新的DefaultAuthorizationPolicyProvider(选项);
}
公共任务GetDefaultPolicyAsync()=>FallbackPolicyProvider.GetDefaultPolicyAsync();
公共任务GetPolicyAsync(字符串policyName)
{
if(!policyName.StartsWith(POLICY_前缀,StringComparison.OrdinalIgnoreCase))
返回FallbackPolicyProvider.GetPolicyAsync(policyName);
string val=policyName.Substring(POLICY_PREFIX.Length);
//将字符串转换为INT[]
int[]ia=val.Split(',')。选择(n=>Convert.ToInt32(n)).ToArray();
ELocation[]位置=(ELocation[])(对象)ia;
var policy=new AuthorizationPolicyBuilder();
政策。添加要求(新的LEMClaimRequirement(位置));
返回Task.FromResult(policy.Build());
}
}
谢谢你的帮助 对于
自定义策略提供程序
,它使用LemsclairAuthorizeAttribute
构建策略,然后检查生成的策略。要将多个参数传递给lemsclairauthorizeattribute
,需要注意生成策略字符串并从策略字符串中提取策略的过程
对于解决方案,请执行以下步骤:
- LemAuthorizeAttribute.cs
public class LEMClaimAuthorizeAttribute : AuthorizeAttribute { public LEMClaimAuthorizeAttribute(ELocation[] eLocations, EEntity[] eEntities = null) //public LEMClaimAuthorizeAttribute(ELocation[] eLocations) { Locations = eLocations; Entitys = eEntities; } const string POLICY_PREFIX_ELocation = "LEMClaim.ELocation"; const string POLICY_PREFIX_EEntity = "LEMClaim.EEntity"; public ELocation[] Locations { get { if (Enum.TryParse(typeof(ELocation[]), Policy.Substring(POLICY_PREFIX_ELocation.Length), out var locations)) { return (ELocation[])locations; } return default(ELocation[]); } set { if (value != null) { int[] intVals = Array.ConvertAll(value, val => (int)val); string arrayVal = string.Join(",", intVals); Policy = Policy == null ? $"{POLICY_PREFIX_ELocation}{arrayVal}" : Policy + $";{POLICY_PREFIX_ELocation}{arrayVal}"; } } } public EEntity[] Entitys { get { if (Enum.TryParse(typeof(EEntity[]), Policy.Substring(POLICY_PREFIX_EEntity.Length), out var locations)) { return (EEntity[])locations; } return default(EEntity[]); } set { if (value != null) { int[] intVals = Array.ConvertAll(value, val => (int)val); string arrayVal = string.Join(",", intVals); Policy = Policy == null ? $"{POLICY_PREFIX_EEntity}{arrayVal}" : Policy + $";{POLICY_PREFIX_EEntity}{arrayVal}"; } } } //remaining code omitted for brevity }
- LEMClaimRequirement.cs
public class LEMClaimRequirement : IAuthorizationRequirement { public LEMClaimRequirement(ELocation[] eLocations, EEntity[] eEntities = null) { Locations = eLocations; Entitys = eEntities; } public ELocation[] Locations { get; set; } public EEntity[] Entitys { get; set; } }
- lemclaimpolicProvider.cs
public class LEMClaimPolicyProvider : IAuthorizationPolicyProvider { const string POLICY_PREFIX = "LEMClaim"; const string POLICY_PREFIX_ELocation = "LEMClaim.ELocation"; const string POLICY_PREFIX_EEntity = "LEMClaim.EEntity"; public DefaultAuthorizationPolicyProvider FallbackPolicyProvider { get; } public LEMClaimPolicyProvider(IOptions<AuthorizationOptions> options) { FallbackPolicyProvider = new DefaultAuthorizationPolicyProvider(options); } public Task<AuthorizationPolicy> GetDefaultPolicyAsync() => FallbackPolicyProvider.GetDefaultPolicyAsync(); public Task<AuthorizationPolicy> GetPolicyAsync(string policyName) { if (!policyName.StartsWith(POLICY_PREFIX, StringComparison.OrdinalIgnoreCase)) return FallbackPolicyProvider.GetPolicyAsync(policyName); var val = policyName.Split(";"); //get locations int[] ia1 = val.FirstOrDefault(k => k.StartsWith(POLICY_PREFIX_ELocation, StringComparison.OrdinalIgnoreCase)) .Substring(POLICY_PREFIX_ELocation.Length) .Split(',').Select(n => Convert.ToInt32(n)).ToArray(); ELocation[] locations = (ELocation[])(object)ia1; int[] ia2 = val.FirstOrDefault(k => k.StartsWith(POLICY_PREFIX_EEntity, StringComparison.OrdinalIgnoreCase)) ?.Substring(POLICY_PREFIX_EEntity.Length) ?.Split(',').Select(n => Convert.ToInt32(n)).ToArray(); EEntity[] entitys = (EEntity[])(object)ia2; var policy = new AuthorizationPolicyBuilder(); policy.AddRequirements(new LEMClaimRequirement(locations, entitys)); return Task.FromResult(policy.Build()); } }
自定义策略提供程序
,它使用LemsclairAuthorizeAttribute
构建策略,然后检查生成的策略。要将多个参数传递给lemsclairauthorizeattribute
,需要注意生成策略字符串并从策略字符串中提取策略的过程
对于解决方案,请执行以下步骤:
- LemAuthorizeAttribute.cs
public class LEMClaimAuthorizeAttribute : AuthorizeAttribute { public LEMClaimAuthorizeAttribute(ELocation[] eLocations, EEntity[] eEntities = null) //public LEMClaimAuthorizeAttribute(ELocation[] eLocations) { Locations = eLocations; Entitys = eEntities; } const string POLICY_PREFIX_ELocation = "LEMClaim.ELocation"; const string POLICY_PREFIX_EEntity = "LEMClaim.EEntity"; public ELocation[] Locations { get { if (Enum.TryParse(typeof(ELocation[]), Policy.Substring(POLICY_PREFIX_ELocation.Length), out var locations)) { return (ELocation[])locations; } return default(ELocation[]); } set { if (value != null) { int[] intVals = Array.ConvertAll(value, val => (int)val); string arrayVal = string.Join(",", intVals); Policy = Policy == null ? $"{POLICY_PREFIX_ELocation}{arrayVal}" : Policy + $";{POLICY_PREFIX_ELocation}{arrayVal}"; } } } public EEntity[] Entitys { get { if (Enum.TryParse(typeof(EEntity[]), Policy.Substring(POLICY_PREFIX_EEntity.Length), out var locations)) { return (EEntity[])locations; } return default(EEntity[]); } set { if (value != null) { int[] intVals = Array.ConvertAll(value, val => (int)val); string arrayVal = string.Join(",", intVals); Policy = Policy == null ? $"{POLICY_PREFIX_EEntity}{arrayVal}" : Policy + $";{POLICY_PREFIX_EEntity}{arrayVal}"; } } } //remaining code omitted for brevity }
- LEMClaimRequirement.cs
public class LEMClaimRequirement : IAuthorizationRequirement { public LEMClaimRequirement(ELocation[] eLocations, EEntity[] eEntities = null) { Locations = eLocations; Entitys = eEntities; } public ELocation[] Locations { get; set; } public EEntity[] Entitys { get; set; } }
- lemclaimpolicProvider.cs
public class LEMClaimPolicyProvider : IAuthorizationPolicyProvider { const string POLICY_PREFIX = "LEMClaim"; const string POLICY_PREFIX_ELocation = "LEMClaim.ELocation"; const string POLICY_PREFIX_EEntity = "LEMClaim.EEntity"; public DefaultAuthorizationPolicyProvider FallbackPolicyProvider { get; } public LEMClaimPolicyProvider(IOptions<AuthorizationOptions> options) { FallbackPolicyProvider = new DefaultAuthorizationPolicyProvider(options); } public Task<AuthorizationPolicy> GetDefaultPolicyAsync() => FallbackPolicyProvider.GetDefaultPolicyAsync(); public Task<AuthorizationPolicy> GetPolicyAsync(string policyName) { if (!policyName.StartsWith(POLICY_PREFIX, StringComparison.OrdinalIgnoreCase)) return FallbackPolicyProvider.GetPolicyAsync(policyName); var val = policyName.Split(";"); //get locations int[] ia1 = val.FirstOrDefault(k => k.StartsWith(POLICY_PREFIX_ELocation, StringComparison.OrdinalIgnoreCase)) .Substring(POLICY_PREFIX_ELocation.Length) .Split(',').Select(n => Convert.ToInt32(n)).ToArray(); ELocation[] locations = (ELocation[])(object)ia1; int[] ia2 = val.FirstOrDefault(k => k.StartsWith(POLICY_PREFIX_EEntity, StringComparison.OrdinalIgnoreCase)) ?.Substring(POLICY_PREFIX_EEntity.Length) ?.Split(',').Select(n => Convert.ToInt32(n)).ToArray(); EEntity[] entitys = (EEntity[])(object)ia2; var policy = new AuthorizationPolicyBuilder(); policy.AddRequirements(new LEMClaimRequirement(locations, entitys)); return Task.FromResult(policy.Build()); } }
LEMClaimPolicyProvider
强制转换为枚举数组。像这样:var位置=(ia1!=null)?ia1.Cast().ToArray():null我觉得LEMClaimPolicyProvider
中的GetPolicyAsync
非常糟糕。没有更干净的方法吗?对于稍后阅读本文的读者,我对陶舟答案所做的唯一更改是将LEMClaimPolicyProvider
强制转换为枚举数组。像这样:var位置=(ia1!=null)?ia1.Cast().ToArray():null我觉得LEMClaimPolicyProvider
中的GetPolicyAsync
非常糟糕。难道没有更干净的方法吗?