【发布时间】:2021-08-09 23:30:42
【问题描述】:
我创建了一个方法,用户可以登录到我的应用程序,然后将令牌发送给用户,以便它可以用于查看应用程序中的任何其他视图。当我在邮递员上测试登录方法时,我得到了500 服务器错误如下而不是令牌。我看过类似的问题/帖子,但没有看到与 JWT 相关的帖子
下面是输出
System.ArgumentNullException:值不能为空。 (参数“值”) 在 System.Security.Claims.Claim..ctor(字符串类型,字符串值,字符串 valueType,字符串颁发者,字符串 originalIssuer,ClaimsIdentity 主题,字符串 propertyKey,字符串 propertyValue) 在 System.Security.Claims.Claim..ctor(字符串类型,字符串值) 在 /Users/Ken/Desktop/Coop_Marketing/Coop_Marketing/Coop_Marketing/Controllers/AccountController.cs:line 101 中的 Coop_Marketing.Controllers.AccountController.Login(LoginViewModel formdata) 在 Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.TaskOfIActionResultExecutor.Execute(IActionResultTypeMapper 映射器,ObjectMethodExecutor 执行器,对象控制器,对象 [] 参数) 在 Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.g__Awaited|12_0(ControllerActionInvoker 调用程序,ValueTask`1 actionResultValueTask) 在 Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.g__Awaited|10_0(ControllerActionInvoker 调用程序,任务 lastTask,下一个状态,作用域范围,对象状态,布尔 isCompleted) 在 Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed 上下文) 在 Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(状态&下一个,范围&范围,对象&状态,布尔& isCompleted) 在 Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.g__Awaited|13_0(ControllerActionInvoker 调用者,任务 lastTask,下一个状态,作用域范围,对象状态,布尔 isCompleted) 在 Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Awaited|24_0(ResourceInvoker 调用者,任务 lastTask,下一个状态,作用域范围,对象状态,布尔 isCompleted) 在 Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResourceExecutedContextSealed 上下文) 在 Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Next(状态&下一个,范围&范围,对象&状态,布尔& isCompleted) 在 Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Awaited|19_0(ResourceInvoker 调用程序,任务 lastTask,下一个状态,作用域范围,对象状态,布尔 isCompleted) 在 Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Awaited|17_0(ResourceInvoker 调用程序,任务任务,IDisposable 范围) 在 Microsoft.AspNetCore.Routing.EndpointMiddleware.g__AwaitRequestTask|6_0(端点端点,任务 requestTask,ILogger 记录器) 在 Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext 上下文) 在 Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext 上下文)
下面是带有登录方式的Account控制器
public async Task<IActionResult> Login([FromBody] LoginViewModel formdata)
{
// Get the User from database
var user = await _userManager.FindByNameAsync(formdata.Username);
var roles = await _userManager.GetRolesAsync(user);
var key = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(_appSettings.Secret));
double tokenExpiryTime = Convert.ToDouble(_appSettings.ExpireTime);
if(user !=null && await _userManager.CheckPasswordAsync(user,formdata.Password))
{
var tokenhandler = new JwtSecurityTokenHandler();
// Describe the token used by the user to log in
var tokenDescriptor = new SecurityTokenDescriptor
{
Subject = new ClaimsIdentity(new Claim[]
{
new Claim(JwtRegisteredClaimNames.Sub, formdata.Username),
new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
new Claim(ClaimTypes.NameIdentifier, user.Id),
new Claim(ClaimTypes.Role, roles.FirstOrDefault()),
new Claim("LoggedOn", DateTime.Now.ToString()),
}),
SigningCredentials = new SigningCredentials(key, SecurityAlgorithms.HmacSha256Signature),
Issuer = _appSettings.Site,
Audience = _appSettings.Audience,
Expires = DateTime.UtcNow.AddMinutes(tokenExpiryTime)
};
// Generate the token
var token = tokenhandler.CreateToken(tokenDescriptor);
return Ok(new {token= tokenhandler.WriteToken(token), expiration = token.ValidTo,username = user.UserName,userRole = roles.FirstOrDefault()});
}
// Return error
ModelState.AddModelError("","Username/Password was not Found");
return Unauthorized(new { LoginError = "Please check the Login Credentials - Invalid Username/Password was entered" });
}
}
}
还有 LoginViewModel
public class LoginViewModel
{
[Required]
[Display(Name = "User Name")]
public string Username { get; set; }
[Required]
[DataType(DataType.Password)]
public string Password { get; set; }
}
问题在于 > var tokenDescriptor = new SecurityTokenDescriptor 根据输出中提到的代码中的第 101 行。但是,我无法弄清楚为什么会出现错误。
【问题讨论】:
-
错误显示 Claim 的构造函数有一个空参数
value...System.Security.Claims.Claim..ctor(String type, String value)。为了帮助调试,请将数组移出“单行新”嵌套,以便您可以逐步使用调试器并确定哪个声明失败。
标签: c# .net asp.net-mvc asp.net-core