Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

dnx451 RC1 What happened to InMemorySymmetricSecurityKey?

Tags:

c#

.net

oauth

jwt

hmac

I've been trying to create and sign a JwtSecurityToken using a simple key. And after a lot of research it seems that all the examples I find use the InMemorySymmetricSecurityKey class but unfortunately this class doesn't seem to exist in the newest versions of the System.IdentityModel libraries.

These are the dependencies I'm using:

"System.IdentityModel.Tokens": "5.0.0-rc1-211161024",
"System.IdentityModel.Tokens.Jwt": "5.0.0-rc1-211161024"

I also tried using it's base class SymmetricSecurityKey but then I get the following exception when trying to create the token:

"Value cannot be null.\r\nParameter name: IDX10000: The parameter 'signatureProvider' cannot be a 'null' or an empty object."

This is the code that throws the exception:

public static string CreateTokenHMAC()
{
    HMACSHA256 hmac = new HMACSHA256(Convert.FromBase64String("test"));

    var key = new SymmetricSecurityKey(hmac.Key);

    var signingCredentials = new SigningCredentials(key, SecurityAlgorithms.HmacSha256Signature);

    JwtSecurityToken token = _tokenHandler.CreateJwtSecurityToken(new SecurityTokenDescriptor()
    {
        Audience = AUDIENCE,
        Issuer = ISSUER,
        Expires = DateTime.UtcNow.AddHours(6),
        NotBefore = DateTime.Now,
        Claims = new List<Claim>()
        {
            new Claim(ClaimTypes.Email, "[email protected]")
        },
        SigningCredentials = signingCredentials
    });

    return _tokenHandler.WriteToken(token);
}

It's the first time I'm using JwtSecurityToken so my guess is that I'm probably missing a step somewhere

like image 250
Rui Taborda Avatar asked Feb 17 '16 17:02

Rui Taborda


3 Answers

I was unable to get it to work using the RsaSecurityKey example provided in the accepted answer, but this did work for me (using System.IdentityModel.Tokens.Jwt v5.1.3).

var signingKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes("test"));
var signingCredentials = new SigningCredentials(signingKey, SecurityAlgorithms.HmacSha256);

var securityTokenDescriptor = new SecurityTokenDescriptor()
{
    Subject = new ClaimsIdentity(new List<Claim>()
    {
        new Claim(ClaimTypes.NameIdentifier, "[email protected]"),
        new Claim(ClaimTypes.Role, "Administrator"),
    }, "Custom"),
    NotBefore = DateTime.Now,
    SigningCredentials = signingCredentials,
    Issuer = "self",
    IssuedAt = DateTime.Now,
    Expires = DateTime.Now.AddHours(3),
    Audience = "http://my.website.com"
};

var tokenHandler = new JwtSecurityTokenHandler();
var plainToken = tokenHandler.CreateToken(securityTokenDescriptor);
var signedAndEncodedToken = tokenHandler.WriteToken(plainToken);

and to verify

var validationParameters = new TokenValidationParameters()
{
     ValidateAudience = true,
     ValidAudience = "http://my.website.com",
     ValidateIssuer = true,
     ValidIssuer = "self",
     ValidateIssuerSigningKey = true,
     IssuerSigningKey = signingKey,
     RequireExpirationTime = true,
     ValidateLifetime = true,
     ClockSkew = TimeSpan.Zero
};
try
{
    SecurityToken mytoken = new JwtSecurityToken();
    var myTokenHandler = new JwtSecurityTokenHandler();
    var myPrincipal = myTokenHandler.ValidateToken(signedAndEncodedToken, validationParameters, out mytoken);
} catch (Exception ex)
{
    System.Diagnostics.Debug.WriteLine("Authentication failed");
}
like image 68
jonzim Avatar answered Nov 09 '22 21:11

jonzim


This should work (note this requires RC2 packages > 304180813)

var handler = new JwtSecurityTokenHandler();
var tokenDescriptor = new SecurityTokenDescriptor
{
    Subject = new ClaimsIdentity(
        new Claim[] { new Claim(ClaimTypes.NameIdentifier, "bob") }),
    SigningCredentials = new SigningCredentials(
        new SymmetricSecurityKey(new byte[256]),
        SecurityAlgorithms.HmacSha256)
};

var jwt = handler.CreateEncodedJwt(tokenDescriptor);
like image 31
Brent Schmaltz Avatar answered Nov 09 '22 22:11

Brent Schmaltz


I managed to reach the exact same exception. I worked around the problem by generating the key another way:

RSAParameters keyParams;
using (var rsa = new RSACryptoServiceProvider(2048))
{
    try
    {
        keyParams = rsa.ExportParameters(true);
    }
    finally
    {
        rsa.PersistKeyInCsp = false;
    }
}
RsaSecurityKey key = new RsaSecurityKey(keyParams);
var signingCredentials = new SigningCredentials(key, SecurityAlgorithms.HmacSha256Signature);

Here is a great post about token-based authentication on ASP.NET 5 RC1 by Mark Hughes

like image 2
Jaffar Avatar answered Nov 09 '22 20:11

Jaffar