web-dev-qa-db-fra.com

Authentification par jeton JWT, jetons expirés fonctionnant toujours, noyau Web. Api Web

Je suis en train de créer une API web de base .net.

Préface - J'ai implémenté l'authentification par jeton selon https://stormpath.com/blog/token-authentication-asp-net-core et https://dev.to/samueleresca/development-token-authentication-using-aspnet-core . J'ai également lu quelques numéros sur github et ici sur SO.

Cela a également été utile https://goblincoding.com/2016/07/24/asp-net-core-policy-based-authorisation-using-json-web-tokens/ .

Après avoir implémenté tout cela, j'ai l'impression de manquer quelque chose.

J'ai créé une simple Angular qui se trouve dans un client Web. Lorsque je m'authentifie, le client reçoit un jeton. Je le stocke en session pour l'instant (toujours en dev, l'adresse problèmes de sécurité quant à l'endroit où le stocker plus tard).

Pas vraiment sûr que ceci ( JWT (JSON Web Token) prolongation automatique de l'expiration ) soit utile car je n'ai pas implémenté de jetons de rafraîchissement pour autant que je puisse voir.

J'ai remarqué que lorsque j'appelle à la déconnexion, puis que je me reconnecte, le client reçoit un nouveau jeton, comme prévu. Cependant, si le délai d'expiration du jeton est passé (je l'ai défini sur 1 minute pour les tests), puis que la page est actualisée, le jeton semble rester le même dans mon application. c'est-à-dire. c'est comme si le jeton n'expire jamais?!

Je m'attendais à ce que le client reçoive une erreur 401 non autorisée et je peux alors gérer le fait de forcer l'utilisateur à se réauthentifier.

N'est-ce pas ainsi que cela devrait fonctionner? Y a-t-il une magie de jeton d'actualisation automatique en arrière-plan qui est par défaut (je n'ai pas configuré de notion de jetons de rafraîchissement dans les tutoriels explicitement)? Ou est-ce que je manque quelque chose sur le concept d'authentification par jeton?

Aussi - s'il s'agit d'un jeton perpétuellement rafraîchissant, dois-je m'inquiéter de la sécurité si le jeton a été compromis?

Merci de votre aide

15
Jamadan

Je crois que cela a à voir avec ClockSkew dans JwtBearerOptions.

Passez à TimeSpan.Zero car je crois que la valeur par défaut est définie sur 5 minutes (pas sûr à 100% cependant).

J'ai posté un exemple de code ci-dessous qui doit être placé dans Startup.cs => Configurer.

        app.UseJwtBearerAuthentication(new JwtBearerOptions()
        {
            AuthenticationScheme = "Jwt",
            AutomaticAuthenticate = true,
            AutomaticChallenge = true,
            TokenValidationParameters = new TokenValidationParameters()
            {
                ValidAudience = Configuration["Tokens:Audience"],
                ValidIssuer = Configuration["Tokens:Issuer"],
                ValidateIssuerSigningKey = true,
                IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["Tokens:Key"])),
                ValidateLifetime = true,
                ClockSkew = TimeSpan.Zero
            }
        });
38
DJDJ

Si votre heure d'expiration est bien supérieure à la valeur par défaut (5 minutes) ou supérieure à une heure définie comme je l'avais et qu'elle considère toujours le jeton expiré comme valide, et en définissant ClockSkew sur TimeSpan.Zero n'a aucun effet, assurez-vous d'avoir la propriété

ValidateLifetime 

mis à true comme j'avais le mien réglé à false causant le problème, ce qui est tout à fait logique, mais c'était une surveillance facile.

services.AddAuthentication(option =>
    {
        option.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
        option.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
    })
    .AddJwtBearer(options =>
    {
        options.TokenValidationParameters = new TokenValidationParameters
        {
            ValidateIssuer = true,
            ValidateAudience = true,
            ValidateLifetime = true,
            ValidateIssuerSigningKey = true,
            ValidIssuer = Configuration["JwtToken:Issuer"],
            ValidAudience = Configuration["JwtToken:Issuer"],
            IssuerSigningKey = new SymmetricSecurityKey(
               Encoding.UTF8.GetBytes(Configuration["JwtToken:SecretKey"]))
        };
    });
3
Thierry