基于权限的基于声明策略的授权

时间:2019-12-03 15:30:37

标签: asp.net-core .net-core claims-authentication

每个控制器页面都有单独的授权。只要具有访问权限,此授权就必须有效。我在以下类中使用Permission_Access进行此操作。但是,当用户没有任何权限时,它将返回403错误。我们可以自定义这些错误代码吗?

例如,当Permission_Acces不存在时,我想返回一个不同的错误消息,我该怎么做?

我真正想做的是向其中一个权限添加条件。

这些是我的代码->

AuthorizationPolicyProvider.cs

    public override Task<AuthorizationPolicy> GetPolicyAsync(string policyName)
    {

        if (!policyName.StartsWith(PermissionAuthorizeAttribute.PolicyPrefix, StringComparison.OrdinalIgnoreCase))
        {
            return base.GetPolicyAsync(policyName);
        }

        var permissionNames = policyName.Substring(PermissionAuthorizeAttribute.PolicyPrefix.Length).Split(',');

        var policy = new AuthorizationPolicyBuilder()
            .RequireAuthenticatedUser()
            .RequireClaim(PermissionAuthorizeAttribute.PolicyPrefix, permissionNames)
            .Build();

        return Task.FromResult(policy);
    }

PermissionAuthorizeAttribute.cs

internal const string PolicyPrefix = "PERMISSION:";

/// <summary>
/// Creates a new instance of <see cref="AuthorizeAttribute"/> class.
/// </summary>
/// <param name="permissions">A list of permissions to authorize</param>
public PermissionAuthorizeAttribute(params string[] permissions)
{
    Policy = $"{PolicyPrefix}{string.Join(",", permissions)}";
}

PermissionsAuth.cs

public class PermissionsAuth
{

    public const string Permission_Access = nameof(Permission_Access); // Accessing Perms.
    public const string Permission_All = nameof(Permission_All);// All Perms.
}

ClaimProvider.cs

    public async Task<ClaimsPrincipal> TransformAsync(ClaimsPrincipal principal)
    {
        if (principal != null && principal.Identity.IsAuthenticated)
        {
            ClaimsIdentity identity = principal.Identity as ClaimsIdentity;

            ApplicationUser user = await userManager.FindByIdAsync(identity.Claims.FirstOrDefault(x => x.Type == ClaimTypes.NameIdentifier).Value);

            if (user != null)
            {
                if (principal.IsInRole("Owner"))
                {
                    var perm_all = identity.Claims.FirstOrDefault(x => x.Type == "PERMISSION:" && x.Value == PermissionsAuth.Permission_All);

                    if (perm_all == null)
                    {
                        identity.AddClaim(new Claim("PERMISSION:", PermissionsAuth.Permission_All, ClaimValueTypes.String, "Internal"));
                    }

                }

                List<Claim> claims = identity.Claims.Where(x => x.Type == "PERMISSION:").ToList();

                claims.ForEach(c => identity.RemoveClaim(c));

                foreach (var item in claims.ToList())
                {
                    int count = claims.Count(x => x.Type == item.Type && x.Value == item.Value);
                    if (count == 1)
                    {
                        identity.AddClaim(item);
                    }
                }

                Claim firmClaim = identity.Claims.FirstOrDefault(x => x.Type == "FIRM");
                var firm = JsonConvert.DeserializeObject<Firm>(firmClaim.Value);

                if (firmClaim != null)
                {
                    Claim access = identity.Claims.FirstOrDefault(x => x.Type == "PERMISSION:" && x.Value == PermissionsAuth.Permission_Access);

                    if (access.Value.Any())
                    {
                        if (firm.ServiceTime < DateTime.Now || firm.ServiceTime == null)
                        {
                            identity.RemoveClaim(access);
                        }
                    }
                }
            }
        }

        return principal;
    }

0 个答案:

没有答案