web-dev-qa-db-fra.com

L'attribut ASP.NET Core Authorize ne fonctionne pas avec JWT

Je souhaite implémenter la sécurité basée sur JWT dans ASP.Net Core. Tout ce que je veux, pour l'instant, c'est lire les jetons au porteur dans l'en-tête Authorization et les valider par rapport à mes critères. Je n'ai pas besoin (et je ne veux pas) d'inclure l'identité ASP.Net. En fait, j'essaie d'éviter d'utiliser autant de choses que MVC ajoute autant que possible, sauf si j'en ai vraiment besoin.

J'ai créé un projet minimal, qui illustre le problème. Pour voir le code d'origine, il suffit de parcourir l'historique des modifications. Je m'attendais à ce que cet échantillon rejette toutes les demandes pour/api/icons, à moins qu'elles ne fournissent l'en-tête HTTP Authorization avec un jeton de porteur correspondant. L'exemple autorise en fait toutes les requêtes .

Startup.cs

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Configuration;
using Microsoft.AspNetCore.Routing;
using Microsoft.IdentityModel.Tokens;
using System.Text;
using System;
using Newtonsoft.Json.Serialization;

namespace JWTSecurity
{
    public class Startup
    {
        public IConfigurationRoot Configuration { get; set; }

        public Startup(IHostingEnvironment env)
        {
            IConfigurationBuilder builder = new ConfigurationBuilder().SetBasePath(env.ContentRootPath);
            Configuration = builder.Build();
        }

        public void ConfigureServices(IServiceCollection services)
        {
            services.AddOptions();
            services.AddAuthentication();
            services.AddMvcCore().AddJsonFormatters(options => options.ContractResolver = new CamelCasePropertyNamesContractResolver());
        }

        public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
        {
            loggerFactory.AddConsole();
            app.UseJwtBearerAuthentication(new JwtBearerOptions
            {
                AutomaticAuthenticate = true,
                AutomaticChallenge = true,
                TokenValidationParameters = new TokenValidationParameters
                {
                    ValidateIssuerSigningKey = true,
                    IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes("supersecretkey")),
                    ValidateIssuer = false,
                    ValidateAudience = false,
                    ValidateLifetime = true,
                    ClockSkew = TimeSpan.Zero
                }
            });
            app.UseMvc(routes => routes.MapRoute("default", "{controller=Home}/{action=Index}/{id?}"));
        }
    }
}

Contrôleurs/IconsController.cs

using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;

namespace JWTSecurity.Controllers
{
    [Route("api/[controller]")]
    public class IconsController : Controller
    {
        [Authorize]
        public IActionResult Get()
        {
            return Ok("Some content");
        }
    }
}
20
Andrew Williamson

Je l'ai trouvé!

Le problème principal est dans cette ligne:

services.AddMvcCore().AddJsonFormatters(options => options.ContractResolver = new CamelCasePropertyNamesContractResolver());

J'ai remarqué qu'en passant de AddMvcCore () à AddMvc (), l'autorisation a soudainement commencé à fonctionner! Après avoir fouillé dans le code source ASP.NET , pour voir ce que fait AddMvc(), je me suis rendu compte que j'avais besoin d'un deuxième appel, à IMvcBuilder.AddAuthorization().

services.AddMvcCore()
    .AddAuthorization() // Note - this is on the IMvcBuilder, not the service collection
    .AddJsonFormatters(options => options.ContractResolver = new CamelCasePropertyNamesContractResolver());
48
Andrew Williamson

Vous utilisez également l'authentification d'identité et elle contient implicitement l'authentification par cookie. Vous vous êtes probablement connecté avec un schéma d'identité et cela a provoqué une authentification réussie.

Supprimez l'authentification d'identité si elle n'est pas requise (si vous voulez uniquement l'authentification jwt), sinon spécifiez Bearer schéma pour l'attribut Authorize comme ci-dessous:

[Authorize(ActiveAuthenticationSchemes = "Bearer")]
20
adem caglin

Pour ceux qui ont même essayé les réponses des aperçus et qui n'ont pas résolu le problème, voici comment le problème a été résolu dans mon cas.

[Authorize(AuthenticationSchemes="Bearer")]
4
Andre Mendonca