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