Мне удалось написать атрибут, который позволяет проверять наличие претензии после получения отзывов от nlawalker
и ivamax9
В заключение, класс HasPermissionAttribute
принимает claimType
, а необязательный claimValue
затем создает имя политики. Класс атрибута выглядит следующим образом
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class HasPermissionAttribute : AuthorizeAttribute
{
public const string Policy_Prefix = "HasClaim";
public const string Policy_Glue = ".";
public HasPermissionAttribute(string type, string value = null)
{
Policy = GetPolicyValue(type, value);
}
private string GetPolicyValue(string type, string value)
{
if (string.IsNullOrWhiteSpace(type))
{
throw new ArgumentNullException($"{type} cannot be null.");
}
List<string> parts = new List<string> { type.Replace(Policy_Glue, "_").Trim() };
if (!string.IsNullOrWhiteSpace(value))
{
parts.Add(value.Replace(Policy_Glue, "_"));
}
string policy = $"{Policy_Prefix}{Policy_Glue}{string.Join(Policy_Glue, parts)}";
return policy;
}
}
Теперь, когда у нас есть политика, применяемая через HasPermissionAttribute
, теперь нам нужно взять примененную политику и зарегистрировать ее, используя AuthorizationPolicyBuilder
, которая проверяет, существует ли данное требование или нет. Тем не менее, я добавил класс с именем ClaimCheckerPolicyProvider
, который принимает предоставленную заявку и обрабатывает чек следующим образом
internal class ClaimCheckerPolicyProvider : IAuthorizationPolicyProvider
{
public Task<AuthorizationPolicy> GetDefaultPolicyAsync()
{
return Task.FromResult(new AuthorizationPolicyBuilder().RequireAuthenticatedUser().Build());
}
public Task<AuthorizationPolicy> GetPolicyAsync(string policyName)
{
if (IsClaimBasePolicy(policyName))
{
string[] parts = GetParts(policyName);
if (parts.Length > 0)
{
AuthorizationPolicyBuilder policy = GetPolicyBuilder(parts);
return Task.FromResult(policy.Build());
}
}
return Task.FromResult<AuthorizationPolicy>(null);
}
private bool IsClaimBasePolicy(string policyName)
{
return !string.IsNullOrWhiteSpace(policyName)
&& policyName.StartsWith(HasPermissionAttribute.Policy_Prefix, StringComparison.OrdinalIgnoreCase);
}
private string[] GetParts(string policyName)
{
return policyName.Split(HasPermissionAttribute.Policy_Glue, StringSplitOptions.RemoveEmptyEntries)
.Where(x => !x.Equals(HasPermissionAttribute.Policy_Prefix))
.ToArray();
}
private AuthorizationPolicyBuilder GetPolicyBuilder(string[] parts)
{
if (parts == null)
{
throw new ArgumentNullException($"{nameof(parts)} cannot be null.");
}
var length = parts.Length;
if (length == 0)
{
throw new ArgumentOutOfRangeException($"{nameof(parts)} cannot cannot be empty.");
}
var policy = new AuthorizationPolicyBuilder();
if (length > 1)
{
return policy.RequireClaim(parts[0], parts[1]);
}
return policy.RequireClaim(parts[0]);
}
}
Наконец, нам нужно зарегистрировать провайдера как услугу. В ConfigureServices
класса Startup мы добавляем следующее
services.AddTransient<IAuthorizationPolicyProvider, ClaimCheckerPolicyProvider>();