我对这段代码有问题:
private async Task<object> GenerateJwtToken(string email, User user)
{
var claims = new List<Claim>
{
new Claim(JwtRegisteredClaimNames.Sub, email),
new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
new Claim(ClaimTypes.NameIdentifier, user.Id)
};
用户扩展身份用户。问题是我得到:
无法从'int'转换为'System.Security.Claims.ClaimsIdentity'"。 即使对于 ClaimTypes.NameIdentifier,我也会收到错误:"无法从 "string"到"System.IO.BinaryReader">
如果我将 Id 更改为其他内容,例如电子邮件或名字错误消失......找不到有关它的任何信息。
我在新Claim(ClaimTypes.Name, userFromRepo.Username)
的视觉代码上遇到了此错误,告诉Argument 1: cannot convert from 'string' to 'System.IO.BinaryReader'
.我的代码是这样的:
public async Task<IActionResult> ReadUser([FromBody]UserDto userDto){
User userFromRepo = _authRepository.GetUserAsync();
//generate token for user
var tokenHandler = new JwtSecurityTokenHandler();
var key = Encoding.ASCII.GetBytes("my secret key");
var tokenDescriptor = new SecurityTokenDescriptor{
Subject = new ClaimsIdentity(new Claim[]
{
new Claim(ClaimTypes.NameIdentifier, userFromRepo.Id.ToString()),
new Claim(ClaimTypes.Name, userFromRepo.Username) //error here in this ctor
}),
Expires = DateTime.Now.AddDays(1),
SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha512Signature)
};
在我的存储库方法之前添加await
缺少的关键字后,顺便说一下,这是异步的,错误现在消失了。
public async Task<IActionResult> ReadUser([FromBody]UserDto userDto){
User userFromRepo = await _authRepository.GetUserAsync(); //added await
//generate token for user
var tokenHandler = new JwtSecurityTokenHandler();
var key = Encoding.ASCII.GetBytes("my secret key");
var tokenDescriptor = new SecurityTokenDescriptor{
Subject = new ClaimsIdentity(new Claim[]
{
new Claim(ClaimTypes.NameIdentifier, userFromRepo.Id.ToString()),
new Claim(ClaimTypes.Name, userFromRepo.Username) //error gets fixed
}),
Expires = DateTime.Now.AddDays(1),
SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha512Signature)
};
也许你正面临类似的事情?
可以理解的是,我对这个问题有点晚了,但我遇到了类似的问题。
我发现新的声明有多个签名可以传递到其中。明确说明类型解决了我的问题。
new Claim(ClaimTypes.Name as string, userFromRepo.Username as string)
希望这能为遇到此问题的其他任何人提供一些帮助。
通常它的工作方式(至少在 ASP.NET Core 3中(是当脚手架实例化ClaimsPrincipal
时,sub
JWT声明会自动转换为(由InboundClaimTypeMap
(转换为NameIdentifier
。
因此,只需与用户设置JwtRegisteredClaimNames.Sub
声明就足够了。Id 作为值。
但是,您可以通过在AddIdentity()
调用中为IdentityOptions.ClaimsIdentity.UserIdClaimType
分配值来自定义标识应用于标识目的的声明,例如:
services.AddIdentity<ApplicationUser, IdentityRole>(options =>
{
options.ClaimsIdentity.UserIdClaimType = JwtRegisteredClaimNames.Sub;
});
如果要禁用声明映射,可以通过在配置中包含以下语句来清除映射:
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
或将此标志设置为 false:
JwtSecurityTokenHandler.DefaultMapInboundClaims = false;
就我而言,我的方法签名上出现了构建错误。修复后修复错误
我的方法签名是这样的:
private async Task<User> AuthenticateUserAsync(string email, string password)
定义"User"后,修复了与方法签名相关的类构建错误。
将user.Id
转换为字符串
private async Task<object> GenerateJwtToken(string email, User user)
{
var claims = new List<Claim>
{
new Claim(JwtRegisteredClaimNames.Sub, email),
new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
new Claim(ClaimTypes.NameIdentifier, user.Id.ToString())
};