I have a .NET Core 2.0 Web API. I am using Jwt authentication on it.
Whenever the application reaches this line, an exception is thrown:
var userClaims = await _userManager.GetClaimsAsync(user);
The exception is:
System.InvalidOperationException: Sequence contains more than one matching element
What is weird is that this wasn't happening before, it started happening when I upgraded to .NET Core 2.0 from 1.1.
The Seed method for the database is below:
public async Task Seed()
{
var adminUserJ = await _userManager.FindByNameAsync("Ciwan");
var regularUser = await _userManager.FindByNameAsync("John");
if (adminUserJ == null)
{
if (!await _roleManager.RoleExistsAsync("Admin"))
{
var role = new IdentityRole("Admin");
role.Claims.Add(new IdentityRoleClaim<string> { ClaimType = "IsAdmin", ClaimValue = "True" });
await _roleManager.CreateAsync(role);
}
adminUserJ = new BbUser
{
UserName = "Ciwan",
Email = "ck83s9@gmail.com"
};
var userResult = await _userManager.CreateAsync(adminUserJ, "Welcome123");
var roleResult = await _userManager.AddToRoleAsync(adminUserJ, "Admin");
var claimResult = await _userManager.AddClaimAsync(adminUserJ, new Claim("Points", "10"));
if (!userResult.Succeeded || !roleResult.Succeeded || !claimResult.Succeeded)
{
throw new InvalidOperationException("Failed to build user and roles");
}
}
if (regularUser == null)
{
if (!await _roleManager.RoleExistsAsync("Regular"))
{
var role = new IdentityRole("Regular");
role.Claims.Add(new IdentityRoleClaim<string> { ClaimType = "IsRegular", ClaimValue = "True" });
await _roleManager.CreateAsync(role);
}
regularUser = new BbUser
{
UserName = "John",
Email = "j.watson@world.com"
};
var userResult = await _userManager.CreateAsync(regularUser, "BigWow321");
var roleResult = await _userManager.AddToRoleAsync(regularUser, "Regular");
var claimResult = await _userManager.AddClaimAsync(regularUser, new Claim("Points", "10"));
if (!userResult.Succeeded || !roleResult.Succeeded || !claimResult.Succeeded)
{
throw new InvalidOperationException("Failed to build user and roles");
}
}
_context.AddRange(GetListOfArtists(adminUserJ.Id, regularUser.Id));
await _context.SaveChangesAsync();
}
I can't see anything wrong. I tried looking at the AspNetUserClaims
table in the database, but all seems OK. I have 2 claims in there, one for each user.
This error happens when I attempt to log in a user, so the request arrives here:
[HttpPost("auth/token")]
public async Task<IActionResult> CreateToken([FromBody] CredentialsDto credentials)
{
try
{
var user = await _userManager.FindByNameAsync(credentials.Username);
if (user != null)
{
if (IsUserPasswordValid(credentials, user))
{
var claims = await GetClaimsAsync(user);
var token = CreateNewJwtToken(claims);
return Ok(new
{
token = new JwtSecurityTokenHandler().WriteToken(token),
expiration = token.ValidTo
});
}
}
}
catch (Exception exception)
{
Console.WriteLine(exception);
throw;
}
return BadRequest("Failed to generate token!");
}
private async Task<IEnumerable<Claim>> GetClaimsAsync(BbUser user)
{
var userClaims = await _userManager.GetClaimsAsync(user);
return new[] {
new Claim(JwtRegisteredClaimNames.Sub, user.UserName),
new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString())
}.Union(userClaims);
}