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

[Guard] Adding cutom role to the security token breaks authentication #36603

Closed
alterphp opened this issue Apr 27, 2020 · 6 comments
Closed

[Guard] Adding cutom role to the security token breaks authentication #36603

alterphp opened this issue Apr 27, 2020 · 6 comments

Comments

@alterphp
Copy link

Symfony version(s) affected: 4.4

Description
I'm following Custom Authentication System with Guard to implement my own "switch user" feature (across different firewalls). Instead of extending AbstractGuardAuthenticator as described in the documentation, I use my own implementation of createAuthenticatedToken(UserInterface $user, $providerKey) method.

My goal is just to add a custom role in the generated PostAuthenticationGuardToken.

    /**
     * Shortcut to create a PostAuthenticationGuardToken for you, if you don't really
     * care about which authenticated token you're using.
     *
     * @param string $providerKey
     *
     * @return PostAuthenticationGuardToken
     */
    public function createAuthenticatedToken(UserInterface $user, $providerKey)
    {
        $roles = $user->getRoles();

        // Why adding any custom role breaks authentication ?
        $roles[] = 'ROLE_FOO';

        return new PostAuthenticationGuardToken($user, $providerKey, $roles);
    }

Adding the role in the code above breaks authentication. Adding the roles in the UserInterface::getRoles() method is OK...

Any idea of what is happening here ?

@Nyholm
Copy link
Member

Nyholm commented May 3, 2020

Yes. I think so. Or this is a super wild guess.

Try debugging Symfony\Component\Security\Core\Authentication\Token\AbstractToken::setUser()

My guess is that when you try to authenticate, it will see that the user has changed, ie the roles on your UserInterface entity does not match the roles on the token, and that is why you are unauthenticated.

@alterphp
Copy link
Author

alterphp commented May 3, 2020

Thnaks a lot @Nyholm !

You're right. Method hasUserChanged from AbstractToken checks if roles have changed and then unauthenticate if so...

Only an extra ROLE_PREVIOUS_ADMIN role is allowed, strictly on a SwitchUserToken. The problem is that this type of token requires the previous admin user token to be instanciated. In my case the admin user has logged in to another app kernel (backoffice and front app are separated).

@alterphp
Copy link
Author

alterphp commented May 3, 2020

Maybe using a SwitchUserTokenInterface with a nullable return for method public function getOriginalToken(): ?TokenInterface would be more convenient for cross-firewall/cross-kernel switch user ?

@Nyholm
Copy link
Member

Nyholm commented May 3, 2020

There are a security.always_authenticate_before_granting: true that you may find interesting.


If you doing cross-kernel, then it feels like you need some SSO provider. Ie a third party that helps you authenticate.

But sure, if everything is in the same code base, then you can probably hack your way around somehow. Im not sure what the best way to move forward is though.


Since this is not a symfony bug, could we close this issue and I'll ask you to find support on Slack or StackOverflow? (See https://symfony.com/support).

@ajgarlag
Copy link
Contributor

ajgarlag commented May 3, 2020 via email

@alterphp
Copy link
Author

alterphp commented May 3, 2020

There are a security.always_authenticate_before_granting: true that you may find interesting.

If you doing cross-kernel, then it feels like you need some SSO provider. Ie a third party that helps you authenticate.

But sure, if everything is in the same code base, then you can probably hack your way around somehow. Im not sure what the best way to move forward is though.

Since this is not a symfony bug, could we close this issue and I'll ask you to find support on Slack or StackOverflow? (See https://symfony.com/support).

Cross-kernel is for extra reason and is not the minimal switch_user feature breaker.

Impersonating a user into a different firewall (and different firewall context) is not working with Symfony switch_user feature because SwitchUserToken requires the original token. SSO is relevant for transparent authentication into multiple users, but for the same user. My use case (and I think it's pretty common) is to log in as a front user from an allowed backoffice account, where backoffice and front do not share the same security firewall.

My switch user implementation works but I cannot add an additional role (like ROLE_PREVIOUS_ADMIN). I've pushed a PR in case it seems interesting to the community.

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

Successfully merging a pull request may close this issue.

6 participants