【发布时间】:2021-08-27 04:21:34
【问题描述】:
我有一个 MVC 应用程序和一个公开的 API 端点。我使用 Identity Core 的默认值验证了我的 MVC 应用程序,我使用 User.FindFirstValue(ClaimTypes.NameIdentifier) 来查找某个用户是否已登录,等等。
对于我的 API Endpoint,我使用 JWT 身份验证下面是 JWT 的配置代码:
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(jwt =>
{
var key = Encoding.ASCII.GetBytes(Configuration["Jwt:Secret"]);
jwt.SaveToken = true;
jwt.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(key),
ValidateIssuer = false,
ValidateAudience = false,
RequireExpirationTime = false,
ValidateLifetime = true
};
});
这是令牌请求的控制器:
[HttpPost]
[Route("token")]
public async Task<IActionResult> Token([FromBody] UserLoginRequest user)
{
if (ModelState.IsValid)
{
var existingUser = await _userManager.FindByEmailAsync(user.Email);
if (existingUser == null)
{
return BadRequest();
}
var isCorrect = await _userManager.CheckPasswordAsync(existingUser, user.Password);
if (isCorrect)
{
var jwtToken = _identityService.GenerateJwtToken(existingUser);
return Ok(new RegistrationResponse()
{
Result = true,
Token = jwtToken
});
}
else
{
return BadRequest();
}
}
return BadRequest();
}
在我的 MVC 控制器上,我使用 [Authorize]
在我的 API 端点上,我使用 [Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
我的GenerateJWTToken 方法:
public string GenerateJwtToken(IdentityUser user)
{
var jwtTokenHandler = new JwtSecurityTokenHandler();
var key = Encoding.ASCII.GetBytes(_jwtConfig.Secret);
var tokenDescriptor = new SecurityTokenDescriptor
{
Subject = new ClaimsIdentity(new[]
{
new Claim("Id", user.Id),
new Claim(JwtRegisteredClaimNames.Sub, user.Email),
new Claim(JwtRegisteredClaimNames.Email, user.Email),
new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString())
}),
Expires = DateTime.UtcNow.AddHours(6),
SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha512Signature)
};
var token = jwtTokenHandler.CreateToken(tokenDescriptor);
var jwtToken = jwtTokenHandler.WriteToken(token);
return jwtToken;
}
}
但显然,此解决方案无法正常运行,因为一旦我启动 MVC 应用程序并尝试登录,我就会被重定向回 Index 并且我仍然未经授权。反之亦然,使用 API 时,当我调用 Postman 时,我得到了令牌,当我尝试调用我的书签控制器来查询用户的书签时,我得到零,尽管有特定用户的书签。
欢迎任何关于我如何完成这项工作的想法。
【问题讨论】:
-
在向书签发出请求时,您是否将不记名令牌与请求一起发送?其次,您的 mvc 身份验证失败,因为您已将 JWT 身份验证指定为默认身份验证方案。
-
是的,我确实将令牌与请求一起发送。我的书签实体有一个 UserId 属性,我用它来检索该特定用户的所有书签。当这是在 MVC 中时,我很容易使用 (User.FindFirstValue(ClaimTypes.NameIdentifier)) 检索用户 ID,但在我的 API 调用中,我得到零个书签。 @杰弗里
-
@Jeffery 还有我可以做些什么来将会话身份验证和 JWT 身份验证设为默认值
-
对于我完成的所有 JWT 身份验证,我编写了自己的 JWT 令牌生成器,我在其中指定了诸如 NameIdentifier 之类的声明类型以及我可能特别需要的其他声明。
-
我发布了我的代码作为 cmets 的答案以提供帮助。看看能不能解决你的问题
标签: c# asp.net-mvc authentication .net-core jwt