简体   繁体   中英

Symfony 4 logs in as anonymous after login_check

In Symfony 4, when I log in as a user via a login form, it posts the data to /login_check it identifies and authentificates the user correctly and then, when it redirects the user to the target path, it reauthentificates as an Anonymous user.

I have looked and followed with xdebug all the authentification process and it actually logs in the user, redirects the user and reauthentificates as an anon user. I have no clue as per what could cause this.

When using the Remember me functionality everything works as expected so this is only when not using it.

在此处输入图片说明

The 302 Redirect "POST @login (2c1c05)" is actually logged in as shown here below

在此处输入图片说明

And the security tab displays the user correctly:

在此处输入图片说明

However, the redirect logs out the user and reauthentificates as an anon user:

在此处输入图片说明 在此处输入图片说明

My security configuration looks like this:

security:
    encoders:
        App\Entity\Current\CurrentUser:
            algorithm: sha512
            iterations: 5000
            encode_as_base64: true
        App\Entity\Legacy\User:
            algorithm: sha512
            iterations: 0
            encode_as_base64: false
            id: app.security.legacy_digest
        Symfony\Component\Security\Core\User\User:
            algorithm: sha512

    providers:
        chain_provider:
            chain:
                providers: [in_memory_provider, legacy_entity_provider, current_entity_provider]
        in_memory_provider:
            memory:
                users:
                    bar:
                        password:           sX49rzTmjz3+u9XFIkpphfNxjKHMrPWP7Y6l7sKkadWIgOFuYo+Ixjj6iMCeWr0LlUh9EXfi5nw5lgz4W5LDKA==
                        roles:              [ROLE_USER, ROLE_ADMIN]
        legacy_entity_provider:
            entity:
                class:              App\Entity\Legacy\User
                manager_name:       legacy
                property: username

        current_entity_provider:
            entity:
                class:              App\Entity\Current\CurrentUser
                property:           username
                manager_name:       current


    firewalls:
        dev:
            pattern: ^/(_(profiler|wdt)|css|images|js)/
            security: false
        main:
            provider: chain_provider
            anonymous: true
            form_login:
                login_path: /login
                check_path: /login
                username_parameter: _username
                password_parameter: _password
            logout:
                path: logout
                target: /

    access_control:
         - { path: ^/admin, roles: ROLE_ADMIN }

    role_hierarchy:
        ROLE_ADMIN:      [ROLE_USER]

My login form:

<form id="login-form" action="/login" method="post">
                <fieldset>
                    <label for="login">{% trans %}label.login{% endtrans %}</label>
                    <input class="form-control" type="text" id="username" name="_username" value="{{ last_username }}"/>
                    <label for="password">{% trans %}label.password{% endtrans %}</label>
                    <input type="password" class="form-control mb-2" id="password" name="_password"/>
                    <input type="hidden" name="_target_path" value="{{ path(('myaccount_fr_fr' )) }}"/>
                    <button id="login-button" type="submit" class="btn mb-2  btn-secondary btn-block btn-submit_FX text-uppercase">
                        {% trans %}button.loginSubmit{% endtrans %}
                    </button>
                </fieldset>
            </form>

The login route path:

login:
    path: /login
    controller: App\Controller\SecurityController::login

The SecurityController:

class SecurityController extends Controller
{

    public function login(Request $request, AuthenticationUtils $authenticationUtils)
    {
        $error = $authenticationUtils->getLastAuthenticationError();
        $lastUsername = $authenticationUtils->getLastUsername();

        return $this->render('user/login.html.twig', array (
            'last_username' => $lastUsername,
            'error' => $error,
        ));
    }
}

There are curious behaviours sometimes when wrongly configuring a set of features for our applications and instead of having some sort of error that we need to decypher we only have some sort of collateral effect or behaviour in our application. In this case, when logging in, it would automatically log out the user without giving any further error of whatsoever.

When using AdvancedUserInterface there are 4 extra functions that the User Entity needs to implement

public function isAccountNonExpired();

public function isAccountNonLocked();

public function isCredentialsNonExpired();

public function isEnabled();

Note that this user implementation is now deprecated from 4.1 onwards and the use of User Checkers is now advised instead.

If you follow the documentation you will notice that within the first example you will find this:

On the first example:

    /**
     * @ORM\Column(name="is_active", type="boolean")
     */
    private $isActive;

    public function __construct()
    {
        $this->isActive = true;
        // may not be needed, see section on salt below
        // $this->salt = md5(uniqid('', true));
    }

And then lower down, in the section Forbid Inactive Users (AdvancedUserInterface)

public function isEnabled()
    {
        return $this->isActive;
    }

Well this does not work as you would expect it to work. On subsequent requests, when the user is hydrated by the ORM the object is not fully constructed and isActive returns null. You need to get isActive from the database itself or force it from the constant itself:

private $isActive = true;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM