【发布时间】:2021-04-24 11:26:34
【问题描述】:
我正在使用 Asp.Net Core 5,以及带有 EFcore 的 Asp.Net Identity。我已经关注了许多视频教程的部分内容、在 SO 上发布的建议和 this 非常有用的文章,以使我的项目达到我至少获得 401 的程度。我现在的问题是我不明白为什么我会得到 401。我已经用我在 jwt.io 上的秘密验证了我的令牌,一切都告诉我它应该可以工作,但事实并非如此。我完全不知所措。废话不多说,言归正传。
我的创业班。注意:在 OnMessageReceived 事件上下文中。Token 为 null,直到我使用授权标头设置它。
//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();
});
}
}
}
我的授权控制器。有三个端点。两个用于测试我拥有的角色,一个用于测试任何有效的 jwt。它们都返回 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();
}
}
}
我正在测试的 JWT(假设令牌没有过期,我一直在确保它有效)
eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJWSUVXIjoiRmFsc2UiLCJFRElUIjoiRmFsc2UiLCJERUxFVEUiOiJGYWxzZSIsIkNSRUFURSI6IkZhbHNlIiwicm9sZXMiOiJERUZBVUxUIiwibmJmIjoxNjExMTIxNTI1LCJleHAiOjE2MTExMjUxMjUsImlzcyI6ImF1dG8taGlnaGxpZ2h0ZXItaWFtIiwiYXVkIjoiYXV0by1oaWdobGlnaHRlci1mcm9udC1lbmQifQ.jnbW552pr7kylc82-4FmJJMmaeu7LQ7L48M5cdnSzuMsA1yRuts9sXUQ2_ok41SqX8mFpi7yreJJXGlE6qC1vA
我发送的请求
curl --location --request GET 'http://localhost:5000/api-v1/Authorization/TestAny' \
--header 'Authorization: Bearer eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJWSUVXIjoiRmFsc2UiLCJFRElUIjoiRmFsc2UiLCJERUxFVEUiOiJGYWxzZSIsIkNSRUFURSI6IkZhbHNlIiwicm9sZXMiOiJERUZBVUxUIiwibmJmIjoxNjExMTIwMDkzLCJleHAiOjE2MTExMjM2OTMsImlzcyI6ImF1dG8taGlnaGxpZ2h0ZXItaWFtIiwiYXVkIjoiYXV0by1oaWdobGlnaHRlci1mcm9udC1lbmQifQ.zOsNADvKGx1FYkzKLX4K53Y185dHFiM408aAjinQUQrVWQ_spXClozOAvp2glgiQkM0IwkDneB4Q_JCpQfet1g'
如果我遗漏了什么,我会尽快提供更多信息。
【问题讨论】:
-
嗨@Ryan Callahan,关于这个案例有什么更新吗?
标签: c# asp.net-core jwt asp.net-identity asp.net-roles