我试图尽可能简单地在我的www.example.com核心webAPI上实现JWT身份验证asp.net。我不知道我错过了什么,但它总是返回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")));
}
这就是我生成token的方法
[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;
}
我在app.useRouting()之后添加了app.useAuthorization()。当我向/Login发送POST请求时,我会获得令牌。但当我使用postman中的令牌查询任何其他端点时(在postman中的authorization/JWT中添加了令牌),每次都获得401未授权。还有什么我遗漏的吗?
6条答案
按热度按时间eqzww0vc1#
请记住,
UseAuthentication
、UseRouting
和UseAuthorization
中间件必须正确,以便ASP框架正确地将身份上下文注入到http请求中。它应该如下所示:(. NET核心版本3.1)
编辑:相同的代码适用于. NET 5和. NET 6
wwodge7n2#
第一步:首先确定stratup.cs类中configure方法的顺序:
下面是www.example.com core3.1的有效订购单asp.net
如果步骤1不起作用,请尝试步骤2:确保令牌验证参数和令牌生成参数&算法相同,以便转到startup.cs类的ConfigureServices方法,并转到生成令牌的类或方法(在我的示例中是UserService类)
配置服务方法代码:
令牌生成代码:
还请注意,在我的情况下,我在appsetting.json中有一些拼写错误例如在令牌生成代码中,我调用了Audince,但在appSetting.json中它是Audience。这就是为什么两个Audience不匹配。
应用设置.json代码:
dpiehjr43#
首先,您需要检查使用configureServices代码生成的JWT标记是否有效。要验证JWT标记,您可以使用JWT debugger。它会将JWT标记值解析为每个参数,您可以通过这些参数验证哪个参数值分配不正确,JWT调试器也会向您提供JWT有效或无效。一旦您弄清楚了这一点,您就可以处理已识别的错误或执行下一步操作。
1mrurvl14#
这里还有一些其他问题,您可能想要看一看并可能改进。登录机制目前包含一个7天到期的令牌。这意味着暴露的令牌仍将允许攻击者在7天内访问和模拟用户。一般来说,最好是:
这使用户能够在某些内容受到损害时“注销”所有会话,特别是大多数身份验证提供程序(如Auth0)或授权提供程序(如Authress)都提供这些功能和更多功能。
cnwbcb6i5#
总结
在我的示例中,我没有使用任何Identity Server,但我提供了主机作为ValidIssuer。它验证了
Authority
的算法和密钥,但没有返回任何内容,这导致系统抛出未处理的异常。通过从AddJwtBearer(options => ...)
中的JwtBearerOptions
中删除options.Authority
解决了此问题。在那之后,我遇到了401错误,通过从
AddJwtBearer(options => ...)
中的JwtBearerOptions
中删除options.Audience
来解决它,还将ValidateLifetime
添加到TokenValidationParameters
(您可以在下面的第1部分中看到)编号
第(1)部分JWT配置
在.NET 6中:
额外
使用以下任一位置从Appsettings获取JWT设置
“JSON Web令牌密钥”
是
configuration
中节的名称:或:
nmpmafwu6#
我一次又一次地遇到同样的问题,我想通了,这是因为
.AddJwtBearer()
中的TokenValidationParameters
必须像这样:只有在那种情况下,我才能让它工作。