ASP.NET Core Authorize属性不适用于JWT
我想在ASP.Net Core中实现基于JWT的安全性.我现在想要做的就是读取Authorization
标头中的承载令牌,并根据我的标准对其进行验证.我不需要(也不想)包含ASP.Net Identity.实际上,除非我确实需要,否则我将尽量避免使用MVC添加的尽可能多的东西.
I want to implement JWT-based security in ASP.Net Core. All I want it to do, for now, is to read bearer tokens in the Authorization
header and validate them against my criteria. I don't need (and don't want) to include ASP.Net Identity. In fact, I'm trying to avoid using as many of the things that MVC adds in as possible unless I really need them.
我创建了一个最小的项目,演示了该问题.要查看原始代码,只需查看编辑历史记录即可.我期望该示例拒绝对/api/icons
的所有请求,除非它们为Authorization
HTTP标头提供了相应的承载令牌.样本 实际上允许所有请求 .
I've created a minimal project, which demonstrates the problem. To see the original code, just look through the edit history. I was expecting this sample to reject all requests for /api/icons
unless they provide the Authorization
HTTP header with a corresponding bearer token. The sample actually allows all requests.
Startup.cs
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?}"));
}
}
}
Controllers/IconsController.cs
Controllers/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");
}
}
}
找到了!
主要问题在这一行:
services.AddMvcCore().AddJsonFormatters(options => options.ContractResolver = new CamelCasePropertyNamesContractResolver());
我注意到,通过从AddMvcCore()切换到AddMvc(),授权突然开始起作用了!在深入研究 ASP.NET源代码之后,了解AddMvc()
的用途,我意识到我需要第二次呼叫IMvcBuilder.AddAuthorization()
.
I noticed that by switching from AddMvcCore() to AddMvc(), the authorization suddenly started working! After digging through the ASP.NET source code, to see what AddMvc()
does, I realized that I need a second call, to IMvcBuilder.AddAuthorization()
.
services.AddMvcCore()
.AddAuthorization() // Note - this is on the IMvcBuilder, not the service collection
.AddJsonFormatters(options => options.ContractResolver = new CamelCasePropertyNamesContractResolver());