/// <summary> /// Given a JWT token, decodes it and splits the parts into a /// JsonWebToken object. /// </summary> /// <param name="token">String value formatted according to JWT spec</param> /// <returns>Decoded JsonWebToken object</returns> public static JsonWebToken GetTokenFromString(string token) { if (string.IsNullOrEmpty(token)) { throw new ArgumentException("Token is null or empty", "token"); } JsonWebToken ret = new JsonWebToken(); string[] decodedToken = Decode(token); ret.Header = JsonWebToken.GetPrettyPrintedJson(decodedToken[0]); ret.Body = JsonWebToken.GetPrettyPrintedJson(decodedToken[1]); //signature is not JSON, so output it as the raw value ret.Signature = decodedToken[2]; ret.HeaderClaims = JsonConvert.DeserializeObject <IDictionary <string, object> >(ret.Header); ret.BodyClaims = JsonConvert.DeserializeObject <IDictionary <string, object> >(ret.Body); if (ret.BodyClaims.ContainsKey("actortoken")) { //Actor token is an encoded inner token. Decode it and get the parts. JsonWebToken actorToken = GetTokenFromString(ret.BodyClaims["actortoken"].ToString()); ret.BodyClaims["actortoken"] = actorToken; } string audience = ret.BodyClaims["aud"].ToString(); ret.HostName = string.Empty; ret.TenantID = string.Empty; ret.ClientID = string.Empty; ret.UserID = string.Empty; ret.IssuerID = string.Empty; bool isHighTrust = false; bool isLowTrust = false; bool isContext = false; if (ret.BodyClaims.ContainsKey("appctx") && ret.BodyClaims.ContainsKey("appctxsender") && ret.BodyClaims.ContainsKey("isbrowserhostedapp")) { //This is a SharePoint context token isContext = true; } else if (audience.StartsWith("00000003-0000-0ff1-ce00-000000000000/")) { //This is a SharePoint access token. Now figure out if it's high or low trust if (ret.BodyClaims.ContainsKey("actortoken")) { //This is a high trust token isHighTrust = true; } else { isLowTrust = true; } } else { //This is a JWT token but not one from SharePoint //no-op } if (isHighTrust || isLowTrust || isContext) { ret.HostName = audience.Substring(audience.IndexOf("/") + 1, audience.IndexOf("@") - audience.IndexOf("/") - 1); ret.TenantID = audience.Substring(audience.IndexOf("@") + 1, audience.Length - audience.IndexOf("@") - 1); if (ret.BodyClaims.ContainsKey("nameid")) { ret.UserID = ret.BodyClaims["nameid"].ToString(); } } if (isHighTrust) { //For high-trust apps, the issuerID is in the actortoken ret.IssuerID = ((JsonWebToken)ret.BodyClaims["actortoken"]).BodyClaims["iss"].ToString(); //For high-trust apps, the nameid in the actortoken is the app's client ID string clientID = ((JsonWebToken)ret.BodyClaims["actortoken"]).BodyClaims["nameid"].ToString(); ret.ClientID = clientID.Substring(0, clientID.IndexOf("@")); } if (isLowTrust) { //For low-trust apps, the issuer is Azure ACS. ret.IssuerID = ret.BodyClaims["iss"].ToString(); if (ret.BodyClaims.ContainsKey("actor")) { string clientID = ret.BodyClaims["actor"].ToString(); if (clientID.Contains("@")) { ret.ClientID = clientID.Substring(0, clientID.IndexOf("@")); } else { ret.ClientID = clientID; } } else { if (ret.BodyClaims.ContainsKey("nameid")) { //App-only low-trust string clientID = ret.BodyClaims["nameid"].ToString(); ret.ClientID = clientID.Substring(0, clientID.IndexOf("@")); } } } if (isContext) { ret.IssuerID = ret.BodyClaims["iss"].ToString(); ret.ClientID = audience.Substring(0, audience.IndexOf("/") - 1); } return(ret); }
/// <summary> /// Given a JWT token, decodes it and splits the parts into a /// JsonWebToken object. /// </summary> /// <param name="token">String value formatted according to JWT spec</param> /// <returns>Decoded JsonWebToken object</returns> public static JsonWebToken GetTokenFromString(string token) { if(string.IsNullOrEmpty(token)) { throw new ArgumentException("Token is null or empty", "token"); } JsonWebToken ret = new JsonWebToken(); string[] decodedToken = Decode(token); ret.Header = JsonWebToken.GetPrettyPrintedJson(decodedToken[0]); ret.Body = JsonWebToken.GetPrettyPrintedJson(decodedToken[1]); //signature is not JSON, so output it as the raw value ret.Signature = decodedToken[2]; ret.HeaderClaims = JsonConvert.DeserializeObject<IDictionary<string,object>>(ret.Header); ret.BodyClaims = JsonConvert.DeserializeObject<IDictionary<string, object>>(ret.Body); if (ret.BodyClaims.ContainsKey("actortoken")) { //Actor token is an encoded inner token. Decode it and get the parts. JsonWebToken actorToken = GetTokenFromString(ret.BodyClaims["actortoken"].ToString()); ret.BodyClaims["actortoken"] = actorToken; } string audience = ret.BodyClaims["aud"].ToString(); ret.HostName = string.Empty; ret.TenantID = string.Empty; ret.ClientID = string.Empty; ret.UserID = string.Empty; ret.IssuerID = string.Empty; bool isHighTrust = false; bool isLowTrust = false; bool isContext = false; if(ret.BodyClaims.ContainsKey("appctx") && ret.BodyClaims.ContainsKey("appctxsender") && ret.BodyClaims.ContainsKey("isbrowserhostedapp")) { //This is a SharePoint context token isContext = true; } else if (audience.StartsWith("00000003-0000-0ff1-ce00-000000000000/")) { //This is a SharePoint access token. Now figure out if it's high or low trust if(ret.BodyClaims.ContainsKey("actortoken")) { //This is a high trust token isHighTrust = true; } else { isLowTrust = true; } } else { //This is a JWT token but not one from SharePoint //no-op } if(isHighTrust || isLowTrust || isContext) { ret.HostName = audience.Substring(audience.IndexOf("/") + 1, audience.IndexOf("@") - audience.IndexOf("/") - 1); ret.TenantID = audience.Substring(audience.IndexOf("@") + 1, audience.Length - audience.IndexOf("@") - 1); if (ret.BodyClaims.ContainsKey("nameid")) { ret.UserID = ret.BodyClaims["nameid"].ToString(); } } if(isHighTrust) { //For high-trust apps, the issuerID is in the actortoken ret.IssuerID = ((JsonWebToken)ret.BodyClaims["actortoken"]).BodyClaims["iss"].ToString(); //For high-trust apps, the nameid in the actortoken is the app's client ID string clientID = ((JsonWebToken)ret.BodyClaims["actortoken"]).BodyClaims["nameid"].ToString(); ret.ClientID = clientID.Substring(0, clientID.IndexOf("@")); } if (isLowTrust) { //For low-trust apps, the issuer is Azure ACS. ret.IssuerID = ret.BodyClaims["iss"].ToString(); if (ret.BodyClaims.ContainsKey("actor")) { string clientID = ret.BodyClaims["actor"].ToString(); if (clientID.Contains("@")) { ret.ClientID = clientID.Substring(0, clientID.IndexOf("@")); } else { ret.ClientID = clientID; } } else { if(ret.BodyClaims.ContainsKey("nameid")) { //App-only low-trust string clientID = ret.BodyClaims["nameid"].ToString(); ret.ClientID = clientID.Substring(0, clientID.IndexOf("@")); } } } if(isContext) { ret.IssuerID = ret.BodyClaims["iss"].ToString(); ret.ClientID = audience.Substring(0, audience.IndexOf("/") - 1); } return ret; }
private void PopulatePropertyGrid(JsonWebToken token) { dataGridView3.Rows.Add("ClientID", token.ClientID); dataGridView3.Rows.Add("TenantID", token.TenantID); dataGridView3.Rows.Add("HostName", token.HostName); dataGridView3.Rows.Add("IssuerID", token.IssuerID); dataGridView3.Rows.Add("UserID", token.UserID); }