protected IEnumerable <Claim> GetClaimsFromAccount(TAccount account)
        {
            var claims = new List <Claim> {
                new Claim(Constants.ClaimTypes.Subject, GetSubjectForAccount(account)),
                new Claim(Constants.ClaimTypes.UpdatedAt, EpochTimeExtensions.ToEpochTime(account.LastUpdated).ToString(), ClaimValueTypes.Integer),
                new Claim("tenant", account.Tenant),
                new Claim(Constants.ClaimTypes.PreferredUserName, account.Username),
            };

            if (!String.IsNullOrWhiteSpace(account.Email))
            {
                claims.Add(new Claim(Constants.ClaimTypes.Email, account.Email));
                claims.Add(new Claim(Constants.ClaimTypes.EmailVerified, account.IsAccountVerified ? "true" : "false"));
            }

            if (!String.IsNullOrWhiteSpace(account.MobilePhoneNumber))
            {
                claims.Add(new Claim(Constants.ClaimTypes.PhoneNumber, account.MobilePhoneNumber));
                claims.Add(new Claim(Constants.ClaimTypes.PhoneNumberVerified, !String.IsNullOrWhiteSpace(account.MobilePhoneNumber) ? "true" : "false"));
            }

            claims.AddRange(account.Claims.Select(x => new Claim(x.Type, x.Value)));
            claims.AddRange(userAccountService.MapClaims(account));

            return(claims);
        }
Example #2
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);
            }
        }