Reputation: 2256
I am trying to implement JWT token Authentication But while trying to ClaimsPrincipal getting an exception.
Unable to create claims from securityToken, 'issuer' is null or empty
I am not getting what exactly is wrong in below code
public static string GenrateToken(string userId, string deviceId)
{
var time = DateTime.UtcNow;
var symmetricKey = Convert.FromBase64String(Secret);
var tokenHandler = new JwtSecurityTokenHandler();
SecurityKey securityKey = new InMemorySymmetricSecurityKey(symmetricKey);
var now = DateTime.UtcNow;
var expiry = now.AddHours(24);
var tokenDescriptor = new SecurityTokenDescriptor
{
Subject = new ClaimsIdentity(new[]
{new Claim("userId", userId),new Claim("deviceId", deviceId),new Claim("time", time.ToString())}
),
Lifetime = new Lifetime(now, expiry),
SigningCredentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256Signature, "")
};
var stoken = tokenHandler.CreateToken(tokenDescriptor);
var token = tokenHandler.WriteToken(stoken);
return token;
}
public static ClaimsPrincipal GetPrincipal(string token)
{
try
{
var tokenHandler = new JwtSecurityTokenHandler();
var jwtToken = tokenHandler.ReadToken(token) as JwtSecurityToken;
if (jwtToken == null)
return null;
var symmetricKey = Convert.FromBase64String(Secret);
SecurityKey securityKey = new InMemorySymmetricSecurityKey(symmetricKey);
var validationParameters = new TokenValidationParameters()
{
RequireExpirationTime = true,
ValidateIssuer = false,
ValidateAudience = false,
IssuerSigningKey = securityKey
};
SecurityToken securityToken;
var principal = tokenHandler.ValidateToken(token, validationParameters, out securityToken);
return principal;
}
catch (Exception ex)
{
//should write log
return null;
}
}
Upvotes: 4
Views: 2907
Reputation: 850
Sure It is later to answer the op, but just in case other ppl has the same problem...
Which version of JwtSecurityTokenHandler are you using? Apparently, there is a bug that enforces Issuer validation, regardless of your setting of:
ValidateIssuer=false
It should be fixed in version 5.0.0, but there are other breaking changes that have me tied to version 4.x.x
Does your token have a iss claim? If not, add it as:
new Claim("iss", issuerName),
Later, setup the issuer when your token is validated:
var validationParameters = new TokenValidationParameters
{
RequireExpirationTime = true,
ValidateIssuer = false,
ValidIssuer = issuerName,
ValidAudience = false,
IssuerSigningKey = securityKey
};
Where issuerName is any string constant that you wouldn't like to check, but you're forced to use. Even if it is not going to be validated, must exists
Bug: https://github.com/AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet/issues/154 (You can also use the workaround described there)
Upvotes: 2