Où dois-je insérer l'autorisation dans Asp.net WebAPI?

comme je le vois j'ai 3 endroits possibles pour brancher mes affaires dans le pipeline

1)     AuthorizationFilters

2)     Action Filters

3)     DelegatingHandler

le plus évident est AuthorizationFilters, où je peux décorer mes actions / controllers avec mon attribut custom authorization. dire. . MyCustomAuthorizationAttribute .

puisque les gestionnaires de messages HTTP en sont à la première étape du traitement. Il ne fait aucun sens de le mettre là ?

Autoriser pour moi maintenant signifie simplement vérifier un token dans l'en-tête qui est donnée au client après authentification.

25
demandé sur ashutosh raina 2013-02-14 13:48:02
la source

1 ответов

Mise À Jour Juillet 2014

ma réponse originale couvrait le WebApi 1. avec WebApi 2 Il y a eu quelques changements, c'est-à-dire qu'il y a maintenant un IAuthenticationFilter ce qui signifie que vous pouvez déplacer logique d'authentification de l' DelegatingHandler qui est un peu plus élégant.

Il y a un Nuget projet ici qui offre une mise en œuvre de IAuthenticationFilter et explique également un certain contexte à son introduction.

OWIN middleware est maintenant peut-être le meilleur endroit pour implémenter votre logique d'authentification - il y a un exemple d'authentification de certificat ici et l'Authentification de Base OWIN Middleware ici ce billet de blog l'exemple précédent est privilégiée car elle illustre l'utilisation de la base AuthenticationHandler classe.

le Conseil sur AuthorizationFilters reste en grande partie inchangée.

Mise À Jour

typiquement...

Utiliser DelegatingHandler pour réaliser Authentication... c'est à dire quelqu'un qui est. Utilisez ceci pour définir le principe du Thread et du contexte utilisateur, ajouter des revendications, etc. Vous pouvez aussi placer la logique d'autorisation ici, mais à une échelle assez globale. Personnellement, j'utiliserais toujours les filtres D'autorisation pour obtenir une autorisation.

Utiliser AuthorizationFilters pour restreindre les contrôleurs et les actions à des personnes spécifiques. Ceux-ci sont utilisés lorsque vous pouvez extrapoler leur permission avec les informations contenues dans les paramètres claims, principal, url ou les requêtes http. Le le filtre d'autorisation par défaut peut être utilisé pour restreindre l'accès aux utilisateurs anonymes ou par rôles (si défini dans quelque chose comme un gestionnaire de délégation) - évidemment, vous pouvez implémenter vos propres filtres D'autorisation aussi si vous en avez besoin.

occasionnellement utiliser ActionFilters quand vous avez besoin de prendre la décision sur l'autorisation en utilisant le contenu du message par exemple, vous avez besoin d'accéder à une propriété sur l'entité pour décider s'ils ont accès (évidemment faire attention avec ce(!)).

Remarque:

AuthorizationFilters sont appelés avant que le contenu du corps soit lu donc ils n'ont pas accès au corps du message pour prendre des décisions d'autorisation c'est pourquoi le ActionFilters précisément OnActionExecuting est utilisé pour des erreurs occasionnelles d'authentification.

Dans votre scénario, je mettrais un simple DelegatingHandler pour prendre votre en-tête et régler le principal.

public class CustomAuthenticationMessageHandler : DelegatingHandler
{


    public CustomAuthenticationMessageHandler ()
    {

    }

    protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request,
                                                           CancellationToken cancellationToken)
    {
        Authenticate(request);

        return base.SendAsync(request, cancellationToken);
    }

    protected virtual void Authenticate(HttpRequestMessage request)
    {

        var authorisationHeader = request.Headers.Authorization;

        if (authorisationHeader == null)
        {
            return;
        }

        //Ensure you are happy with the header contents then

        {
            var principal = new GenericPrincipal(//new Identity , //Roles);
            Thread.CurrentPrincipal = principal;
            HttpContext.Current.User = principal;
        }

    }
}

alors utilisez AuthorizationFilters pour restreindre l'accès:

    [Authorize]
    public string Get()
    {

    }

    [Authorize(Roles = "Admin")]
    public string GetAdminOnly()
    {

    }

pour enregistrer l'authentification globale

config.MessageHandlers.Add(new CustomAuthenticationMessageHandler());

cela signifie que dans chaque requête le principal sera défini à null ou à une identité valide. Il ne gérera pas l'autorisation, c'est-à-dire qu'il ne refusera pas l'accès aux contrôleurs ou aux actions.

pour commencer À protéger les ressources

soit cibler les contrôleurs protégés et les actions avec la norme ou la coutume [Autoriser] attribut. Ou s'inscrire dans le monde entier:

config.Filters.Add(new AuthorizeAttribute());

et seulement la liste blanche des controllers et des actions que vous voulez non sécurisé en utilisant le [AllowAnonymous] l'attribut.

si vous voulez seulement l'authentification sur certaines routes

alors vous pouvez modifier votre DelegatingHandler un peu pour mettre le InnerHandler pour diriger vers le bon contrôleur par exemple

public CustomAuthenticationMessageHandler(HttpConfiguration configuration)
{
       InnerHandler = new HttpRoutingDispatcher(configuration);
}

et ensuite vous pouvez spécifier ce handler sur vos routes comme suit:

config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "myurl",
            defaults: new {},
            constraints: new {},
            handler: new CustomAuthenticationHandler(config)
            );
37
répondu Mark Jones 2014-07-08 16:43:03
la source

Autres questions sur