[英]Asp.Net Web Api JWT Authorization With Identity Always Getting 401
I'm using Asp.Net Core 5, and Asp.Net Identity with EFcore.我正在使用 Asp.Net Core 5,以及带有 EFcore 的 Asp.Net Identity。 I've followed parts of many video tutorials, advice posted here on SO and this very helpful article to get my project to the point where I'm at least getting 401's.
我已经关注了许多视频教程的部分内容,在 SO 上发布的建议以及这篇非常有用的文章,以使我的项目达到我至少获得 401 的程度。 My problem is now that I can't understand why I am getting 401's.
我现在的问题是我不明白为什么我会得到 401。 I've validated my token with my secret on jwt.io and everything tells me that it should be working, but it is not.
我已经用我在 jwt.io 上的秘密验证了我的令牌,一切都告诉我它应该可以工作,但事实并非如此。 I am at a complete loss.
我完全不知所措。 Enough fluff, down to business.
废话不多说,说正事。
My Startup Class.我的启动 Class。 Note: in the OnMessageReceived event context.Token is null until I set it with the authorization header.
注意:在 OnMessageReceived 事件上下文中。令牌是 null,直到我使用授权 header 设置它。
//imports
namespace auto_highlighter_iam
{
public class Startup
{
private readonly IConfiguration _config;
private readonly IWebHostEnvironment _env;
public Startup(IConfiguration config, IWebHostEnvironment env)
{
_config = config;
_env = env;
}
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<DataContext>(options =>
{
options.UseNpgsql(_config.GetConnectionString("AutoHighlighterIAMDev"));
});
IdentityBuilder iBuilder = services.AddIdentityCore<IdentityUser>(options =>
{
options.User.AllowedUserNameCharacters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._ ";
options.Password.RequiredLength = 12;
options.Password.RequireDigit = false;
options.Password.RequireLowercase = false;
options.Password.RequireUppercase = false;
options.Password.RequireNonAlphanumeric = false;
options.User.RequireUniqueEmail = true;
//options.SignIn.RequireConfirmedEmail = true;
});
iBuilder = new IdentityBuilder(iBuilder.UserType, typeof(IdentityRole), iBuilder.Services)
.AddEntityFrameworkStores<DataContext>()
.AddRoleManager<RoleManager<IdentityRole>>()
.AddSignInManager<SignInManager<IdentityUser>>();
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(config =>
{
config.Events = new JwtBearerEvents()
{
OnMessageReceived = context =>
{
// Interesting note here. before this next line context.Token is null, but the authorization header has the jwt
context.Token = context.Request.Headers[HeaderNames.Authorization];
// Although the previous line successfully set context.Token to the jwt still getting 401's
return Task.CompletedTask;
}
};
config.RequireHttpsMetadata = !_env.IsDevelopment();
config.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuerSigningKey = true, //tried as false
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_config["JWT:Secret"])),
ValidateIssuer = true, //tried as false
ValidIssuer = _config["JWT:Iss"],
ValidateAudience = true, //tried as false
ValidAudience = _config["JWT:Aud"]
};
});
services.AddAuthorization();
services.AddControllers();
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new OpenApiInfo { Title = "auto_highlighter_iam", Version = "v1" });
c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
{
In = ParameterLocation.Header,
Description = "Insert JWT with Bearer into field",
Name = "Authorization",
Type = SecuritySchemeType.ApiKey
});
c.AddSecurityRequirement(new OpenApiSecurityRequirement {
{
new OpenApiSecurityScheme
{
Reference = new OpenApiReference
{
Type = ReferenceType.SecurityScheme,
Id = "Bearer"
}
},
Array.Empty<string>()
}
});
});
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, DataContext dataContext)
{
dataContext.Database.Migrate();
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseSwagger();
app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "auto_highlighter_iam v1"));
}
app.UseExceptionHandler("/exception");
app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthorization();
app.UseAuthentication();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
}
}
My AuthorizationController.我的授权控制器。 There are three endpoints.
有三个端点。 Two to test the roles I have and one that should test for any valid jwt.
两个用来测试我的角色,一个用来测试任何有效的 jwt。 All of them return a 401.
它们都返回 401。
// imports
namespace auto_highlighter_iam.Controllers
{
[ApiController]
[Route("/api-v1/[controller]")]
public class AuthorizationController : ControllerBase
{
[HttpGet("[action]")]
[Authorize(Roles = "SUPERADMIN")]
public IActionResult TestSuperAdmin()
{
return Ok();
}
[HttpGet("[action]")]
[Authorize(Roles = "DEFAULT")]
public IActionResult TestDefault()
{
return Ok();
}
[HttpGet("[action]")]
[Authorize]
public IActionResult TestAny()
{
return Ok();
}
}
}
The JWT I am testing with (pretend the token isn't expired, I've been making sure it's valid)我正在测试的 JWT (假设令牌未过期,我一直在确保它有效)
eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJWSUVXIjoiRmFsc2UiLCJFRElUIjoiRmFsc2UiLCJERUxFVEUiOiJGYWxzZSIsIkNSRUFURSI6IkZhbHNlIiwicm9sZXMiOiJERUZBVUxUIiwibmJmIjoxNjExMTIxNTI1LCJleHAiOjE2MTExMjUxMjUsImlzcyI6ImF1dG8taGlnaGxpZ2h0ZXItaWFtIiwiYXVkIjoiYXV0by1oaWdobGlnaHRlci1mcm9udC1lbmQifQ.jnbW552pr7kylc82-4FmJJMmaeu7LQ7L48M5cdnSzuMsA1yRuts9sXUQ2_ok41SqX8mFpi7yreJJXGlE6qC1vA
The request I am sending我发送的请求
curl --location --request GET 'http://localhost:5000/api-v1/Authorization/TestAny' \
--header 'Authorization: Bearer eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJWSUVXIjoiRmFsc2UiLCJFRElUIjoiRmFsc2UiLCJERUxFVEUiOiJGYWxzZSIsIkNSRUFURSI6IkZhbHNlIiwicm9sZXMiOiJERUZBVUxUIiwibmJmIjoxNjExMTIwMDkzLCJleHAiOjE2MTExMjM2OTMsImlzcyI6ImF1dG8taGlnaGxpZ2h0ZXItaWFtIiwiYXVkIjoiYXV0by1oaWdobGlnaHRlci1mcm9udC1lbmQifQ.zOsNADvKGx1FYkzKLX4K53Y185dHFiM408aAjinQUQrVWQ_spXClozOAvp2glgiQkM0IwkDneB4Q_JCpQfet1g'
I'll be quick to provide any more info if I missed anything.如果我错过了什么,我会尽快提供更多信息。
You need to put your middleware:你需要把你的中间件:
app.UseAuthentication();
before your app.UseAuthorization();
在你的
app.UseAuthorization();
Like this:像这样:
app.UseAuthentication();
app.UseAuthorization();
Update:更新:
And you need to change your request to(delete Bearer
):您需要将您的请求更改为(删除
Bearer
):
curl --location --request GET 'http://localhost:5000/api-v1/Authorization/TestAny' \
--header 'Authorization: eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJWSUVXIjoiRmFsc2UiLCJFRElUIjoiRmFsc2UiLCJERUxFVEUiOiJGYWxzZSIsIkNSRUFURSI6IkZhbHNlIiwicm9sZXMiOiJERUZBVUxUIiwibmJmIjoxNjExMTIwMDkzLCJleHAiOjE2MTExMjM2OTMsImlzcyI6ImF1dG8taGlnaGxpZ2h0ZXItaWFtIiwiYXVkIjoiYXV0by1oaWdobGlnaHRlci1mcm9udC1lbmQifQ.zOsNADvKGx1FYkzKLX4K53Y185dHFiM408aAjinQUQrVWQ_spXClozOAvp2glgiQkM0IwkDneB4Q_JCpQfet1g'
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.