I'm trying to use package System.IdentityModel.Tokens.Jwt to generate a token. I found some code samples online, was pretty straightforward, but then I'm running into an error that I can't figure out. Here's the code I'm using (has been modified slightly for brevity):
<%@ Application Language="C#" %>
<%@ Import Namespace="System" %>
<%@ Import Namespace="System.Text" %>
<%@ Import Namespace="System.Reflection" %>
<%@ Import Namespace="System.Collections" %>
<%@ Import Namespace="System.IdentityModel.Tokens" %>
<%@ Import Namespace="System.IdentityModel.Tokens.Jwt" %>
<%@ Import Namespace="System.Security.Claims" %>
<%@ Import Namespace="System.IdentityModel.Protocols.WSTrust" %>
<script runat="server">
public class TestClass
{
public static string GetJwtToken()
{
var tokenHandler = new JwtSecurityTokenHandler();
var input = "anyoldrandomtext";
var securityKey = new byte[input.Length * sizeof(char)];
Buffer.BlockCopy(input.ToCharArray(), 0, securityKey, 0, securityKey.Length);
var now = DateTime.UtcNow;
var tokenDescriptor = new SecurityTokenDescriptor
{
Subject = new ClaimsIdentity(new[]
{
new Claim( ClaimTypes.UserData,
"IsValid", ClaimValueTypes.String, "(local)" )
}),
TokenIssuerName = "self",
AppliesToAddress = "https://www.mywebsite.com",
Lifetime = new Lifetime(now, now.AddMinutes(60)),
SigningCredentials = new SigningCredentials(new InMemorySymmetricSecurityKey(securityKey),
"http://www.w3.org/2001/04/xmldsig-more#hmac-sha256",
"http://www.w3.org/2001/04/xmlenc#sha256"),
};
var token = tokenHandler.CreateToken(tokenDescriptor);
var tokenString = tokenHandler.WriteToken(token);
return tokenString;
}
}
</script>
I keep getting the following error at line 113 (var token = tokenHandler.CreateToken(tokenDescriptor);):
Argument 1: cannot convert from 'System.IdentityModel.Tokens.SecurityTokenDescriptor' to 'Microsoft.IdentityModel.Tokens.SecurityTokenDescriptor'
But I've seen many examples online doing things exactly as I've done them. I also ran into this article (https://msdn.microsoft.com/en-us/library/jj157089(v=vs.110).aspx) that states the following:
In WIF 3.5, all of the WIF classes were contained in the Microsoft.IdentityModel assembly (microsoft.identitymicrosoft.identitymodel.dll). In WIF 4.5, the WIF classes have been split across the following assemblies: mscorlib (mscorlib.dll), System.IdentityModel (System.IdentityModel.dll), System.IdentityModel.Services (System.IdentityModel.Services.dll), and System.ServiceModel (System.ServiceModel.dll).
The WIF 3.5 classes were all contained in one of the Microsoft.IdentityModel namespaces; for example, Microsoft.IdentityModel, Microsoft.IdentityModel.Tokens, Microsoft.IdentityModel.Web, and so on. In WIF 4.5, the WIF classes are now spread across the System.IdentityModel namespaces, the System.Security.Claims namespace, and the System.ServiceModel.Security namespace. In addition to this reorganization, some WIF 3.5 classes have been dropped in WIF 4.5.
I tried for debugging sake to switch to use the Microsoft.* namespace for the SecurityTokenDescriptor, and then I get another series of errors saying TokenIssuerName, AppliesToAddress, and Lifetime aren't valid properties for that class. Yet when I look at the docs online, seems like those properties do exist on Microsoft.IdentityModel.Tokens.SecurityTokenDescriptor. Yet in my Visual Studio, when I do Go to Definition for that class, they're not there, leading me to believe that there's some kind of configuration issue in my Visual Studio. In my package manager, it shows I have Microsoft.IdentityModel.Tokens v5.0.0 installed. I also changed the project to .NET framework 4.5.1 since the JWT library requires it. Beyond that, I don't know where else to look.
I ran into a similar situation with the OpenID Connect library when I upgraded, which previously was in the Microsoft.IdentityModel.Protocol.Extensions
package (which depended on 4.0.2 of the JWT package) but now is Microsoft.IdentityModel.Protocols.OpenIdConnect
which depends on 2.0.0 of Microsoft.IdentityModel.Protocols
(which depends on 5.0.0 of the JWT package).
Remove any of your Microsoft.IdentityModel*
and System.IdentityModel*
packages, and install only the latest (5.0.0) System.IdentityModel.Tokens.Jwt
package which depends on Microsoft.IdentityModel.Tokens
.
You'll want using statements for these namespaces:
Microsoft has simplified some of the parameters to be more like what you would expect from other platforms' JWT libraries, so the SecurityTokenDescriptor
properties are a little different:
var tokenDescriptor = new SecurityTokenDescriptor
{
Subject = new ClaimsIdentity(new[]
{
new Claim( ClaimTypes.UserData,
"IsValid", ClaimValueTypes.String, "(local)" )
}),
Issuer = "self",
Audience = "https://www.mywebsite.com",
Expires = now.AddMinutes(60),
SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(securityKey), SecurityAlgorithms.HmacSha256),
};
Note that SecurityAlgorithms.HmacSha256
is a string constant for "HS256", just like you'd use in most other libraries. Using the above code plus the example in your question, you should be able to generate a valid JWT.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With