JwtSecurityTokenHandler WriteToken和' JSON Compact序列化格式字符串"

时间:2015-10-16 13:22:28

标签: asp.net-mvc-4 json.net

我使用JwtSecurityTokenHandler创建JWT令牌。

#region Assembly System.IdentityModel.Tokens.Jwt.dll, v4.0.20622.1351
\packages\System.IdentityModel.Tokens.Jwt.4.0.2.206221351\lib\net45\System.IdentityModel.Tokens.Jwt.dll

namespace System.IdentityModel.Tokens
{
    // Summary:
    //     A System.IdentityModel.Tokens.SecurityTokenHandler designed for creating
    //     and validating Json Web Tokens. See http://tools.ietf.org/html/draft-ietf-oauth-json-web-token-07.
    public class JwtSecurityTokenHandler            

它有一个名为" WriteToken"的方法。描述如下:

    // Summary:
    //     Writes the System.IdentityModel.Tokens.JwtSecurityToken as a JSON Compact
    //     serialized format string.
    //
    //
    // Returns:
    //     The System.IdentityModel.Tokens.JwtSecurityToken as a signed (if System.IdentityModel.Tokens.SigningCredentials
    //     exist) encoded string.

如何将其转换为"常规" JWT可以被客户端浏览器使用并解析吗?

        ClaimsIdentity sofCid = new ClaimsIdentity(new List<Claim>() { new Claim("MyClaimType", "MyClaimValue") }, "Custom");

        var descriptor = new SecurityTokenDescriptor
        {
            Subject = cid,
            AppliesToAddress = "http://myappliesto.com",
            SigningCredentials = new X509SigningCredentials( /* code that looks up the cert */),
            TokenIssuerName = "http://myissuer.com",
            Lifetime = new Lifetime(DateTime.UtcNow, DateTime.UtcNow.AddMinutes(20))
        };


        JwtSecurityTokenHandler jwtHandler = new JwtSecurityTokenHandler();
        SecurityToken jwt = jwtHandler.CreateToken(descriptor);

        string jsonCompactSerializedString = jwtHandler.WriteToken(jwt);

所以当我说&#34;正常&#34; json,如下所示:

{
"isCool":true,
"favoriteColor":"green",
"rocksTheSuburbs":true,
"favoriteDecade":"80",
"isHipToBeSquare":true
}

{
    "iss": "jira:1314039",
    "iat": 1300819370,
    "exp": 1300819380,
    "qsh": "8063ff4ca1e41df7bc90c8ab6d0f6207d491cf6dad7c66ea797b4614b71922e9",
    "sub": "batman",
    "context": {
        "user": {
            "userKey": "batman",
            "username": "bwayne",
            "displayName": "Bruce Wayne"
        }
    }
}

1 个答案:

答案 0 :(得分:1)

您需要将有效负载解析出JWT,使用Json.NET将其加载到对象中,然后使用所需的序列化设置再次输出。目前,我无法提供客户端代码来执行此操作,但是您可以使用C#执行此操作:

internal class Program
{
    private static void Main()
    {
        // Your code

        var sofCid = new ClaimsIdentity(new List<Claim> { new Claim("MyClaimType", "MyClaimValue") }, "Custom");
        var descriptor = new SecurityTokenDescriptor
                         {
                             Subject = sofCid,
                             AppliesToAddress = "http://myappliesto.com",
                             TokenIssuerName = "http://myissuer.com",
                             Lifetime = new Lifetime(DateTime.UtcNow, DateTime.UtcNow.AddMinutes(20))
                         };
        var jwtHandler = new JwtSecurityTokenHandler();
        SecurityToken jwt = jwtHandler.CreateToken(descriptor);
        string jsonCompactSerializedString = jwtHandler.WriteToken(jwt);

        // My code

        string encodedPayload = jsonCompactSerializedString.Split('.')[1];
        string decodedPayload = Base64UrlDecode(encodedPayload);
        object jsonObject = JsonConvert.DeserializeObject(decodedPayload);
        string formattedPayload = JsonConvert.SerializeObject(jsonObject, Formatting.Indented);
    }

    // A helper method for properly base64url decoding the payload
    public static string Base64UrlDecode(string value, Encoding encoding = null)
    {
        string urlDecodedValue = value.Replace('_', '/').Replace('-', '+');

        switch (value.Length % 4)
        {
            case 2:
                urlDecodedValue += "==";
                break;
            case 3:
                urlDecodedValue += "=";
                break;
        }

        return Encoding.ASCII.GetString(Convert.FromBase64String(urlDecodedValue));
    }
}

以下是formattedPayload的样子:

{
  "MyClaimType": "MyClaimValue",
  "iss": "http://myissuer.com",
  "aud": "http://myappliesto.com",
  "exp": 1468957532,
  "nbf": 1468956332
}

但是,我不会修改有效负载本身。 JWT格式的目标之一是尽可能紧凑。不需要在有效负载上添加空格,并且会增加令牌的大小。