[Authorize]
[HttpGet("getUser")]
public async Task<ActionResult<UserDTO>> GetUser()
{
var token = HttpContext.Request.Headers["Authorization"].FirstOrDefault()?.Split(" ").Last();
if (string.IsNullOrEmpty(token))
{
return Unauthorized(new { message = "Token is required." });
}
var handler = new JwtSecurityTokenHandler();
if (!handler.CanReadToken(token))
{
return BadRequest(new { message = "Invalid token format." });
}
var jwtToken = handler.ReadJwtToken(token);
var claims = jwtToken.Claims;
var email = _httpContextAccessor.HttpContext.User.FindFirstValue(ClaimTypes.Email);
var result = await Mediator.Send(new GetUser.Command());
return HandleResults(result);
}
好吧,我正在创建一种持久登录的方法,但遇到了一些声明为空的问题。似乎令牌确实有声明,在调试模式下检查它时,我看到它有 6 个,但是当尝试使用 httpcontext 访问声明时,它只返回 null。
这是我的代币生成代码
public string Token(ApplicationUser user)
{
var claims = new List<Claim>
{
new Claim(ClaimTypes.Name, user.UserName),
new Claim(ClaimTypes.NameIdentifier, user.Id),
new Claim(ClaimTypes.Email, user.Email),
};
var jwtKey = _configuration["JwtConfig:Key"];
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtKey));
var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
var tokenDescriptor = new SecurityTokenDescriptor
{
Subject = new ClaimsIdentity(claims),
Expires = DateTime.UtcNow.AddDays(1),
SigningCredentials = creds
};
var tokenHandler = new JwtSecurityTokenHandler();
var token = tokenHandler.CreateToken(tokenDescriptor);
return tokenHandler.WriteToken(token);
}
private TokenValidationParameters GetValidationParameters()
{
return new TokenValidationParameters
{
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration["JwtConfig:Key"])),
ValidateIssuer = false,
ValidateAudience = false,
ValidateLifetime = true,
ClockSkew = TimeSpan.Zero
};
}
我尝试添加身份验证方案,但没有成功
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuerSigningKey = true,
IssuerSigningKey = key,
ValidateIssuer = false,
ValidateAudience = false,
};
options.Events = new JwtBearerEvents
{
OnMessageReceived = context =>
{
var accessToken = context.Request.Query["access_token"];
if (!string.IsNullOrEmpty(accessToken) &&
(context.HttpContext.WebSockets.IsWebSocketRequest || context.Request.Headers["Accept"] == "text/event-stream"))
{
context.Token = accessToken;
}
return Task.CompletedTask;
}
};
options.Events = new JwtBearerEvents
{
OnAuthenticationFailed = context =>
{
System.Console.WriteLine(context.Exception);
return Task.CompletedTask;
},
};
});
我还确保使用授权标签并在授权之前进行身份验证,但仍然没有成功。任何帮助将不胜感激。
如果您的端点已使用 JWT 正确进行了身份验证,则无需从 HttpContext.Request 对象获取令牌。
首先,您需要将此属性添加到端点或控制器定义中:
[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
然后确保您在令牌中拥有正确的声明,该令牌随后将用于保护端点。
以下内容可以删除,因为底层框架会为您处理它:
var token = HttpContext.Request.Headers["Authorization"].FirstOrDefault()?.Split(" ").Last();
if (string.IsNullOrEmpty(token))
{
return Unauthorized(new { message = "Token is required." });
}
var handler = new JwtSecurityTokenHandler();
if (!handler.CanReadToken(token))
{
return BadRequest(new { message = "Invalid token format." });
}
var jwtToken = handler.ReadJwtToken(token);
var claims = jwtToken.Claims;