asp.net - 无法使用 JWT 身份验证访问 .NET Core 中的授权内容
问题描述
我开发了一个示例应用程序,我在其中使用 JWT 身份验证来访问私有内容。
在 Postman 中获得令牌后,我也可以通过 Postman 将其传递给私有控制器操作,并且一切正常。
但是当我尝试使用SignInManager
访问时,它不会工作。 User.Identity.Name
并且User.Identity.IsAuthenticated
始终为空
这是我的启动代码
public class Startup
{
private AppModule appModule;
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
appModule = new AppModule();
AppModule.Configuration = Configuration; //setting up of static variable
services.Configure<CookiePolicyOptions>(options =>
{
// This lambda determines whether user consent for non-essential cookies is needed for a given request.
options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = SameSiteMode.None;
});
string connectionSring = null;
if (true) //(env.IsDevelopment())
connectionSring = appModule.GetConnectionString(EuConstants.LOCAL_CONNECTION_NAME);
else
connectionSring = appModule.GetConnectionString(EuConstants.DEFAULT_CONNECTION_NAME);
services.AddDbContext<ApplicationDbContext>(options =>
{
options.UseSqlServer(connectionSring);
});
/* tell the framework to use our cusom user and role classes */
services.AddIdentity<Gn_User, Gn_Role>(options =>
{
options.Stores.MaxLengthForKeys = 128;
})
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders();
services.ConfigureApplicationCookie(o => {
o.LoginPath = "/portal/login";
});
services.AddAuthorization();
services.AddAuthentication(option => {
option.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
option.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
option.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(options => {
options.SaveToken = true;
options.RequireHttpsMetadata = true;
options.TokenValidationParameters = new TokenValidationParameters()
{
ValidateIssuer = true,
ValidateAudience = true,
ValidAudience = Configuration["Jwt:Site"],
ValidIssuer = Configuration["Jwt:Site"],
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["Jwt:SigningKey"]))
};
});
services.AddScoped<AppModule>(sp => appModule
);
services.AddMvc(
options =>
{
// make sure that all attributes by default required authentication
// options.Filters.Add(new AuthorizeFilter(new AuthorizationPolicyBuilder().RequireAuthenticatedUser().Build()));
}
).SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env, IServiceProvider provider)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
app.UseAuthentication();
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseCookiePolicy();
// tell the application to use the authentication
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Portal}/{action=Index}/{id?}");
});
}
}
这是生成令牌的身份验证方法
public async Task<ActionResult> Login([FromBody] Gn_User model)
{
string password = "yaser@1234";
var user = await _userManager.FindByNameAsync(model.UserName);
if (user != null && await _userManager.CheckPasswordAsync(user, password))
{
var claim = new[] {
new Claim(JwtRegisteredClaimNames.Sub, user.UserName)
};
var signinKey = new SymmetricSecurityKey(
Encoding.UTF8.GetBytes(AppModule.Configuration["Jwt:SigningKey"]));
int expiryInMinutes = Convert.ToInt32(AppModule.Configuration["Jwt:ExpiryInMinutes"]);
var token = new JwtSecurityToken(
issuer: AppModule.Configuration["Jwt:Site"],
audience: AppModule.Configuration["Jwt:Site"],
expires: DateTime.UtcNow.AddMinutes(expiryInMinutes),
signingCredentials: new SigningCredentials(signinKey, SecurityAlgorithms.HmacSha256)
);
return Ok(
new
{
token = new JwtSecurityTokenHandler().WriteToken(token),
expiration = token.ValidTo
});
}
return Unauthorized();
}
解决方案
您忘记将您的声明添加到您的 JWT。
public async Task<ActionResult> Login([FromBody] Gn_User model)
{
string password = "yaser@1234";
var user = await _userManager.FindByNameAsync(model.UserName);
if (user != null && await _userManager.CheckPasswordAsync(user, password))
{
var claim = new[] {
new Claim(JwtRegisteredClaimNames.Sub, user.UserName)
};
var signinKey = new SymmetricSecurityKey(
Encoding.UTF8.GetBytes(AppModule.Configuration["Jwt:SigningKey"]));
int expiryInMinutes = Convert.ToInt32(AppModule.Configuration["Jwt:ExpiryInMinutes"]);
var token = new JwtSecurityToken(
issuer: AppModule.Configuration["Jwt:Site"],
audience: AppModule.Configuration["Jwt:Site"],
/////////////////////////////////
claims : claim,// Dont Forget To Add Claims To Your JWT
/////////////////////////////////
expires: DateTime.UtcNow.AddMinutes(expiryInMinutes),
signingCredentials: new SigningCredentials(signinKey, SecurityAlgorithms.HmacSha256)
);
return Ok(
new
{
token = new JwtSecurityTokenHandler().WriteToken(token),
expiration = token.ValidTo
});
}
return Unauthorized();
}
推荐阅读
- javascript - 使用 dd-mm-yyyy 格式的 SharePoint 列表筛选器
- delphi - 如何使用 CEF4Delphi 在 Chromium 中设置自定义 cookie 数据位置
- python - 我的 python 代码有问题,使用 tkinter。我不断收到一条消息,说对象没有属性
- python - 模型未显示在 django 管理页面中
- r - 在R中按条件插入字符串
- arduino-ide - 我不小心短路了我的 SPARKFUN ESP32 THING (13907) 3v3 和接地引脚
- c# - Unity 3d 播放器跳转不起作用,rb.addforce 不起作用
- autodesk-forge - Autodesk Data Management webhook 触发事件两次?
- api - 问答:如何在 Zapier 上设置 Quickbooks OAuth2
- javascript - 有没有办法使用 SVG 渐变作为置换贴图的输入?