web-dev-qa-db-fra.com

Utilisation conjointe de jetons au porteur et d'authentification par cookie

J'ai une application d'une seule page - plus ou moins basée sur le modèle MVC5 SPA - utilisant jetons au porteur pour l'authentification.

Le site dispose également de quelques pages MVC conventionnelles qui doivent être sécurisées, mais en utilisant authentification par cookie.

Dans Startup.Auth, je peux activer les deux types d'autorisation:

app.UseCookieAuthentication(new CookieAuthenticationOptions());
app.UseOAuthBearerTokens(OAuthOptions);

Cependant, cela semble avoir un effet secondaire dans la mesure où chaque fois qu'une demande AJAX est envoyée depuis le SPA, elle envoie à la fois le jeton du porteur dans l'en-tête et le cookie .

Alors que le comportement que je veux vraiment est que niquement le jeton porteur soit utilisé pour les appels WebAPI, et uniquement le cookie pour les appels MVC.

J'aimerais également que les appels MVC soient redirigés vers une page de connexion lorsqu'ils ne sont pas autorisés (définis comme CookieAuthenticationOption), mais je ne veux évidemment pas que cela se produise lors d'un appel API.

Existe-t-il un moyen d'avoir ce type d'authentification en mode mixte dans une seule application? Peut-être via un filtre de chemin/route?

63
Appetere

Je pense que j'ai travaillé cela: -

Démarrage.Auth est en train de câbler le pipeline OWIN, il est donc juste d'y inclure des cookies et des jetons. Mais une modification des options de cookie spécifie le type d'authentification auquel elle doit s'appliquer:

CookieOptions = new CookieAuthenticationOptions
{
  AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie   
};

Ensuite, je devais configurer WebAPI pour utiliser uniquement des jetons:

public static void Configure(HttpConfiguration config)
{
   // Configure Web API to use only bearer token authentication.
   config.SuppressDefaultHostAuthentication();
   config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType));
}

Cela semble réaliser ce que je veux. WebAPI utilise uniquement des jetons au porteur et aucun cookie, et quelques pages MVC conventionnelles utilisent des cookies une fois connecté (à l'aide d'AuthenticationManager).

46
Appetere

vous pouvez ajouter un jeton jwt au cookie (ici mon nom de cookie de jeton jwt est "access_token") en mode http uniquement, et créer un middleware comme celui-ci

public class JwtCookieMiddleware
{
    private readonly RequestDelegate _next;

    public JwtCookieMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    public Task Invoke(HttpContext ctx)
    {
        if (ctx.Request.Cookies.TryGetValue("access_token", out var accessToken))
        {
            if (!string.IsNullOrEmpty(accessToken))
            {
                string bearerToken = String.Format("Bearer {0}", accessToken);
                ctx.Request.Headers.Add("Authorization",bearerToken);
            }
        }
        return this._next(ctx);
    }
}
public static class JwtCookieMiddlewareExtensions
{
    public static IApplicationBuilder UseJwtCookie(this IApplicationBuilder build)
    {
        return build.UseMiddleware<JwtCookieMiddleware>();
    }
}

Et vous devez utiliser le middleware au démarrage comme ceci:

app.UseJwtCookie();
app.UseAuthentification();
app.UseMvc();

le code ci-dessus ajoutera un jeton jwt à l'en-tête de demande http si cette demande avec un cookie de jeton;

3
xiongkailing