Vis*_*osh 13 asp.net asp.net-authorization jwt asp.net-web-api asp.net-core
我正在尝试尽可能简单地在我的 asp.net 核心 webAPI 上实现 JWT 身份验证。我不知道我错过了什么,但即使使用正确的不记名令牌,它也总是返回 401 。
这是我的 configureServices 代码
public void ConfigureServices(IServiceCollection services)
{
services.AddAuthentication(x =>
{
x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(
x =>
{
x.RequireHttpsMetadata = false;
x.SaveToken = true;
x.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes("A_VERY_SECRET_SECURITY_KEY_FOR_JWT_AUTH")),
ValidateAudience = false,
ValidateIssuer = false,
};
}
);
services.AddControllers();
services.AddDbContext<dingdogdbContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("dingdogdbContext")));
}
Run Code Online (Sandbox Code Playgroud)
这就是我生成令牌的方式
[AllowAnonymous]
[HttpPost("/Login")]
public ActionResult<User> Login(AuthModel auth)
{
var user = new User();
user.Email = auth.Email;
user.Password = auth.Password;
//var user = await _context.User.SingleOrDefaultAsync(u=> u.Email == auth.Email && u.Password==auth.Password);
//if(user==null) return NotFound("User not found with this creds");
//starting token generation...
var tokenHandler = new JwtSecurityTokenHandler();
var seckey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes("A_VERY_SECRET_SECURITY_KEY_FOR_JWT_AUTH"));
var signingCreds = new SigningCredentials(seckey, SecurityAlgorithms.HmacSha256Signature);
var token = tokenHandler.CreateToken(new SecurityTokenDescriptor
{
Subject = new System.Security.Claims.ClaimsIdentity(new Claim[] { new Claim(ClaimTypes.Name, user.Id.ToString()) }),
SigningCredentials = signingCreds,
Expires = DateTime.UtcNow.AddDays(7),
});
user.Token = tokenHandler.WriteToken(token);
return user;
}
Run Code Online (Sandbox Code Playgroud)
我在 app.useRouting() 之后添加了 app.useAuthorization()。当我向 /Login 发送 POST 请求时,我得到了令牌。但是当我使用令牌查询任何其他使用邮递员的端点(在邮递员的授权/JWT 中添加令牌)时,每次都会得到 401 未经授权。我还缺少什么吗?
Jak*_*era 35
请记住,在UseAuthentication,UseRouting和UseAuthorization中间件必须正确为了使ASP框架适当注入身份上下文的HTTP请求。
它应该是这样的:(.NET Core 3.1)
编辑:相同的代码适用于 .NET 5
app.UseAuthentication();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
Run Code Online (Sandbox Code Playgroud)
Hoq*_*dul 17
步骤1:首先确定stratup.cs类中configure方法的顺序:
下面我给出了 asp.net core 3.1 的有效订单
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
Run Code Online (Sandbox Code Playgroud)
如果第一步不起作用,请尝试第 2 步:确保令牌验证参数和令牌生成参数和算法相同,请转到 startup.cs 类的 ConfigureServices 方法,并转到您生成的类或方法在我的情况下,令牌是 UserService 类
ConfigureServices 方法代码:
public void ConfigureServices(IServiceCollection services)
{
var connectionString = Configuration.GetConnectionString("mySQLConnectionString");
services.AddDbContext<ApplicationDbContext>(options => options.UseMySql(connectionString));
services.AddIdentity<IdentityUser, IdentityRole>(options =>
{
options.Password.RequireDigit = true;
options.Password.RequireLowercase = true;
options.Password.RequiredLength = 5;
}).AddEntityFrameworkStores<ApplicationDbContext>().AddDefaultTokenProviders();
services.AddAuthentication(auth =>
{
auth.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidateAudience = true,
ValidAudience = Configuration["AuthSettings:Audience"],
ValidIssuer = Configuration["AuthSettings:Issuer"],
RequireExpirationTime = true,
IssuerSigningKey =
new SymmetricSecurityKey(
Encoding.UTF8.GetBytes(Configuration["AuthSettings:key"])),
ValidateIssuerSigningKey = true,
};
});
services.AddScoped<IUserService, UserService>();
services.AddControllers();
}
Run Code Online (Sandbox Code Playgroud)
代币生成代码:
public async Task<UserManagerResponse> LoginUserAsync(LoginVIewModel model)
{
var user = await _userManager.FindByEmailAsync(model.Email);
if(user == null)
{
return new UserManagerResponse
{
Message = "There is no user with that email",
iSSuccess= false
};
}
var result = await _userManager.CheckPasswordAsync(user, model.Password);
if(! result)
{
return new UserManagerResponse
{
Message = "Your Provided password not match eith our system ",
iSSuccess = false
};
}
var clims = new[]
{
new Claim("Email", model.Email),
new Claim(ClaimTypes.NameIdentifier, user.Id)
};
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration["AuthSettings:key"]));
var token = new JwtSecurityToken(
issuer: _configuration["AuthSettings:Issuer"],
audience: _configuration["AuthSettings:Audience"],
claims: clims,
expires: DateTime.Now.AddDays(30),
signingCredentials: new SigningCredentials(key, SecurityAlgorithms.HmacSha256)
);
string tokenAsString = new JwtSecurityTokenHandler().WriteToken(token);
return new UserManagerResponse
{
Message = tokenAsString,
iSSuccess = true,
ExpireDate = token.ValidTo
};
}
}
Run Code Online (Sandbox Code Playgroud)
还请注意,就我而言,我在 appsetting.json 中有一些拼写错误例如,在令牌生成代码中,我将其称为 Audince,但在 appSetting.json 中它是 Audience。这就是为什么两个 Audience 不匹配的原因。
audience: _configuration["AuthSettings:Audince"]
Run Code Online (Sandbox Code Playgroud)
Appsetting.json 代码:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
Run Code Online (Sandbox Code Playgroud)
小智 5
在解决这个问题几个小时后,并尝试了多个问题中的不同内容。以下是我识别问题的方法:
打开文件Microsoft.AspNetCore.Authentication中包的日志记录appsettings.json
{
"Logging": {
"Console": {
"LogLevel": {
"Microsoft.Hosting.Lifetime": "Trace",
"Microsoft.AspNetCore.Authentication": "Information"
}
}
},
// other attributes
}
Run Code Online (Sandbox Code Playgroud)
这会将身份验证失败记录到 Visual Studio 服务器控制台。
new JwtSecurityToken就我而言,我在生成令牌时没有将 expires 参数传递给构造函数。但我正在验证构造函数中的令牌生命周期TokenValidationParameters。
| 归档时间: |
|
| 查看次数: |
8550 次 |
| 最近记录: |