É possível executar todos os manipuladores para uma política in-line em vez de com um atributo?


8

Na maioria das minhas APIs, eu simplesmente faço uma autorização como esta:

[Authorize(Policy = "Foo")]
public MyApi()

Eu recebo essa política de um NuGet e não consigo modificá-la.

Para algumas das minhas APIs, nem sempre quero ter essa política. Isso precisa ser resolvido em tempo de execução com base em algumas configurações. Eu gostaria de alguma maneira de executar isso em linha e garantir que todos os manipuladores que estão configurados sejam executados.

Depois de muita pesquisa, descobri que crio um IAuthorizationServicee utilizo isso para chamar AuthorizeAsync. Parece que é isso que eu quero, mas o problema que estou enfrentando agora é que todos os manipuladores dependem de AuthorizationFilterContextcomo recurso no contexto. Isso parece acontecer automaticamente quando a Autorização é feita através do atributo, mas não através da chamada para AuthorizeAsync. Ele precisa ser passado manualmente neste caso. Meu código agora está assim:

public MyApi()
{
    var allowed = await _authorizationService.AuthorizeAsync(User, null, "Foo").ConfigureAwait(false);
}

Isso parece passar por todos os meus manipuladores corretamente, mas eles não funcionam devido à falta do AuthorizationFilterContext.

1) Essa é a abordagem correta para começar, ou existe alguma outra maneira de fazer isso em linha? Eu estou supondo que provavelmente haja alguma maneira de criar minha própria política que envolva esta e eu possa verificar a configuração lá, mas se houver uma abordagem simples em linha, eu preferiria isso.

2) Se esse caminho for válido, existe uma boa maneira de obter o AuthorizationFilterContext? Tentei criá-lo manualmente, mas receio que isso não esteja correto sem passar mais dados do contexto, mas não consigo encontrar bons exemplos / doc:

new AuthorizationFilterContext(new ActionContext(HttpContext, HttpContext.GetRouteData(), new ActionDescriptor()), new IFilterMetadata[] { });


Essa é uma maneira muito ruim de fazer isso. Antes de tudo, qualquer chamada pode atingir seu método api agora, mesmo que não tenha acesso, porque você faz a verificação de acesso posteriormente. Crie um atributo personalizado para si mesmo e você pode facilmente verificar se a política (única ou múltipla) que você deseja verificar pertence ao usuário ou não. Também é bom ler isso: docs.microsoft.com/en-us/aspnet/ núcleo / segurança / autorização /…
curiousBoy 25/02

Respostas:


-2

Não haverá AuthorizationFilterContextquando você estiver fora do pipeline de autorização. Portanto, você não deve lidar com a autenticação embutida com IAuthorizationService.

Isso parece passar por todos os meus manipuladores corretamente, mas eles não funcionam devido à falta do AuthorizationFilterContext.

Parece que você tem o controle sobre os manipuladores de autenticação. Você já tentou a autenticação de curto-circuito dentro do manipulador, se não for necessário?

O manipulador pode obter serviços via DI, para que você possa colocar a configuração de tempo de execução necessária via IOptions ou IHttpContextAccessor e assim por diante.


-2

Você não pode criar seu próprio Authorizeatributo que herdaria o atual e resolveria a política internamente? Ou melhor ainda, tente usarIAuthorizationPolicyProvider

class MyPolicyProvider : IAuthorizationPolicyProvider
{
    private DefaultAuthorizationPolicyProvider BackupPolicyProvider { get; }

    public MyPolicyProvider()
    {
        BackupPolicyProvider = new DefaultAuthorizationPolicyProvider(options);
    }

    public Task<AuthorizationPolicy> GetPolicyAsync(string policyName)
    {
        if (policyName.Equals("Foo"))
        {
            bool myConditionToAvoidPolicy = true;
            if (myConditionToAvoidPolicy)
            {
                return Task.FromResult<AuthorizationPolicy>(null);
            }
        }

        return BackupPolicyProvider.GetPolicyAsync(policyName);
    }
}

Isso não foi testado, mas você pode encontrar mais informações aqui .


-2

Sua condição de verificação parece acontecer mais tarde, o que eu não acho que seja uma boa ideia. Seu método api está vulnerável e ainda está aberto, pois sua verificação é feita posteriormente. Mas, usando o atributo, você pode capturá-lo no nível anterior e ainda pode aplicar a lógica customizada. No final do dia, tudo o que decide é "sim, tenha acesso" ou "não, não há acesso para você !!" Abaixo não é testado, mas você deve:

public class CustomAuthorize : AuthorizeAttribute
{
    private readonly PermissionAction[] permissionActions;

    public CustomAuthorize(PermissionItem item, params PermissionAction[] permissionActions)
    {
        this.permissionActions = permissionActions;
    }

    public override void OnAuthorization(HttpActionContext actionContext)
    {
        var currentIdentity = System.Threading.Thread.CurrentPrincipal.Identity;
        if (!currentIdentity.IsAuthenticated) {
            // no access
        }

        bool myCondition = "money" == "happiness"; 
        if(myCondition){
           // do your magic here...
        }
        else{
          // another magic...
       }           
    }
}
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.