Ядро asp.net - передать несколько параметров поставщику пользовательской политики авторизации - PullRequest
0 голосов
/ 24 октября 2018

Я пытаюсь настроить провайдера настраиваемой политики в ядре asp.net.Мне нужно передать несколько пользовательских атрибутов авторизации провайдеру, но я не могу понять, как это сделать.

У меня настроен прием одного перечислимого массива в настоящее время, и он работает нормально.Однако я хотел бы добавить еще 2 массива enum в качестве дополнительных необязательных параметров для атрибута авторизации.

Атрибут в том виде, как он есть сейчас:

[LEMClaimAuthorize(new ELocation[] { ELocation.Indy, ELocation.Columbus })]

Хотелось бы, чтобы он работал так:

[LEMClaimAuthorize(new ELocation[] { ELocation.Indy, ELocation.Columbus },
                                           new EEntity[] { EEntity.JobTool })]

LEMClaimAuthorizeAttribute:

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());


    }
}
  1. Это работает только для одного перечислимого массива.
  2. Как мне заставить его работать с другими параметрами массива enum?
  3. Если есть способ получше, в общем у меня все уши

Спасибо за помощь!

1 Ответ

0 голосов
/ 25 октября 2018

Для Custom Policy Provider он использует LEMClaimAuthorizeAttribute для построения Политики, а затем проверяет сгенерированные политики.Для передачи нескольких параметров в LEMClaimAuthorizeAttribute необходимо обратить внимание на процесс создания строки политики и извлечения политик из строки политики.

Для решения выполните следующие действия:

  • LEMClaimAuthorizeAttribute.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;
    }
    }
    
  • LEMClaimPolicyProvider.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());
    }
    }
    
  • Использование

        [LEMClaimAuthorize(new ELocation[] { ELocation.Indy, ELocation.Columbus })]
    public ActionResult One()
    {
        return View();
    }
    [LEMClaimAuthorize(new ELocation[] { ELocation.Indy, ELocation.Columbus }, new EEntity[] { EEntity.JobTool })]
    public ActionResult Two()
    {
        return View();
    }
    
...