Skip to content

Instantly share code, notes, and snippets.

@aimore
Created February 4, 2019 01:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save aimore/9869e8fba1442b44a9cf348468a57bad to your computer and use it in GitHub Desktop.
Save aimore/9869e8fba1442b44a9cf348468a57bad to your computer and use it in GitHub Desktop.
Xamarin.Auth "Authentication Error: Invalid state from server. Possible forgery!" workaround
public class OAuth2AuthenticatorEx : OAuth2Authenticator
{
protected override void OnPageEncountered(Uri url, IDictionary<string, string> query, IDictionary<string, string> fragment)
{
// Remove state from dictionaries.
// We are ignoring request state forgery status
// as we're hitting an ASP.NET service which forwards
// to a third-party OAuth service itself
if (query.ContainsKey("state"))
{
query.Remove("state");
}
if (fragment.ContainsKey("state"))
{
fragment.Remove("state");
}
base.OnPageEncountered(url, query, fragment);
}
}
@fmoghaddampoor
Copy link

Create a class and add this code below:

public class AuthenticatorExtensions : OAuth2Authenticator
{
public AuthenticatorExtensions(string clientId, string clientSecret, string scope, Uri authorizeUrl, Uri redirectUrl, Uri accessTokenUrl, GetUsernameAsyncFunc getUsernameAsync = null, bool isUsingNativeUI = false) : base(clientId, clientSecret, scope, authorizeUrl, redirectUrl, accessTokenUrl, getUsernameAsync, isUsingNativeUI)
{
}
protected override void OnPageEncountered(Uri url, System.Collections.Generic.IDictionary<string, string> query, System.Collections.Generic.IDictionary<string, string> fragment)
{
// Remove state from dictionaries.
// We are ignoring request state forgery status
// as we're hitting an ASP.NET service which forwards
// to a third-party OAuth service itself
if (query.ContainsKey("state"))
{
query.Remove("state");
}

        if (fragment.ContainsKey("state"))
        {
            fragment.Remove("state");
        }

        base.OnPageEncountered(url, query, fragment);
    }
}

Then use it as below:
[Obsolete]
private void SignInGoogleAuth()
{
try
{
string clientId = null;
string redirectUri = null;
//Xamarin.Auth.CustomTabsConfiguration.CustomTabsClosingMessage = null;

            clientId = Constants.GoogleAndroidClientId;
            redirectUri = Constants.GoogleAndroidRedirectUrl;


            account = store.FindAccountsForService(Constants.AppName).FirstOrDefault();

            var authenticator = new AuthenticatorExtensions(
                clientId,
                null,
                Constants.GoogleScope,
                new Uri(Constants.GoogleAuthorizeUrl),
                new Uri(redirectUri),
                new Uri(Constants.GoogleAccessTokenUrl),
                null,
                true);

            authenticator.Completed += OnAuthCompleted;
            authenticator.Error += OnAuthError;

            AuthenticationState.Authenticator = authenticator;

            var presenter = new Xamarin.Auth.Presenters.OAuthLoginPresenter();
            presenter.Login(authenticator);
        }
        catch (Exception ex)
        {
            ShowAlert("Alert", ex.Message);
        }
    }

    [Obsolete]
    async void OnAuthCompleted(object sender, AuthenticatorCompletedEventArgs e)
    {
        var authenticator = sender as OAuth2Authenticator;
        if (authenticator != null)
        {
            authenticator.Completed -= OnAuthCompleted;
            authenticator.Error -= OnAuthError;
        }
        if (e.IsAuthenticated)
        {
                // If the user is authenticated, request their basic user data from Google
                // UserInfoUrl = https://www.googleapis.com/oauth2/v2/userinfo
                var request = new OAuth2Request("GET", new Uri(Constants.GoogleUserInfoUrl), null, e.Account);
                var response = await request.GetResponseAsync();
                if (response != null)
                {
                    // Deserialize the data and store it in the account store
                    // The users email address will be used to identify data in SimpleDB
                    string userJson = await response.GetResponseTextAsync();
                    StaticVariables.googleProfile = JsonConvert.DeserializeObject<GoogleProfile>(userJson);
                }
                if (account != null)
                {
                    store.Delete(account, Constants.AppName);
                }
                await store.SaveAsync(account = e.Account, Constants.AppName);
                Application.Current.Properties.Remove("Id");
                Application.Current.Properties.Remove("FirstName");
                Application.Current.Properties.Remove("LastName");
                Application.Current.Properties.Remove("DisplayName");
                Application.Current.Properties.Remove("EmailAddress");
                Application.Current.Properties.Remove("ProfilePicture");

                Application.Current.Properties.Add("Id", StaticVariables.googleProfile.Id);
                Application.Current.Properties.Add("FirstName", StaticVariables.googleProfile.GivenName);
                Application.Current.Properties.Add("LastName", StaticVariables.googleProfile.FamilyName);
                Application.Current.Properties.Add("DisplayName", StaticVariables.googleProfile.Name);
                Application.Current.Properties.Add("EmailAddress", StaticVariables.googleProfile.Email);
                Application.Current.Properties.Add("ProfilePicture", StaticVariables.googleProfile.Picture);
                await Navigation.PushAsync(new GoogleProfilePage());
        }
    }

    [Obsolete]
    void OnAuthError(object sender, AuthenticatorErrorEventArgs e)
    {
        var authenticator = sender as OAuth2Authenticator;
        if (authenticator != null)
        {
            authenticator.Completed -= OnAuthCompleted;
            authenticator.Error -= OnAuthError;
        }
        Debug.WriteLine("Authentication error: " + e.Message);
    }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment