Dan Kononenko
Dan Kononenko

Reputation: 29

Google OAuth 2 Error: redirect_uri_mismatch random url parameter ASP.NET

I've done authentication via VK, Instagram, Facebook in my site by template below. However google requires "Redirect URL". My redirect URL is like this:

http://localhost:4588/main/AuthenticationCallback?__provider__=google%2B&__sid__=6f3cc5957e4742758719f9b7decc2c09

Parameter "sid" is random every time. So I can't give google precise URL. I tried to input http://localhost:4588/main/AuthenticationCallback as I did for Instagram and it worked for Instagram but Google keeps showing me "400 Error: redirect_uri_mismatch"

I've also tried to pass http://localhost:4588/main/AuthenticationCallback as URL parameter in authorization url to google below. But in this case method "IAuthenticationClient.RequestAuthentication" is not called at all.

Can you advise me what should I input as "Redirect URL" for my Google app?

Template class working with OAuth2:

public class GoogleAuthenticationClient : IAuthenticationClient
{
    public string appId;
    public string appSecret;
    private string redirectUri;

    public GoogleAuthenticationClient(string appId, string appSecret)
    {
        this.appId = appId;
        this.appSecret = appSecret;
    }

    string IAuthenticationClient.ProviderName
    {
        get { return "google+"; }
    }

    void IAuthenticationClient.RequestAuthentication(HttpContextBase context, Uri returnUrl)
    {
        var APP_ID = this.appId;
        this.redirectUri = context.Server.UrlEncode(returnUrl.ToString());

        var address = String.Format(
                "https://accounts.google.com/o/oauth2/auth?client_id={0}&redirect_uri={1}&response_type=code&scope={2}",
                APP_ID, this.redirectUri, "https://www.googleapis.com/auth/plus.login https://www.googleapis.com/auth/userinfo.email"
            );

        HttpContext.Current.Response.Redirect(address, false);
    }

    class AccessToken
    {
        public string access_token = null;
        public string user_id = null;
    }

    class UserData
    {
        public string uid = null;
        public string first_name = null;
        public string last_name = null;
        public string photo_50 = null;
    }

    class UsersData
    {
        public UserData[] response = null;
    }

    AuthenticationResult IAuthenticationClient.VerifyAuthentication(HttpContextBase context)
    {
        try
        {
            string code = context.Request["code"];

            var address = String.Format(
                    "https://accounts.google.com/o/oauth2/token?client_id={0}&client_secret={1}&code={2}&redirect_uri={3}",
                    this.appId, this.appSecret, code, this.redirectUri);

            var response = GoogleAuthenticationClient.Load(address);
            var accessToken = GoogleAuthenticationClient.DeserializeJson<AccessToken>(response);

            address = String.Format(
                    "https://www.googleapis.com/plus/v1/people/{0}?access_token=1/fFBGRNJru1FQd44AzqT3Zg",
                    accessToken.user_id);

            response = GoogleAuthenticationClient.Load(address);
            var usersData = GoogleAuthenticationClient.DeserializeJson<UsersData>(response);
            var userData = usersData.response.First();

            return new AuthenticationResult(
                true, (this as IAuthenticationClient).ProviderName, accessToken.user_id,
                userData.first_name + " " + userData.last_name,
                new Dictionary<string, string>());
        }
        catch (Exception ex)
        {
            return new AuthenticationResult(ex);
        }
    }

    public static string Load(string address)
    {
        var request = WebRequest.Create(address) as HttpWebRequest;
        using (var response = request.GetResponse() as HttpWebResponse)
        {
            using (StreamReader reader = new StreamReader(response.GetResponseStream()))
            {
                return reader.ReadToEnd();
            }
        }
    }

    public static T DeserializeJson<T>(string input)
    {
        var serializer = new JavaScriptSerializer();
        return serializer.Deserialize<T>(input);
    }
}

Code in my Controller:

    public void ExternalLogin(string provider)
    {
        OAuthWebSecurity.RegisterClient(
            client: new GoogleAuthenticationClient(
                    "APP_ID", "APP_CODE"),
            displayName: "google+", // надпись на кнопке
            extraData: null);

        ExternalLoginCallback(provider);
    }

    public void ExternalLoginCallback(string provider)
    {
        OAuthWebSecurity.RequestAuthentication(provider, Url.Action("AuthenticationCallback"));
    }

    public ActionResult AuthenticationCallback()
    {
        var result = OAuthWebSecurity.VerifyAuthentication();

        if (result.IsSuccessful == false)
        {
            return null;
        }
        else
        {
            var provider = result.Provider;
            var uniqueUserID = result.ProviderUserId;
            return RedirectToAction("Main", "Main");
        }            
    }

Upvotes: 1

Views: 4201

Answers (1)

omerio
omerio

Reputation: 1196

You can authorise a redirect URI as explained below, but you can't add any parameters to the redirect uri, please see this answer on how the parameters can be passed to Google google oauth2 redirect_uri with several parameters

The authorised redirect URI needs to be set when you created your client ("APP_ID", "APP_CODE") on the Google Cloud Console. Simply navigate to the API console for your project and edit the Web client to set the correct redirect URI you would like to use.

enter image description here

Upvotes: 5

Related Questions