Facebook login fails with "Invalid State" error

Hi everyone!

I’m trying to integrate Auth0 into my .NET MAUI application. I’ve used Add Authentication to .NET MAUI Apps with Auth0 as a reference and after changing “authentication method” to None in control panel all services except FB (Apple, Google and Database) started to work.

Facebook Auth has a weird issue.
From logged out state:

  • login with Facebook
  • LoginResult has Error “Invalid State”

If I’ll try again after the error (FB form is not presented as token is still valid) login works fine.
After explicitly logging out the issue can be reproduced again.

I use development keys on my dev tenant.

Please share any ideas what I need to try next.

Hello @michael.samorokov,
Welcome to the Auth0 Community! :wave:

I’m not sure about the cause of the error message you get with FB, but the following statement puzzles me:

Do you mean that you set the credential settings of your application in the Auth0 dashboard? :thinking:

If so, I’m afraid that your MAUI application is not properly registered with Auth0.

You can see the Credentials tab only if you register your app as a confidential application, such as a regular web application. A MAUI application is a public application and, as mentioned in my article, it must be registered as a Native application.
Choosing the right application type enables certain flows and disable others, and it is relevant from a security perspective.

Please, register your MAUI app as a Native app and see if this is the cause of your problem.

Hi Andrea! Thank you for you reply!

My app is registered as Native app:
image

Here is the setting I was talking about:

Hi @michael.samorokov, that’s the strange thing. Normally you shouldn’t have the Credentials tab enabled for native apps, unless you explicitly enable it through the management API.

Anyway, I don’t know if this setting is the cause of your error. To try to understand what happens, you should provide the set of HTTP requests and responses exchanged between your application and the authorization server.

@andrea.chiarelli I’ve sent the HAR logs to the support and here is his answer:

After reviewing HAR files we can see in our internal logs, that the Login was successful both times. In the failed traces, it stopped just before the token exchange. But the authentication code was issued.
When you login for the second time, since the session already exists in Auth0, we will redirect to the defined callback URL right after you reach the /authorize endpoint.
On the first attempt, the /authorize endpoint will redirect to the login, then to Facebook. After the authentication on Facebook, it redirects back to Auth0, where we exchange the Facebook auth code against their token, and finally redirect back to application callback URL.

Could it be that the state on the starting /authorize call (e.g. /authorize?..&state=xA8Fx4cuKnBza7Cuuv-YmA) is lost during the above redirects to and from Facebook?
Can you somehow check if the state is or isn’t lost? Although, this doesn’t explain why the same error is not happening with Google Social connection.
Can you please confirm, if the Facebook login is confirmed via the same browser or if it launches the Facebook application? Can you also let me know what browser you are testing this on?

The issue I see here is that the application doesn’t really modify requests which are going between Auth0 and Facebook. I use the WebBrowserAuthenticator described in your article:

public class WebBrowserAuthenticator : IdentityModel.OidcClient.Browser.IBrowser
{
    public async Task<BrowserResult> InvokeAsync(BrowserOptions options, CancellationToken cancellationToken = default)
    {
        try
        {
            WebAuthenticatorResult result = await WebAuthenticator.Default.AuthenticateAsync(
                new Uri(options.StartUrl),
                new Uri(options.EndUrl));

            var url = new RequestUrl(options.EndUrl)
                .Create(new Parameters(result.Properties));

            return new BrowserResult
            {
                Response = url,
                ResultType = BrowserResultType.Success
            };
        }
        catch (TaskCanceledException)
        {
            return new BrowserResult
            {
                ResultType = BrowserResultType.UserCancel,
                ErrorDescription = "Login canceled by the user."
            };
        }
    }
}

I’d appreciate any help or ideas where to look next.

I’ve created another app to address confusion with the application type.
While both applications shown as “Native” the new one indeed doesn’t have the “Credentials” tab:
image


Also old app has an additional section in settings:
Auth0-additional-section-in-the-app-not-working

Despite using the new application, I still have the same issue with FB login. I was also able to reproduce the issue using the source from original @andrea.chiarelli repo: GitHub - auth0-blog/dotnet-maui-auth0-app

I’ve suspected that the issue is with my app settings, but here is the report of, I suspect, same issue: crash: login -> logout -> login again · Issue #9 · auth0-blog/dotnet-maui-auth0-app · GitHub

Hey @michael.samorokov,
I did some debugging of the login process with FB and I ran into the same problem.

In practice, the problem is as the support engineers told you, but looking a bit deeper into the problem, it seems that the state parameter is not missing, but changed by FB. FB adds a #_=_ suffix to it and causes the state validation to fail.
Others have this problem as well and the suggested workaround is to remove the suffix before the validation.

However, the IdentityModel.OidcClient library used in the sample project follows the OIDC standard (as it should be) and doesn’t expect this additional suffix.

My suggestion to work around this problem is twofold:

  • Let the support engineers know about this new detail, in case they can figure out a way to overcome the problem.
  • But perhaps more effectively, open an issue in the OidcClient project to see if they know how to handle this problem without modifying the library’s code

I hope this will help solve the problem.

2 Likes

thank you @andrea.chiarelli ! I’ll dig a bit deeper into this FB thing and let you know what I’ve found.

2 Likes

Hi @andrea.chiarelli ,
you were right, removing _=_ helps to fix the facebook issue:

public async Task<BrowserResult> InvokeAsync(BrowserOptions options, CancellationToken cancellationToken = default)
{
    try
    {
        WebAuthenticatorResult result = await WebAuthenticator.Default.AuthenticateAsync(
            new Uri(options.StartUrl),
            new Uri(options.EndUrl));

        var url = new RequestUrl(options.EndUrl)
            .Create(new Parameters(result.Properties));

        // FB adding #_=_ to the end of the url, so we need to remove it
        if (url.EndsWith("%23_%3D_"))
        {
            url = url.Substring(0, url.LastIndexOf("%23_%3D_"));
        }

        return new BrowserResult
        {
            Response = url,
            ResultType = BrowserResultType.Success
        };
    }
    catch (TaskCanceledException)
    {
        return new BrowserResult
        {
            ResultType = BrowserResultType.UserCancel,
            ErrorDescription = "Login canceled by the user."
        };
    }
}
1 Like

Thank you for sharing @michael.samorokov! :pray:
I’ll integrate this workaround into the sample project as soon as possible

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.