web-dev-qa-db-fra.com

API Web 2, authentification OWIN, déconnexion ne se déconnecte pas

Je fais des recherches pour travailler en vue d'utiliser des jetons Bearer comme mécanisme d'authentification (c'est-à-dire AngularJS UI, authentifie via OWIN dans un projet Web API [2]).

J'ai la connexion qui fonctionne bien, les informations sur le rôle et tout cela va bien, mais je ne peux pas obtenir le jeton pour se déconnecter.

Ma configuration de démarrage est la suivante:

OAuthOptions = new OAuthAuthorizationServerOptions() {
    TokenEndpointPath = new PathString("/Token"),
    Provider = new ApplicationOAuthProvider(PublicClientId),
    AccessTokenExpireTimeSpan = SESSION_TIMEOUT,
    AllowInsecureHttp = true
};

Et mon action de déconnexion est simplement la suivante:

public HttpResponseMessage Logout() {
    var authentication = HttpContext.Current.GetOwinContext().Authentication;
    authentication.SignOut(DefaultAuthenticationTypes.ExternalBearer);

    return new HttpResponseMessage(HttpStatusCode.OK);
}

J'ai laissé tous les éléments d'authentification à des fins de concision, mais pour confirmer que j'utilise ExternalBearer lors de la configuration du jeton.

Dans mon interface utilisateur, je stocke le jeton dans le stockage local (aucun cookie n'est impliqué ici, ce qui est une décision de conception délibérée). J'ai donc un bouton déconnexion sur mon interface utilisateur, l'action Déconnexion est activée et le code fonctionne correctement.

Cependant, si par la suite j'appuie sur une action sur l'API qui nécessite une autorisation, la demande passe toujours (c'est-à-dire que l'utilisateur est toujours authentifié même s'il devrait avoir été déconnecté.

Soit je manque quelque chose de vraiment évident (ce ne serait pas la première fois ;-), soit il y a quelque chose de plus fondamental qui se passe ici - enfin, je cingle @leastprivilege car je sais que c'est leur domaine.

Toute aide ou information serait reçue avec gratitude.


La seule chose à laquelle je peux penser est que le jeton est sans état côté serveur/API et ne peut donc pas être expiré ou déconnecté.

Si tel est le cas, je suppose que je pourrais soit:

a) Ajoutez un jeton d'actualisation qui crée un nouveau jeton qui expire dans le passé - cela fonctionnerait-il même? - en fait annuler cela, il émettrait un nouveau jeton ... l'ancien serait toujours valide

b) Stockez le jeton porteur dans la base de données et vérifiez à chaque fois, en supprimant le jeton à la déconnexion (naturellement salé, haché, etc.). Cependant, cela nous ramène à avoir un serveur avec état.

c) Je peux (et je vais) supprimer le jeton du stockage local lorsque quelqu'un se déconnecte explicitement, mais le jeton est toujours techniquement valide si un méchant peut intercepter le jeton. Naturellement, tout ce qui précède sera terminé SSL de toute façon, ce qui devrait inhiber les méchants/filles .

d) C'est peut-être la raison pour laquelle de nombreuses personnes stockent le jeton de porteur dans un cookie (en tant que mécanisme de stockage) .Ainsi, une fois que vous vous déconnectez, le cookie sera supprimé au prochain rafraîchissement.

Désolé, ce qui précède est un peu une décharge de cerveau, je veux juste anticiper toutes les questions

30
toepoke.co.uk

Puisque OAuth n'est pas un protocole d'authentification, il n'y a aucune notion de déconnexion. Supprimez le jeton d'accès sur le client - c'est tout ce que vous pouvez faire.

Si vous souhaitez invalider le jeton côté serveur, ajoutez-y un identifiant unique et gardez une trace dans votre service - vous devrez créer manuellement quelque chose comme ça.

37
leastprivilege

J'ai une belle solution ici: http://www.nakov.com/blog/2014/12/22/webapi-owin-identity-custom-login-service/ . Il s'agit d'une implémentation de session utilisateur personnalisée pour l'API Web OAuth autorisation de jeton de support basée sur OWIN et l'identité ASP.NET standard (Microsoft.AspNet.Identity.EntityFramework). Il fonctionne comme la plupart des gens peuvent s'y attendre:

  • Les sessions d'API Web meurent après 30 minutes d'inactivité.
  • La durée de vie de la session est prolongée à chaque demande HTTP autorisée avec 30 minutes supplémentaires.
  • La déconnexion fonctionne correctement: après déconnexion, le support access_token devient invalide (il est révoqué).

Le code source de travail complet est disponible sur GitHub: https://github.com/SoftUni/SPA-with-AngularJS/tree/master/Ads-REST-Services

16
Svetlin Nakov

Cette question est là depuis des lustres (et a également répondu), mais je voulais seulement faire sonner mes pensées.

Je ferais la même chose que votre option (C), mais utiliser une expiration plus courte sur le jeton d'accès au porteur quelque chose comme 10 ou 20 minutes, de sorte que lorsque vous vous êtes déconnecté et supprimé le jeton sur le client, bien que techniquement le jeton soit toujours valide , le méchant n'aura que le reste du temps d'expiration pour jouer avec votre jeton valide.

En pratique, j'utiliserais cela avec un jeton d'actualisation de longue durée, afin de pouvoir obtenir un nouveau jeton de support s'il expire et que je souhaite continuer à interagir avec les ressources de l'API, sans avoir à m'authentifier à nouveau.

2
jaeyow

Tant que je sais que le jeton du porteur vit du côté client, je ne pense pas que vous ayez besoin d'une fonction de "déconnexion" côté serveur. Il suffit de supprimer le jeton du stockage local du client pour vous déconnecter.

1
Ghidello