Ejemplo n.º 1
0
        private bool ValidateToken(string identityToken)
        {
            if (AppController.keys != null)
            {
                //IdentityToken
                if (identityToken != null)
                {
                    //Split the identityToken to get Header and Payload
                    string[] splitValues = identityToken.Split('.');
                    if (splitValues[0] != null)
                    {
                        //Decode header
                        var headerJson = Encoding.UTF8.GetString(Base64Url.Decode(splitValues[0].ToString()));
                        //Deserilaize headerData
                        IdTokenHeader headerData = JsonConvert.DeserializeObject <IdTokenHeader>(headerJson);
                        //Verify if the key id of the key used to sign the payload is not null
                        if (headerData.Kid == null)
                        {
                            return(false);
                        }
                        //Verify if the hashing alg used to sign the payload is not null
                        if (headerData.Alg == null)
                        {
                            return(false);
                        }
                    }
                    if (splitValues[1] != null)
                    {
                        //Decode payload
                        var payloadJson = Encoding.UTF8.GetString(Base64Url.Decode(splitValues[1].ToString()));
                        payloadData = JsonConvert.DeserializeObject <IdTokenJWTClaimTypes>(payloadJson);
                        //Verify Aud matches ClientId
                        if (payloadData.Aud != null)
                        {
                            if (payloadData.Aud[0].ToString() != AppController.clientid)
                            {
                                return(false);
                            }
                        }
                        else
                        {
                            return(false);
                        }
                        //Verify Authtime matches the time the ID token was authorized.
                        if (payloadData.Auth_time == null)
                        {
                            return(false);
                        }
                        //Verify exp matches the time the ID token expires, represented in Unix time (integer seconds).
                        if (payloadData.Exp != null)
                        {
                            long expiration       = Convert.ToInt64(payloadData.Exp);
                            long currentEpochTime = EpochTimeExtensions.ToEpochTime(DateTime.UtcNow);
                            //Verify the ID expiration time with what expiry time you have calculated and saved in your application
                            //If they are equal then it means IdToken has expired
                            if ((expiration - currentEpochTime) <= 0)
                            {
                                return(false);
                            }
                        }
                        //Verify Iat matches the time the ID token was issued, represented in Unix time (integer seconds).
                        if (payloadData.Iat == null)
                        {
                            return(false);
                        }
                        //verify Iss matches the  issuer identifier for the issuer of the response.
                        if (payloadData.Iss != null)
                        {
                            if (payloadData.Iss.ToString() != AppController.issuerEndpoint)
                            {
                                return(false);
                            }
                        }
                        else
                        {
                            return(false);
                        }
                        //Verify sub. Sub is an identifier for the user, unique among all Intuit accounts and never reused.
                        //An Intuit account can have multiple emails at different points in time, but the sub value is never changed.
                        //Use sub within your application as the unique-identifier key for the user.
                        if (payloadData.Sub == null)
                        {
                            return(false);
                        }
                    }
                    //Use external lib to decode mod and expo value and generte hashes
                    RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();

                    //Read values of n and e from discovery document.
                    rsa.ImportParameters(
                        new RSAParameters()
                    {
                        //Read values from discovery document
                        Modulus  = Base64Url.Decode(AppController.mod),
                        Exponent = Base64Url.Decode(AppController.expo)
                    });

                    //Verify Siganture hash matches the signed concatenation of the encoded header and the encoded payload with the specified algorithm
                    SHA256 sha256 = SHA256.Create();

                    byte[] hash = sha256.ComputeHash(Encoding.UTF8.GetBytes(splitValues[0] + '.' + splitValues[1]));

                    RSAPKCS1SignatureDeformatter rsaDeformatter = new RSAPKCS1SignatureDeformatter(rsa);
                    rsaDeformatter.SetHashAlgorithm("SHA256");
                    if (rsaDeformatter.VerifySignature(hash, Base64Url.Decode(splitValues[2])))
                    {
                        //identityToken is valid
                        return(true);
                    }
                    else
                    {
                        //identityToken is not valid
                        return(false);
                    }
                }
                else
                {
                    //identityToken is not valid
                    return(false);
                }
            }
            else
            {
                //Missing mod and expo values
                return(false);
            }
        }
        /// <summary>
        /// Determines whether [is identifier token valid] [the specified identifier token].
        /// </summary>
        /// <param name="idToken">The identifier token.</param>
        /// <returns>
        ///   <c>true</c> if [is identifier token valid] [the specified identifier token]; otherwise, <c>false</c>.
        /// </returns>
        /// <exception cref="System.ArgumentNullException">idToken</exception>
        /// <exception cref="System.Exception">Error validating identity token:</exception>
        public bool IsValidIdToken(string idToken)
        {
            if (string.IsNullOrEmpty(idToken))
            {
                throw new ArgumentNullException("idToken");
            }
            try
            {
                string[] splitValues = idToken.Split('.');
                if (splitValues[0] != null)
                {
                    //decode header
                    var           headerJson = Encoding.UTF8.GetString(FromBase64Url(splitValues[0].ToString()));
                    IdTokenHeader headerData = JsonConvert.DeserializeObject <IdTokenHeader>(headerJson);

                    //Verify if the key id of the key used to sign the payload is not null
                    if (headerData.Kid == null)
                    {
                        return(false);
                    }

                    //Verify if the hashing alg used to sign the payload is not null
                    if (headerData.Alg == null)
                    {
                        return(false);
                    }
                }
                if (splitValues[1] != null)
                {
                    //decode payload
                    var payloadJson = Encoding.UTF8.GetString(FromBase64Url(splitValues[1].ToString()));

                    IdTokenPayload payloadData = JsonConvert.DeserializeObject <IdTokenPayload>(payloadJson);

                    //verify aud matches clientId
                    if (payloadData.Aud != null)
                    {
                        if (payloadData.Aud[0].ToString() != ClientId)
                        {
                            return(false);
                        }
                    }
                    else
                    {
                        return(false);
                    }

                    //verify authtime matches the time the ID token was authorized.
                    if (payloadData.Auth_time == null)
                    {
                        return(false);
                    }

                    //verify exp matches the time the ID token expires, represented in Unix time (integer seconds).
                    if (payloadData.Exp != null)
                    {
                        ulong expiration = Convert.ToUInt64(payloadData.Exp);

                        TimeSpan epochTicks = new TimeSpan(new DateTime(1970, 1, 1).Ticks);
                        TimeSpan unixTicks  = new TimeSpan(DateTime.UtcNow.Ticks) - epochTicks;
                        ulong    unixTime   = Convert.ToUInt64(unixTicks.Milliseconds);
                        //Verify the expiration time with what you expiry time have calculated and saved in your application
                        if ((expiration - unixTime) <= 0)
                        {
                            return(false);
                        }
                    }
                    else
                    {
                        return(false);
                    }

                    //Verify iat matches the time the ID token was issued, represented in Unix time (integer seconds).
                    if (payloadData.Iat == null)
                    {
                        return(false);
                    }

                    //verify iss matches the  issuer identifier for the issuer of the response.
                    if (payloadData.Iss != null)
                    {
                        if (payloadData.Iss.ToString() != issuerUrl)
                        {
                            return(false);
                        }
                    }
                    else
                    {
                        return(false);
                    }

                    //verify sub. sub is an identifier for the user, unique among all Intuit accounts and never reused.
                    //An Intuit account can have multiple emails at different points in time, but the sub value is never changed.
                    //Use sub within your application as the unique-identifier key for the user.
                    if (payloadData.Sub == null)
                    {
                        return(false);
                    }
                }

                //verify Siganture matches the sigend concatenation of the encoded header and the encoded payload with the specified algorithm
                RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();

                //Read values of n and e from discovery document.
                rsa.ImportParameters(
                    new RSAParameters()
                {
                    //Read values from discovery document
                    Modulus  = FromBase64Url(mod),
                    Exponent = FromBase64Url(expo)
                });

                //verify using RSA signature
                SHA256 sha256 = SHA256.Create();
                byte[] hash   = sha256.ComputeHash(Encoding.UTF8.GetBytes(splitValues[0] + '.' + splitValues[1]));

                RSAPKCS1SignatureDeformatter rsaDeformatter = new RSAPKCS1SignatureDeformatter(rsa);
                rsaDeformatter.SetHashAlgorithm("SHA256");
                if (rsaDeformatter.VerifySignature(hash, FromBase64Url(splitValues[2])))
                {
                    return(true);
                }
                else
                {
                    return(false);
                }
            }
            catch (Exception exception)
            {
                throw new Exception("Error validating identity token: ", exception);
            }
        }