Exemple #1
0
        /// <summary>
        /// Token request object initilization to retreive user information
        /// </summary>
        /// <param name="accessToken"></param>
        /// <returns></returns>
        public object GetTokenInfo(string accessToken)
        {
            Oauth2Service.TokeninfoRequest  tokeninfoRequest = new Oauth2Service().Tokeninfo();
            Google.Apis.Discovery.Parameter accessType       = new Google.Apis.Discovery.Parameter {
                DefaultValue = GoogleReqestParameters.offline.ToString(), Name = GoogleReqestParameters.access_type.ToString()
            };
            tokeninfoRequest.RequestParameters.Add("AccessType", accessType);
            tokeninfoRequest.AccessToken = accessToken;
            Tokeninfo tokeninfo = tokeninfoRequest.Execute();

            return(tokeninfo);
        }
Exemple #2
0
        /// <summary>
        /// Is token expired or not
        /// </summary>
        /// <param name="accessToken"></param>
        /// <returns></returns>
        public bool IsTokenExpired(string accessToken)
        {
            Tokeninfo tokeninfo = null;

            Oauth2Service.TokeninfoRequest  tokeninfoRequest = new Oauth2Service().Tokeninfo();
            Google.Apis.Discovery.Parameter accessType       = new Google.Apis.Discovery.Parameter {
                DefaultValue = GoogleReqestParameters.offline.ToString(), Name = GoogleReqestParameters.access_type.ToString()
            };
            tokeninfoRequest.RequestParameters.Add("AccessType", accessType);
            tokeninfoRequest.AccessToken = accessToken;
            try
            {
                tokeninfo = tokeninfoRequest.Execute();
            }
            catch (Exception)
            {
                // ignored
            }
            return(tokeninfo == null);
        }
Exemple #3
0
        /// <summary>
        /// Processes the request based on the path.
        /// </summary>
        /// <param name="context">Contains the request and response.</param>
        public void ProcessRequest(HttpContext context)
        {
            // Get the code from the request POST body.
            string accessToken = context.Request.Params["access_token"];
            string idToken     = context.Request.Params["id_token"];

            // Validate the ID token
            if (idToken != null)
            {
                JwtSecurityToken        token = new JwtSecurityToken(idToken);
                JwtSecurityTokenHandler jsth  = new JwtSecurityTokenHandler();

                // Configure validation
                Byte[][] certBytes = getCertBytes();
                Dictionary <String, X509Certificate2> certificates = new Dictionary <String, X509Certificate2>();

                for (int i = 0; i < certBytes.Length; i++)
                {
                    X509Certificate2 certificate = new X509Certificate2(certBytes[i]);
                    certificates.Add(certificate.Thumbprint, certificate);
                }
                {
                    // Set up token validation
                    TokenValidationParameters tvp = new TokenValidationParameters()
                    {
                        ValidateActor = false,                                    // check the profile ID

                        ValidateAudience = (CLIENT_ID != "YOUR_VALID_CLIENT_ID"), // check the client ID
                        ValidAudience    = CLIENT_ID,

                        ValidateIssuer = true, // check token came from Google
                        ValidIssuer    = "accounts.google.com",

                        ValidateIssuerSigningKey = true,
                        RequireSignedTokens      = true,
                        CertificateValidator     = X509CertificateValidator.None,
                        IssuerSigningKeyResolver = (s, securityToken, identifier, parameters) =>
                        {
                            return(identifier.Select(x =>
                            {
                                // TODO: Consider returning null here if you have case sensitive JWTs.

                                /*if (!certificates.ContainsKey(x.Id))
                                 * {
                                 *  return new X509SecurityKey(certificates[x.Id]);
                                 * }*/
                                if (certificates.ContainsKey(x.Id.ToUpper()))
                                {
                                    return new X509SecurityKey(certificates[x.Id.ToUpper()]);
                                }
                                return null;
                            }).First(x => x != null));
                        },
                        ValidateLifetime      = true,
                        RequireExpirationTime = true,
                        ClockSkew             = TimeSpan.FromHours(13)
                    };

                    try
                    {
                        // Validate using the provider
                        SecurityToken   validatedToken;
                        ClaimsPrincipal cp = jsth.ValidateToken(idToken, tvp, out validatedToken);
                        if (cp != null)
                        {
                            its.valid   = true;
                            its.message = "Valid ID Token.";
                        }
                    }
                    catch (Exception e)
                    {
                        // Multiple certificates are tested.
                        if (its.valid != true)
                        {
                            its.message = "Invalid ID Token.";
                        }
                        if (e.Message.IndexOf("The token is expired") > 0)
                        {
                            // TODO: Check current time in the exception for clock skew.
                        }
                    }
                }

                // Get the Google+ id for this user from the "sub" claim.
                Claim[] claims = token.Claims.ToArray <Claim>();
                for (int i = 0; i < claims.Length; i++)
                {
                    if (claims[i].Type.Equals("sub"))
                    {
                        its.gplus_id = claims[i].Value;
                    }
                }
            }

            // Use Tokeninfo to validate the user and the client.
            var tokeninfo_request = new Oauth2Service().Tokeninfo();

            tokeninfo_request.AccessToken = accessToken;

            // Use Google as a trusted provider to validate the token.
            // Invalid values, including expired tokens, return 400
            Tokeninfo tokeninfo = null;

            try
            {
                tokeninfo = tokeninfo_request.Execute();
                if (tokeninfo.IssuedTo != CLIENT_ID)
                {
                    ats.message = "Access Token not meant for this app.";
                }
                else
                {
                    ats.valid    = true;
                    ats.message  = "Valid Access Token.";
                    ats.gplus_id = tokeninfo.UserId;
                }
            }
            catch (Exception stve)
            {
                ats.message = "Invalid Access Token: " + stve.Message;
            }

            // Use the wrapper to return JSON
            token_status_wrapper tsr = new token_status_wrapper();

            tsr.id_token_status     = its;
            tsr.access_token_status = ats;

            context.Response.StatusCode  = 200;
            context.Response.ContentType = "text/json";
            context.Response.Write(JsonConvert.SerializeObject(tsr));
        }
        /// <summary>
        /// Processes the request based on the path.
        /// </summary>
        /// <param name="context">Contains the request and response.</param>
        public void ProcessRequest(HttpContext context)
        {
            // Get the code from the request POST body.
            string accessToken = context.Request.Params["access_token"];
            string idToken = context.Request.Params["id_token"];

            // Validate the ID token
            if (idToken != null)
            {
                JwtSecurityToken token = new JwtSecurityToken(idToken);
                JwtSecurityTokenHandler jsth = new JwtSecurityTokenHandler();

                // Configure validation
                Byte[][] certBytes = getCertBytes();
                Dictionary<String, X509Certificate2> certificates = new Dictionary<String, X509Certificate2>();

                for (int i = 0; i < certBytes.Length; i++)
                {
                    X509Certificate2 certificate = new X509Certificate2(certBytes[i]);
                    certificates.Add(certificate.Thumbprint, certificate);
                }
                {
                    // Set up token validation
                    TokenValidationParameters tvp = new TokenValidationParameters()
                    {
                        ValidateActor = false, // check the profile ID

                        ValidateAudience = (CLIENT_ID != "YOUR_VALID_CLIENT_ID"), // check the client ID
                        ValidAudience = CLIENT_ID,

                        ValidateIssuer = true, // check token came from Google
                        ValidIssuer = "accounts.google.com",

                        ValidateIssuerSigningKey = true,
                        RequireSignedTokens = true,
                        CertificateValidator = X509CertificateValidator.None,
                        IssuerSigningKeyResolver = (s, securityToken, identifier, parameters) =>
                        {
                            return identifier.Select(x =>
                            {
                                // TODO: Consider returning null here if you have case sensitive JWTs.
                                /*if (!certificates.ContainsKey(x.Id))
                                {
                                    return new X509SecurityKey(certificates[x.Id]);
                                }*/
                                if (certificates.ContainsKey(x.Id.ToUpper()))
                                {
                                    return new X509SecurityKey(certificates[x.Id.ToUpper()]);
                                }
                                return null;
                            }).First(x => x != null);
                        },
                        ValidateLifetime = true,
                        RequireExpirationTime = true,
                        ClockSkew = TimeSpan.FromHours(13)
                    };

                    try
                    {
                        // Validate using the provider
                        SecurityToken validatedToken;
                        ClaimsPrincipal cp = jsth.ValidateToken(idToken, tvp, out validatedToken);
                        if (cp != null)
                        {
                            its.valid = true;
                            its.message = "Valid ID Token.";
                        }
                    }
                    catch (Exception e)
                    {
                        // Multiple certificates are tested.
                        if (its.valid != true)
                        {
                            its.message = "Invalid ID Token.";
                        }
                        if (e.Message.IndexOf("The token is expired") > 0)
                        {
                            // TODO: Check current time in the exception for clock skew.
                        }
                    }
                }

                // Get the Google+ id for this user from the "sub" claim.
                Claim[] claims = token.Claims.ToArray<Claim>();
                for (int i = 0; i < claims.Length; i++)
                {
                    if (claims[i].Type.Equals("sub"))
                    {
                        its.gplus_id = claims[i].Value;
                    }
                }
            }

            // Use Tokeninfo to validate the user and the client.
            var tokeninfo_request = new Oauth2Service().Tokeninfo();
            tokeninfo_request.AccessToken = accessToken;

            // Use Google as a trusted provider to validate the token.
            // Invalid values, including expired tokens, return 400
            Tokeninfo tokeninfo = null;
            try
            {
                tokeninfo = tokeninfo_request.Execute();
                if (tokeninfo.IssuedTo != CLIENT_ID)
                {
                    ats.message = "Access Token not meant for this app.";
                }
                else
                {
                    ats.valid = true;
                    ats.message = "Valid Access Token.";
                    ats.gplus_id = tokeninfo.UserId;
                }
            }
            catch (Exception stve)
            {
                ats.message = "Invalid Access Token: " + stve.Message;
            }

            // Use the wrapper to return JSON
            token_status_wrapper tsr = new token_status_wrapper();
            tsr.id_token_status = its;
            tsr.access_token_status = ats;

            context.Response.StatusCode = 200;
            context.Response.ContentType = "text/json";
            context.Response.Write(JsonConvert.SerializeObject(tsr));
        }
Exemple #5
0
        public User ConnectViaSocialNetwork(User user, string socialNetworkName)
        {
            var _socialNetworkClientId = "";
            var _socialNetworkUserId   = "";
            var _issuedTo = "";

            if (object.Equals(socialNetworkName, "Google"))
            {
                _socialNetworkClientId = ConfigurationManager.AppSettings["GoogleClientKey"];

                var tokeninfo_request = new Oauth2Service().Tokeninfo();
                tokeninfo_request.IdToken = user.SocialNetworkIdToken;
                var tokeninfo = tokeninfo_request.Execute();

                _socialNetworkUserId = tokeninfo.UserId;
                _issuedTo            = tokeninfo.IssuedTo;
            }
            else
            {
                //Social network does not exist
                return(null);
            }

            if (object.Equals(user.SocialNetworkUserId, _socialNetworkUserId) && object.Equals(_socialNetworkClientId, _issuedTo))
            {
                // Credentials match.

                // Check if google user ID already exists in the system.
                string currentEmail = userJdbc.GetEmailBySocialNetworkUserId(socialNetworkName, user.SocialNetworkUserId);

                if (String.IsNullOrWhiteSpace(currentEmail))
                {
                    // Google user ID does not exist in the system.
                    // If email already exists but has not been confirmed, delete it.
                    userJdbc.RemoveUserIfActivationExpired((string)user.Emails[0]);

                    //Generate random alphanumeric password
                    const string chars      = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
                    var          random     = new Random();
                    string       randomPass = new string(Enumerable.Repeat(chars, 8).Select(s => s[random.Next(s.Length)]).ToArray());
                    user.Password = SecurityUtils.CreatePasswordHash(randomPass);

                    //Make sure username is not null
                    if (String.IsNullOrWhiteSpace(user.Username))
                    {
                        var mail = new MailAddress((string)user.Emails[0]);
                        user.Username = mail.User;
                    }

                    //Set profile pic
                    if (String.IsNullOrWhiteSpace(user.ProfilePicURL))
                    {
                        user.ProfilePicURL = Utilities.WS_API_URL + "images/profile_pics/profile_default.jpg";
                    }

                    //Create New User (or update existing one)
                    int userId = userJdbc.CreateUserViaSocialNetwork(user, socialNetworkName);
                    if (userId <= 0)
                    {
                        return(null);
                    }
                }
                else if (!object.Equals(currentEmail, user.Emails[0]))
                {
                    // Google user ID already exists in the system but email has changed (probably a user changed email on social network).
                    // If new email already exists but has not been confirmed, delete it.
                    userJdbc.RemoveUserIfActivationExpired((string)user.Emails[0]);
                    // Add another email to the user.
                    userJdbc.UpdateSocialNetworkEmail(socialNetworkName, user.SocialNetworkUserId, (string)user.Emails[0]);
                }

                // Return user.
                return(userJdbc.GetUserByEmail((string)user.Emails[0]));
            }
            else
            {
                // Credentials did not match.
                return(null);
            }
        }