I try to set the remember me functionnality in Symfony 5.
When the checkbox isn't checked and logging in, the user is still connected after reopenning the browser.
Here is my config (security.yaml) :
security:
#(...)
firewalls:
#(...)
main:
#(...)
remember_me:
secret: '%kernel.secret%'
lifetime: 31536000 # 365 days in seconds (default)
path: /
# by default, the feature is enabled by checking a
# checkbox in the login form (see below), uncomment the
# following line to always enable it.
#always_remember_me: true
form_login:
login_path: login
check_path: login
use_referer: true
default_target_path: welcome_locale
#(...)
And here is my login checkbox:
<label>
<input type="checkbox" id="remember_me" name="_remember_me" value="remember-me" checked> Remember me</label>
Am I missing something ?
The remember_me config option isn't used for that purpose. As said in the doc:
Once a user is authenticated, their credentials are typically stored in the session. This means that when the session ends they will be logged out and have to provide their login details again next time they wish to access the application. You can allow users to choose to stay logged in for longer than the session lasts using a cookie with the remember_me firewall option
It just says that the session will last longer than the normal session variable by using a cookie.
By default the session isn't destroyed when you close the browser.
In this two posts you can find more info on how to do something like that in PHP which may help you solve it.
Post1
Post2
In my Symfony project I have a members zone accessible only by logged users then I write this in my security.yml (access_control):
{ path: ^/membre/, role: IS_AUTHENTICATED_REMEMBERED }
I did too a form with fos_user_security_check action and a _target_path = detail_page_membre.
When I try to log my user, I was redirected to / and in my log I have this:
User has been authenticated successfully. {"username":"toto"} []
Matched route "detail_page_membre".
Populated the TokenStorage with an anonymous Token.
Access denied, the user is not fully authenticated; redirecting to
authentication entry point.
I don't have write any firewalls maybe it's this?
This issue often happens because of the session:
check your session configuration under framework in config.php file:
framework:
session:
# handler_id set to null will use default session handler from php.ini
handler_id: ~
Read more:
Logging in redirects to the login page with no errors
Symfony2 - Access is denied (user is not fully authenticated)
I would like to authenticate the user through an API (external user provider) running my integration tests.
my config_test.yml
imports:
- { resource: config.yml }
- { resource: parameters_test.yml }
framework:
test: ~
session:
storage_id: session.storage.mock_file
monolog:
handlers:
main:
type: stream
path: %kernel.logs_dir%/%kernel.environment%.log
level: info
After the login (SUCCEED) the next step is ask for user information and I got:
"Full authentication is required to access this resource."
I guess something is happening with the stored session.
I am using Redis on dev and prod to store sessions.
Mocking sessions on the test environment because of
"Failed to start the session because headers have already been sent by "/path/to/bin/phpunit" at line 2."
Doing it manually is working like a charm.
session.storage.mock_file uses by default %kernel.cache_dir%/sessions for a storing of session's file. Check if this folder is writable for both server user and cli user.
'Setting up Permissions' http://symfony.com/doc/current/book/installation.html#configuration-and-setup
Another 2 possible reasons of error:
stateless: true on your firewall in firewalls section. The ContextListener is not created and Token is not saved to the session. AnonymousToken is assigned to next request.
stateless: true you also can have RememberMeToken instead of AnonymousToken if remember_me feature enabled. This token is also not full fledged.
UPDATE
Ensure that intercept_redirects is false in config_test.yml as it may break all redirects.
web_profiler:
toolbar: false
intercept_redirects: false
I'm configuring a Symfony2 application using the FOSUserBundle to use http_digest authentication. This is with Symfony 2.1.0-BETA2.
In security.yml, I am simply switching out http_basic for http_digest and adding the required key property. All else remains the same.
Relevant configuration that works:
firewalls:
main:
pattern: ^/
anonymous: ~
form_login: false
provider: fos_user_bundle
http_basic:
realm: "Example Realm"
Relevant configuration that does not work:
firewalls:
main:
pattern: ^/
anonymous: ~
form_login: false
provider: fos_user_bundle
http_digest:
realm: "Example Realm"
key: "%secret%"
As you can see, the only difference is switching out http_basic for http_digest. Changing the value of the key property appears to make no difference.
When using an in_memory provider, http_digest works just fine. This matter is only present when using the fos_user_bundle provider.
By working, I mean that with when using http_basic, the valid user credentials are accepted. When using http_digest the same valid user details are not accepted and the browser's default http authentication prompt is re-displayed.
Between security configuration changes, I clear both the dev and prod caches, empty the browser cache and close the browser.
Is there something critical I'm missing from the configuration?
Update
I've logged a successful http_basic attempt and an unsuccessful http_digest attempt and diffed the logs.
Both logs are identical up to and including where Doctrine logs the SQL query used for authentication.
Following the authentication query in the http_digest log are the lines:
security.DEBUG: Expected response: '3460e5c31b09d4e8872650838a0c0f1a' but received: '5debe5d0028f65ae292ffdea2616ac19'; is AuthenticationDao returning clear text passwords? [] []
security.INFO: exception 'Symfony\Component\Security\Core\Exception\BadCredentialsException' with message 'Incorrect response' in /home/jon/www/local.app.simplytestable.com/vendor/symfony/symfony/src/Symfony/Component/Security/Http/Firewall/DigestAuthenticationListener.php:105
Passwords, using the FOSUserBundle, are salted and hashed.
I'd like to ascertain whether this matter arises due a misconfiguration on my part or whether it's a bug in the FOSUserBundle.
HTTP digest authentication works, in short, by comparing hashes calculated from values including the username, realm, password and various nonse and replay-avoidance values.
The plaintext password is required on both the client and server side to generate the same hashes.
FOSUserBundle salts and hashes passwords.
The server-side hash generated within the Symfony\Component\Security\Http\Firewall\DigestAuthenticationListener class will be passed a hashed not plaintext password and so can never generate the correct hash for comparison.
I have implemented remember me functionality in Symfony2. When I log in with remember me box checked, cookie named "REMEMBERME" gets created. That cookie is also available if I close browser and open it after many hours. But when I load home page of my application, the cookie gets automatically deleted and I see no user logged in. Can anyone explain me the reason for cookie deletion?
remember_me:
key: qwerty
lifetime: 604800
path: /
domain: ~
This is my security.yml file section
EDIT: I have still not found the solution to this question...
EDIT2: Now got new problem. The REMEMBERME cookie does not get set at all. How to solve this??
SOLVED: see answer below
Although this question has already been answered, I would like to contribute a possible solution, if only for posterity and Google search referrals for this problem :)
"The issue is simple: a remembered used does not have the IS_AUTHENTICATED_FULLY role but only IS_AUTHENTICATED_REMEMBERED to make a difference between a remembered user and a user who logged in"
Source: http://www.mail-archive.com/symfony-users#googlegroups.com/msg34021.html
What this means is that in your security configuration, you must make sure that for every ACL entry the IS_AUTHENTICATED_REMEMBERED role is configured in addition to the IS_AUTHENTICATED_FULLY role.
For example:
#app/config/security.yml
security:
...
access_control:
- { path: ^/login$, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/admin/, role: [IS_AUTHENTICATED_FULLY,IS_AUTHENTICATED_REMEMBERED] }
John.
I've the same issue as you do (or did), what I've found is that when I am (Symfony2 actually =) ) setting REMEMBERME cookie on line 101 at /vendor/symfony/src/Symfony/Component/Security/Http/RememberMe/TokenBasedRememberMeService.php file $user->getPassword() returns NULL, so cookie gets hash calculated with NULL password value.
What happening next, is when you returning to your site being fully confident that you will be automatically authenticated, Symfony begins to check your cookie at the same file as above but on line 58 it founds that cookie hash is not the same as it expects and throws an exception('The cookie\'s hash is invalid.') internally catches it and proceeds somewhere.
So that is the case why in my case cookie doesn't work.
I haven't found a solution yet, but I will dig for it and may be I'm lucky.
Hope your issue is the same and solution will help us both.
The Solution:
When implementing eraseCredentials() which claims to be used to erase user sensitive data from UserInterface do not perform $this->password = null. I've made this mistake because I haven't being understanding its purpose. You can take a glance at Symfony 2 Logout (UserInterface::eraseCredentials) for a little bit of explanation. So it serializes token object and we are in trouble.
I had this problem and the issue was that I did not use single quotation marks in the property key of remember_me section (security.yml).
Change this:
remember_me:
key: qwerty
lifetime: 604800
path: /
domain: ~
to this:
remember_me:
key: 'qwerty'
lifetime: 604800
path: /
domain: ~
You can check it in the symfony documentation:http://symfony.com/doc/2.7/cookbook/security/remember_me.html
try to increase your session lifetime:
(config.yml)
framework:
session:
default_locale: %locale%
auto_start: true
lifetime: 604800
In my case it was a wrong implementation of the supportsClass method of my userProvider, which in turn caused an exception in the TokenBasedRememberMeService class on line 43 (thrown by getUserProvider, and catched elsewhere, thus failing silently).
Digging in the path shown by Dmitry made me solve the issue.
In my case I have implemented a custom Login Handler which was returning a RedirectResponse as per documentation. It turns out that that makes Symfony to bypass the standard login routine, and causing the REMEMBERME cookie not been created/stored.
I had to remove the Login Handler, implement a custom Login Listener with all needed logic.
You can see how to implement a Login Listener here
You should also make sure your "remember_me" input in the login form does not have the value attribute:
This is correct:
<input type="checkbox" id="remember_me" name="_remember_me" />
But this will not work:
<input type="checkbox" id="remember_me" name="_remember_me" value="" />
If you are using form_login, check also that remember_me is enabled in security.yml:
firewalls:
main:
form_login:
# ...
remember_me: true
I had the same issue. After investigation I found that :
/vendor/symfony/doctrine-bridge/Security/User/EntityUserProvider.php::loadUserByUsername() requires to either have set the property field on your entity user provider or that your repository implements Symfony\Bridge\Doctrine\Security\User\UserLoaderInterface and has a method loadUserByUsername().
I just added the property field like so :
providers:
user_provider:
entity:
class: App\Entity\User
property: email
I'm using Symfony 4 and I had a similar problem, the REMEMBERME cookies was not set.
My issue was that I had a value="" set to the input type checkbox field.
So I changed from this
<input type="checkbox" value="" id="remember_me" name="_remember_me">
to this
<input type="checkbox" id="remember_me" name="_remember_me">
In my case, the authenticators was overided with the method supportsRememberMe:
public function supportsRememberMe()
{
return true; // change it to true
}