Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Setting of state_handler in Auth0Service causes "Invalid state" error #154

Closed
iAmRoland opened this issue Oct 28, 2019 · 17 comments · Fixed by #156
Closed

Setting of state_handler in Auth0Service causes "Invalid state" error #154

iAmRoland opened this issue Oct 28, 2019 · 17 comments · Fixed by #156
Assignees
Milestone

Comments

@iAmRoland
Copy link

Description

Upgraded from 5.2.0 to 5.3.0 and ran into this issue.

When I attempt to login I get a "Invalid state" error. Went through multiple threads and couple issues here and on other repos without success.

After some time of debugging I found the following line to be a issue:

$auth0Config['state_handler'] = $sessionStateHandler;

Commenting it out made the login work again, but editing vendor files is no fix.

Attempted to find out why. Went into the SDK and dumped out the state, the store does not seem to contain anything. The state variable does never seem to get set. So the validate method returns false all the time. Maybe i'm incorrectly understanding how this should work.

Also is it supposed to set the state handler even if I have state_handler set to false in my config?
Or is that config meant only for the SDK?

Reproduction

This might be specific to something in my project, a bit unsure still.

I'm using the database connection in Auth0, logging in with username and password.

My setup looks pretty much like this guide, with custom user handling:
https://auth0.com/docs/quickstart/webapp/laravel#integrate-auth0-in-your-application

Only differences are the login and logout methods.
On login i'm simply checking if user is logged in and then returning a login view if they're not. On that view I have Lock.js setup and configured.

Maybe a relevant section from that configuration:

auth: {
    redirectUrl: '{{ $auth0Config["redirect_uri"] }}',
    responseType: 'code',
    params: {
        scope: 'openid profile name email'
    }
}

Environment

  • Version of this library used: 5.3.0
  • Version of the platform or framework used, if applicable: Laravel 5.8 and PHP 7.2
  • Other modules/plugins/libraries that might be involved: Using the latest SDK
@joshcanhelp joshcanhelp self-assigned this Oct 28, 2019
@joshcanhelp
Copy link
Contributor

@iAmRoland - Apologies for the delay in getting back to you. We have a few reports of state handling issues in this library, possibly because of the previous release, but I have not been able to reproduce anything so far. We're adjusting how state is handled and stored in the SDK in an upcoming major release but happy to do a patch release if we figure out that the source of this issue is indeed in the SDK or this package.

I would say that Lock.js will complicate things and, in general, we recommend using Universal Login (hosted page) rather than the embedded one.

So, the 5.3.0 was meant to address and fix issues with state handling, mainly due to misuse of the Laravel session handing. Commenting the line out you mentioned will default the SDK to use "regular" session handling for state, which will work for many cases but not all.

In short, state is:

  1. Generated when the login link is generated
  2. Stored in a session store (by default)
  3. Sent to Auth0 when logging in
  4. Returned unchanged to your application's callback URL in a query param
  5. Checked against the stored value
  6. Deleted after the check, valid or not

... so if you're checking what's getting sent and what's stored, you'll want to:

  1. Check both the auth URL and the session store here to make sure both have state values that match
  2. Check both the URL parameters and the session store here to makes sure they are the same

Auth0 Application and Connection settings on the dashboard won't have any effect on state checking, it's all handled in the application code itself.

@mraypold
Copy link

mraypold commented Nov 12, 2019

I'm encountering similar issues when state_handler is set to false upon upgrading from 5.1 to 5.3

I've dug through some code and believe its related to this pull request. #135

If I manually set the constructor in Auth0Service to use the DummyStateHandler instead of the SessionStateHandler then everything works as expected. I believe this is how the library used to handle the scenario when state_handler was false.

I've been unsuccessful in using the Laravel IoC to construct Auth0Service with a DummyStateHandler. I believe this is because the constructor is expecting the SessionStateHandler class instead of the StateHandler interface.

The root of the issue appears to be here.

    /**
     * Auth0Service constructor.
     *
     * @param array $auth0Config
     * @param StoreInterface $sessionStorage
     *
     * @throws \Auth0\SDK\Exception\CoreException
     */
    public function __construct(
        array $auth0Config = null,
        StoreInterface $sessionStorage = null,
        SessionStateHandler $sessionStateHandler = null
    )
    {
        // Backwards compatible fallbacks
        if (!$auth0Config instanceof Repository && !is_array($auth0Config)) {
            $auth0Config = config('laravel-auth0');
        }
        if (!$sessionStorage instanceof StoreInterface) {
            $sessionStorage = new LaravelSessionStore();
        }
        if (!$sessionStateHandler instanceof SessionStateHandler) {
            $sessionStateHandler = new DummyStateHandler($sessionStorage);
        }

        $auth0Config['store'] = $sessionStorage;
        $auth0Config['state_handler'] = $sessionStateHandler;
        $this->auth0 = new Auth0($auth0Config);
    }

Apologies if this isn't clear. I'll try and clarify further if you have questions.

@joshcanhelp
Copy link
Contributor

joshcanhelp commented Nov 13, 2019

@mraypold - Appreciate the detailed report here. You're correct about the instance checking here, that should be StateHandler, not SessionStateHandler. Apologies for the miss there.

But, more critically, we went from accepting a store and state_handler from the configuration to always passing one in LoginServiceProvider->register(). Regardless of the instance check, those will override anything that is in config. Apologies for the even bigger miss there, it didn't occur to me that anyone would be passing along the store and handler that way (though perfectly acceptable).

This definitely needs a patch release. Can you take a look at the diff below and see if this addresses your situation, both the config file and the IoC? My local tests are working.

https://github.com/auth0/laravel-auth0/compare/fix-store-and-state-handing

  1. Fixes the type hint and instance check in the Service and ServiceProvider
  2. Overrides the injected ones with the config values, if present
  3. More clear local var names

If the logic makes sense, I'll get tests in there and submit a PR.

@nstapelbroek - Would you take a look here and make sure this still solves your use case as well?

@joshcanhelp joshcanhelp added this to the 5.3.1 milestone Nov 13, 2019
@mraypold
Copy link

@joshcanhelp I've taken a look at the branch and tested it against our local environments. It appears to have solved the issues we are encountering.

We're currently running a temporary fork with very similar code changes, but your solution looks a bit cleaner.

My only comment would be that I think the composer.json states the library requires PHP 5.5 or higher and the null coalescing used in the new constructor code is a PHP 7 feature.

@joshcanhelp
Copy link
Contributor

@mraypold - Thanks for the quick look here. You're correct about the null coalescing ... I didn't run any PHP compatibility scans yet.

@iAmRoland
Copy link
Author

Tested the changes as well, seems to fix the issue on my end 👍

@nstapelbroek
Copy link
Contributor

nstapelbroek commented Nov 13, 2019

Hey everyone,

Thanks for notifying me. I completely missed this issue in the last couple of days.
I agree with the conversation above: the bug seemed to be introduced in the last PR that did some overhaul on the state and sessionHandler construction logic. The root cause seems simple enough: I did not realise you could set the state_handler or storage to false in the config 😅. My apologies.

The suggested fix in #156 seems good and works on my local setup. 👍

edit: Typos 🤓

@joshcanhelp
Copy link
Contributor

@nstapelbroek - Appreciate the testing and response!

@iAmRoland @mraypold - One thing that would be helpful to know is why you are skipping state checking in your application. I still plan on releasing this patch but disabling state may not be possible in an upcoming major.

@mraypold
Copy link

@joshcanhelp One of our clients requires IdP initiated SSO which required the state_handler to be disabled for this one workflow. In all other cases it was possible to use state handling as recomended by Auth0.

@joshcanhelp
Copy link
Contributor

#156 is ready for final review. Our team will look at it this morning and get a release out today 👍 Thanks for the assistance here everyone

@iAmRoland
Copy link
Author

Awesome!

I disabled state handling when I implemented Lock.js, this was about a year or two ago though. Have not had the time to go through and possibly revamp it, only upgrades and patches mostly.

@joshcanhelp
Copy link
Contributor

Released!

https://packagist.org/packages/auth0/login#5.3.1

@bryanjamesmiller
Copy link

@iAmRoland Can you describe how you disabled state handling? I am having the same issue I think... even on the newer releases. I am also using Lock.js. If @joshcanhelp has any suggestions regarding this same error still happening on 5.3.1 (I've tried a few other updates as well, and always get the same error). I'm trying to update a Laravel app to version 6 (and my next task is to update it to v7). Thanks!

@bryanjamesmiller
Copy link

bryanjamesmiller commented Apr 20, 2020

@joshcanhelp I think this issue should be reopened. I'm trying to upgrade from "auth0/auth0-php": "5.0.4", where everything is working to "auth0/auth0-php": "5.4", and I get "Invalid state":

Screenshot at Apr 20 14-33-20

We are using <script src="https://cdn.auth0.com/js/lock/11.21.0/lock.min.js"></script> as well. The rest of our setup is quite plain and matching to doc specifications. Any help is GREATLY appreciated!!

@bryanjamesmiller
Copy link

@joshcanhelp I think I found a workaround but not sure if it's safe or recommended. In my Controller that loads our Blade file with the login view containing the auth0 lock script, I am registering a state via $state = app(SessionStateHandler::class)->issue(). I am then including the $state in the JS Script via auth: { state: "{{ $state }}", ... }.

I have 2 reservations about the workaround:

  1. I see there is a deprecation warning for SessionStateHandler, and to favor TransientStateHandler instead. However I do not see a TransientStoreHandler class included in this package?
  2. There is no documentation that I could find anywhere describing this workflow with auth0

So if either of these reasons means we shouldn't be doing things this way, can you please respond? Thank you and have a nice day!

@bryanjamesmiller
Copy link

@joshcanhelp though I did just find this: #102 - sorry for all the posts. Maybe they will be helpful to somebody else. I think auth0 should consider adding something about this in the docs.

@joshcanhelp
Copy link
Contributor

@bryanjamesmiller - Apologies for the delay in getting back to you here. The fix here is fixing a specific case where the state_handler is set in the config file. This is just one potential cause of the invalid state error.

I would highly recommend using the latest version of this package, 6.0.0, which will pull in the latest version of the underlying SDK and hopefully help with this issue. The version you're using above is, as you mentioned, using deprecated and now removed components.

If you're still having this issue with the latest version, please open a new Issue with the details of your setup 👍

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Aug 25, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants