Need help resolving redirect_uri_mismatch error

335 views Asked by At

I'm using Google/Facebook/LinkedIn authentication on my ASP.NET MVC 5 website. For some reason, every once in a while, some users complain about not being able to login because they get redirect_uri_mismatch error.

As I said, what's strange is that the error seems to happen intermittently and only to some users. I'm including my code down below so that you can point out what I'm doing wrong.

Here's the Startup.cs file code

using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
using System.Web;
using Owin;
using Owin.Security.Providers.LinkedIn;
using Microsoft.Owin.Security.Cookies;
using Microsoft.Owin.Security.Facebook;
using Microsoft.Owin.Security.Google;

namespace myWebSite
{
    public class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            // Set up app to use cookies for authentication
            var cookieOptions = new CookieAuthenticationOptions
            {
                AuthenticationType = "Cookies",
                CookieSecure = CookieSecureOption.SameAsRequest,
                ExpireTimeSpan = TimeSpan.FromMinutes(60),
                SlidingExpiration = true,
                LoginPath = new Microsoft.Owin.PathString("/Account/Login")
            };
            app.UseCookieAuthentication(cookieOptions);

            // Set up external authentication
            var externalCookieOptions = new CookieAuthenticationOptions
            {
                AuthenticationType = "ExternalCookie",
                CookieSecure = CookieSecureOption.SameAsRequest,
                ExpireTimeSpan = TimeSpan.FromMinutes(10),
                AuthenticationMode = Microsoft.Owin.Security.AuthenticationMode.Passive,
                CookieManager = new Helpers.SystemWebCookieManager()
            };
            app.UseCookieAuthentication(externalCookieOptions);

            #region Facebook Authentication

            var fbOptions = new FacebookAuthenticationOptions
            {
                AuthenticationType = "Facebook",
                AppId = "myFacebookAppIdGoesHere",
                AppSecret = "myFacebookAppSecretGoesHere",
                SignInAsAuthenticationType = "ExternalCookie",
                Provider = new FacebookAuthenticationProvider
                {
                    OnAuthenticated = async ctx =>
                    {
                        var token = ctx.AccessToken;

                        var id = ctx.Id;
                        var firstName = ctx.User["first_name"];
                        var middleName = ctx.User["middle_name"];
                        var lastName = ctx.User["last_name"];
                        var gender = ctx.User["gender"];
                        var birthday = ctx.User["birthday"];
                        var email = ctx.User["email"];
                        var username = ctx.User["username"];

                        ctx.Identity.AddClaim(new Claim("urn:myWebSite:AuthorityId", "1", ClaimValueTypes.String, "Facebook"));

                        if (id != null)
                        {
                            ctx.Identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, id.ToString(), ClaimValueTypes.String, "Facebook"));
                        }
                        if (firstName != null)
                        {
                            ctx.Identity.AddClaim(new Claim(ClaimTypes.GivenName, firstName.ToString(), ClaimValueTypes.String, "Facebook"));
                        }
                        if (middleName != null)
                        {
                            ctx.Identity.AddClaim(new Claim("urn:facebook:middle_name", middleName.ToString(), ClaimValueTypes.String, "Facebook"));
                        }
                        if (lastName != null)
                        {
                            ctx.Identity.AddClaim(new Claim(ClaimTypes.Surname, lastName.ToString(), ClaimValueTypes.String, "Facebook"));
                        }
                        if (gender != null)
                        {
                            ctx.Identity.AddClaim(new Claim(ClaimTypes.Gender, gender.ToString(), ClaimValueTypes.String, "Facebook"));
                        }
                        if (birthday != null)
                        {
                            ctx.Identity.AddClaim(new Claim(ClaimTypes.DateOfBirth, birthday.ToString(), ClaimValueTypes.String, "Facebook"));
                        }
                        if (email != null)
                        {
                            ctx.Identity.AddClaim(new Claim(ClaimTypes.Email, email.ToString(), ClaimValueTypes.String, "Facebook"));
                        }

                        ctx.Identity.AddClaim(new Claim("fb.token", token));
                    },
                    OnReturnEndpoint = async ctx =>
                    {
                        if (ctx.Identity == null)
                        {
                            // User is not authenticated
                            throw new HttpException(403, "Unable to authenticate with Facebook...");
                        }
                        else
                        {
                            if (ctx.Properties.Dictionary.ContainsKey("returnUrl"))
                            {
                                ctx.RedirectUri += "?returnUrl=" + ctx.Properties.Dictionary["returnUrl"];
                            }
                        }
                    }
                }
            };
            fbOptions.Scope.Add("user_birthday");
            fbOptions.Scope.Add("email");
            app.UseFacebookAuthentication(fbOptions);

            #endregion

            #region Google Authentication

            var googleOptions = new GoogleOAuth2AuthenticationOptions
            {
                AuthenticationType = "Google",
                ClientId = "myGoogleClientIdGoesHere",
                ClientSecret = "myGoogleClientSecretGoesHere",
                SignInAsAuthenticationType = "ExternalCookie",
                Provider = new GoogleOAuth2AuthenticationProvider
                {
                    OnAuthenticated = async ctx =>
                    {
                        var token = ctx.AccessToken;

                        var id = ctx.Id;
                        var firstName = ctx.GivenName;
                        var middleName = ctx.User["middle_name"];
                        var lastName = ctx.FamilyName;
                        var gender = ctx.User["gender"];
                        var birthday = ctx.User["birthday"];
                        var email = ctx.Email;
                        var username = ctx.User["username"];

                        ctx.Identity.AddClaim(new Claim("urn:myWebSite:AuthorityId", "3", ClaimValueTypes.String, "Google"));

                        if (id != null)
                        {
                            ctx.Identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, id.ToString(), ClaimValueTypes.String, "Google"));
                        }
                        if (firstName != null)
                        {
                            ctx.Identity.AddClaim(new Claim(ClaimTypes.GivenName, firstName.ToString(), ClaimValueTypes.String, "Google"));
                        }
                        if (middleName != null)
                        {
                            ctx.Identity.AddClaim(new Claim("urn:google:middle_name", middleName.ToString(), ClaimValueTypes.String, "Google"));
                        }
                        if (lastName != null)
                        {
                            ctx.Identity.AddClaim(new Claim(ClaimTypes.Surname, lastName.ToString(), ClaimValueTypes.String, "Google"));
                        }
                        if (gender != null)
                        {
                            ctx.Identity.AddClaim(new Claim(ClaimTypes.Gender, gender.ToString(), ClaimValueTypes.String, "Google"));
                        }
                        if (birthday != null)
                        {
                            ctx.Identity.AddClaim(new Claim(ClaimTypes.DateOfBirth, birthday.ToString(), ClaimValueTypes.String, "Google"));
                        }
                        if (email != null)
                        {
                            ctx.Identity.AddClaim(new Claim(ClaimTypes.Email, email.ToString(), ClaimValueTypes.String, "Google"));
                        }

                        ctx.Identity.AddClaim(new Claim("google.token", token));
                    },
                    OnReturnEndpoint = async ctx =>
                    {
                        if (ctx.Identity == null)
                        {
                            // User is not authenticated
                            throw new HttpException(403, "Unable to authenticate with Google...");
                        }
                        else
                        {
                            if (ctx.Properties.Dictionary.ContainsKey("returnUrl"))
                            {
                                ctx.RedirectUri += "?returnUrl=" + ctx.Properties.Dictionary["returnUrl"];
                            }
                        }
                    }
                }
            };
            googleOptions.Scope.Add("openid");
            googleOptions.Scope.Add("email");
            googleOptions.Scope.Add("profile");

            app.UseGoogleAuthentication(googleOptions);

            #endregion

            #region LinkedIn Authentication

            var linkedInOptions = new LinkedInAuthenticationOptions
            {
                AuthenticationType = "LinkedIn",
                ClientId = "myLinkedInClientIdGoesHere",
                ClientSecret = "myLinkedInClientSecretGoesHere",
                SignInAsAuthenticationType = "ExternalCookie",
                Provider = new LinkedInAuthenticationProvider
                {
                    OnAuthenticated = async ctx =>
                    {
                        var token = ctx.AccessToken;

                        var id = ctx.Id;
                        var firstName = ctx.User["first_name"];
                        var middleName = ctx.User["middle_name"];
                        var lastName = ctx.User["last_name"];
                        var gender = ctx.User["gender"];
                        var birthday = ctx.User["birthday"];
                        var email = ctx.Email;
                        var username = ctx.User["username"];

                        ctx.Identity.AddClaim(new Claim("urn:myWebSite:AuthorityId", "4", ClaimValueTypes.String, "LinkedIn"));

                        if (id != null)
                        {
                            ctx.Identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, id.ToString(), ClaimValueTypes.String, "LinkedIn"));
                        }
                        if (firstName != null)
                        {
                            ctx.Identity.AddClaim(new Claim(ClaimTypes.GivenName, firstName.ToString(), ClaimValueTypes.String, "LinkedIn"));
                        }
                        if (middleName != null)
                        {
                            ctx.Identity.AddClaim(new Claim("urn:linkedin:middle_name", middleName.ToString(), ClaimValueTypes.String, "LinkedIn"));
                        }
                        if (lastName != null)
                        {
                            ctx.Identity.AddClaim(new Claim(ClaimTypes.Surname, lastName.ToString(), ClaimValueTypes.String, "LinkedIn"));
                        }
                        if (gender != null)
                        {
                            ctx.Identity.AddClaim(new Claim(ClaimTypes.Gender, gender.ToString(), ClaimValueTypes.String, "LinkedIn"));
                        }
                        if (birthday != null)
                        {
                            ctx.Identity.AddClaim(new Claim(ClaimTypes.DateOfBirth, birthday.ToString(), ClaimValueTypes.String, "LinkedIn"));
                        }
                        if (email != null)
                        {
                            ctx.Identity.AddClaim(new Claim(ClaimTypes.Email, email.ToString(), ClaimValueTypes.String, "LinkedIn"));
                        }

                        ctx.Identity.AddClaim(new Claim("linkedin.token", token));
                    },
                    OnReturnEndpoint = async ctx =>
                    {
                        if (ctx.Identity == null)
                        {
                            // User is not authenticated
                            throw new HttpException(403, "Unable to authenticate with LinkedIn...");
                        }
                        else
                        {
                            if (ctx.Properties.Dictionary.ContainsKey("returnUrl"))
                            {
                                ctx.RedirectUri += "?returnUrl=" + ctx.Properties.Dictionary["returnUrl"];
                            }
                        }
                    }
                }
            };

            app.UseLinkedInAuthentication(linkedInOptions);

            #endregion
        }
    }
}
1

There are 1 answers

0
Sam On BEST ANSWER

In my settings for Google, Facebook and LinkedIn, I only had http://www.yourdomain.com/signin-{socialsite} as the redirect uri. When I also added http://yourdomain.com/signin-{socialsite}, it fixed the issue. If you're having this issue, please make sure you have the return uri with AND without the "www".