2015-10-16 114 views
2

我使用JwtSecurityTokenHandler创建一个JWT令牌JwtSecurityTokenHandler WriteToken和“JSON序列化紧凑格式字符串”。

#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. 

请问这个转换为:“常规”智威汤逊,可以通过客户端浏览器的消耗和解析?

 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); 

所以当我说“正常”的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

您将需要解析的有效载荷从智威汤逊的,它加载到使用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格式的目标之一是尽可能紧凑。向有效负载添加空白是不必要的,并且会增加令牌的大小。