J'essaie de comprendre le nouveau processus d'authentification du jeton de portage OWIN dans le modèle d'application à page unique dans MVC 5. Veuillez me corriger si je me trompe. Pour le flux d'authentification client du mot de passe OAuth, l'authentification du jeton de porteur fonctionne en vérifiant l'en-tête de demande d'autorisation HTTP. pour que le code de jeton d'accès au porteur vérifie si une demande est authentifiée, il ne s'appuie pas sur un cookie pour vérifier si une demande particulière est authentifiée.
Selon ce post:
Exemple d'authentification de jeton de support OWIN avec l'API Web
public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
{
using (IdentityManager identityManager = _identityManagerFactory.CreateStoreManager())
{
if (!await identityManager.Passwords.CheckPasswordAsync(context.UserName, context.Password))
{
context.SetError("invalid_grant", "The user name or password is incorrect.");
return;
}
string userId = await identityManager.Logins.GetUserIdForLocalLoginAsync(context.UserName);
IEnumerable<Claim> claims = await GetClaimsAsync(identityManager, userId);
ClaimsIdentity oAuthIdentity = CreateIdentity(identityManager, claims,
context.Options.AuthenticationType);
ClaimsIdentity cookiesIdentity = CreateIdentity(identityManager, claims,
_cookieOptions.AuthenticationType);
AuthenticationProperties properties = await CreatePropertiesAsync(identityManager, userId);
AuthenticationTicket ticket = new AuthenticationTicket(oAuthIdentity, properties);
context.Validated(ticket);
context.Request.Context.Authentication.SignIn(cookiesIdentity);
}
}
La fonction GrantReourceOwnerCredentials ne compose pas seulement le ticket avec cette ligne: context.Validated (ticket); mais il compose également une identité de cookie et le définit comme suit: context.Request.Context.Authentication.SignIn (cookiesIdentity);
Mes questions sont donc les suivantes: quel est le but exact du cookie dans cette fonction? AuthenticationTicket ne devrait-il pas suffire à l'authentification?
Dans le modèle SPA, il existe en réalité deux mécanismes d'authentification distincts: l'authentification par cookie et l'authentification par jeton. Cela active l'authentification des actions des contrôleurs MVC et Web API, mais nécessite une configuration supplémentaire.
Si vous regardez dans la méthode WebApiConfig.Register, vous verrez cette ligne de code:
config.SuppressDefaultHostAuthentication();
Cela indique à l'API Web d'ignorer l'authentification par cookie, ce qui évite à l'hôte de problèmes expliqués dans le lien que vous avez posté dans votre question :
"... le modèle SPA active le middleware de cookie d'application en mode actif afin d'activer d'autres scénarios tels que l'authentification MVC. Ainsi, l'API Web sera toujours authentifiée si la demande comporte un cookie de session, mais sans jeton de support. Comme vous le feriez pour les attaques CSRF de vos API. Si la requête n’est pas autorisée, les deux composants du middleware le mettront en jeu. Le middleware du cookie modifiera la réponse 401 en un message de redirection vers la page de connexion. Ce n’est pas non plus ce que vous voulez dans une demande d’API Web. "
Alors maintenant, avec l'appel à config.SuppressDefaultHostAuthentication()
, les appels d'API Web nécessitant une autorisation ignorent le cookie automatiquement envoyé avec la demande et recherchent un en-tête d'autorisation commençant par "porteur". Les contrôleurs MVC continueront à utiliser l'authentification par cookie et ignorent le mécanisme d'authentification par jeton car ce n'est pas un très bon point de départ pour l'authentification de page Web.
L'existence du cookie m'a également laissé perplexe, car il n'est clairement pas nécessaire dans un scénario d'authentification de jeton de porteur ... Dans this post, l'auteur dissèque le modèle de compte individuel et dit ce qui suit à propos du cookie:
La méthode définit également un cookie d'application. Je ne vois pas de bonne raison pour cela.
Je suppose que les auteurs du modèle voulaient montrer des exemples de différents types de logique d’authentification et, dans ce cas particulier, montrer comment les informations d’authentification pouvaient être stockées à la fois dans la charge JSON d’authentification de jeton du porteur et dans un fichier. cookie d'authentification standard.
Le fait que la charge d'authentification JSON soit définie pour inclure également une propriété non chiffrée supplémentaire (inutile) (l'id d'utilisateur), en plus du ticket chiffré, semble appuyer cette théorie:
var properties = CreateProperties(user.UserName);
var ticket = new AuthenticationTicket(oAuthIdentity, properties);
Il semble que les auteurs du modèle aient voulu fournir des exemples utiles, plutôt que le strict minimum nécessaire pour réaliser l'authentification par jeton de support. Ceci est également mentionné dans le post lié ci-dessus.
Le cookie a un objectif important. Sa valeur contient le jeton porteur qui peut être extrait par javascript côté client sur vos pages. Cela signifie que si l'utilisateur appuie sur F5 ou actualise la page, le cookie persistera généralement. Votre javascript côté client peut ensuite extraire le jeton porteur du cookie lorsque la page est rechargée.