Symfony2 - Redirection after successful login - authentication

I've just started working through the Symfony 2 tutorials. I have created a bundle with a user class and have tried to follow the instructions to set up a login process. I think I am nearly there, however I'm currently falling at the last hurdle.
I have set up a bundle: Dan\AuthBundle, which contains my user class and another bundle: Dan\HelloBundle which I want to allow only logged in users to access.
My security.yml file is as follows:
security:
encoders:
Dan\AuthBundle\Entity\User: sha512
providers:
main:
entity: { class: Dan\AuthBundle\Entity\User, property: username }
administrators:
entity: { class: DanAuthBundle:User }
firewalls:
secured_area:
pattern: ^/*
form_login:
check_path: /login_check
login_path: /login
always_use_default_target_path: false
default_target_path: /hello
access_control:
- { path: ^/hello/.* }
The main routing.yml file looks like this:
DanAuthBundle:
resource: "#DanAuthBundle/Resources/config/routing.yml"
prefix: /auth/
DanHelloBundle_homepage:
pattern: /hello/
defaults: { _controller: DanHelloBundle:Default:index }
login:
pattern: /login
defaults: {_controller: DanAuthBundle:Default:login }
login_check:
pattern: /login_check
I have created several instances of my user class manually.
If I try to access the url /hello, I correctly get redirected to the login page. If I enter incorrect details, I get the correct message(s) delivered in the template, however, when I log in with the correct details, I receive a 324 (empty response) error (at this time, the url displayed in the browser is login_check).
From reading the documentation, I thought I should be redirected to the page I was originally trying to access?
http://symfony.com/doc/current/book/security.html#using-a-traditional-login-form
By default, if the submitted credentials are correct, the user will be
redirected to the original page that was requested (e.g. /admin/foo).
If the user originally went straight to the login page, he'll be
redirected to the homepage. This can be highly customized, allowing
you to, for example, redirect the user to a specific URL.
Also, if I try to access the page after entering the correct details, I once again get redirected to the login page.
Can anyone see if I've missed anything obvious?
This is from my log file:
[2012-06-18 18:33:47] doctrine.DEBUG: SELECT t0.id AS id1, t0.username
AS username2, t0.salt AS salt3, t0.hashed_password AS hashed_password4
FROM User t0 WHERE t0.username = ? (["hello"]) [] [] [2012-06-18
18:33:47] security.INFO: User "hello" has been authenticated
successfully [] [] [2012-06-18 18:33:47] event.DEBUG: Listener
"Symfony\Component\Security\Http\Firewall::onKernelRequest" stopped
propagation of the event "kernel.request". [] [] [2012-06-18 18:33:47]
event.DEBUG: Listener
"Symfony\Bundle\FrameworkBundle\EventListener\RouterListener" was not
called for event "kernel.request". [] [] [2012-06-18 18:33:47]
event.DEBUG: Listener
"Symfony\Bundle\AsseticBundle\EventListener\RequestListener" was not
called for event "kernel.request". [] [] [2012-06-18 18:33:47]
event.DEBUG: Notified event "kernel.response" to listener
"Symfony\Component\Security\Http\Firewall\ContextListener::onKernelResponse".
[] [] [2012-06-18 18:33:47] security.DEBUG: Write SecurityContext in
the session [] []
Any advice appreciated.
Thanks.

// if you're using Symfony 2.0
$key = '_security.target_path';
// if you're using Symfony 2.1 or greater
// where "main" is the name of your firewall in security.yml
$key = '_security.main.target_path';
// try to redirect to the last page, or fallback to the homepage
if ($this->container->get('session')->has($key)) {
$url = $this->container->get('session')->get($key);
$this->container->get('session')->remove($key);
} else {
$url = $this->container->get('router')->generate('homepage');
}
return new RedirectResponse($url);

You need 2 listeners.
One to set in session last page
Second to redirect after succesfull login
That link will solve your problem: http://www.reecefowell.com/2011/10/26/redirecting-on-loginlogout-in-symfony2-using-loginhandlers/

just use getUser check in your respective action (where you are rendering the login form view) as below:
if($this->getUser()){
return $this->redirect($this->generateUrl('your-redirect-path-alise'));
}

Related

How to block url when the user has not verified their account ? (Symfony 6)

For my project (Symfony 6) I want to restrict some url as long as the user has not validated his account by clicking on the link received by email.
Because since i have make Registration (with symfony's website) I don't understand the interest of this point (account isVerified)
How to do this?
i've tried many things like modify security.yaml
You can give the user an additional role when they verify, then deny access if they don't have it in your controller like so:
// src/Controller/AdminController.php
// ...
public function adminDashboard(): Response
{
$this->denyAccessUnlessGranted('ROLE_VERIFIED');
// or add an optional message - seen by developers
$this->denyAccessUnlessGranted('ROLE_VERIFIED', null, 'User tried to access a page without having ROLE_VERIFIED');
}
https://symfony.com/doc/current/security.html#securing-controllers-and-other-code
You can also deny an entire pattern in security.yml:
# config/packages/security.yaml
security:
# ...
access_control:
# matches /users/verfied/*
- { path: '^/users/verfied', roles: ROLE_VERIFIED}
# matches /users/* except for anything matching the above rule
- { path: '^/users', roles: ROLE_USER }
https://symfony.com/doc/current/security.html#securing-url-patterns-access-control

Symfony 4 login form with security and database users

I was a total noob on Symfony about a week ago and I thought I should just dive in Symfony 4. After a week of trying to solve the basic login problem, I believe the documentation is still missing some parts.
Now I've found a solution and I will share it along with some tips on what you might be doing wrong. First part of the answer is a list of suggestions, while the second part is the creation of a project with working login from scratch (supposing you already have composer installed and using a server like apache).
Part 1: Suggestions
403 Forbidden
Check the access_control: key in security.yaml. The order of the rules has impact, since no more than one rule will match each time. Keep most specific rules on top.
login_check
Make sure the form action sends you to the login_check path, or whatever you changed it to in security.yaml.
Also check that you have declared a route for the login_check path either in a controller or in routes.yaml.
input name
Symfony forms tend to encapsulate input names in an array, while it only expects them to be named _username and _password (you can change that in security.yaml) to count it as a login attempt. So inspect the inputs to make sure the name attributes are correct.
Part 2: Full Symfony 4 Login
Project Setup
Let's start by creating the project. Open cmd/terminal and go to the folder you want to contain the project folder.
cd .../MyProjects
composer create-project symfony/website-skeleton my-project
cd my-project
Now you have created a Symfony 4 website template in .../MyProjects/my-project and the cmd/terminal is in that path and will execute the rest of the commands properly.
Check in your .../MyProjects/my-project/public folder for a .htaccess file. If it exists you are fine, else run the following command.
composer require symfony/apache-pack
You can now find your site by visiting my-project.dev/public. If you want to remove this public path, you should do so using the .htaccess file, not moving the index.php.
Project Settings
1) Edit the DATABASE_URL key inside the .env file to correspond to your database settings.
2) Edit the config/packages/security.yaml file, so it looks like this:
security:
encoders:
App\Entity\User:
algorithm: bcrypt
providers:
user:
entity:
class: App\Entity\User
property: username
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
main:
anonymous: true
provider: user
form_login:
#login_path: login
#check_path: login_check
default_target_path: homepage
#username_parameter: _username
#password_parameter: _password
logout:
#path: /logout
#target: /
access_control:
- { path: ^/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/, roles: ROLE_USER }
- { path: ^/admin, roles: ROLE_ADMIN }
Some explanation:
App\Entity\User is the User entity you 'll create in a while to handle the login.
The user provider is just a name that needs to have a match in providers and firewalls.
The logout key must be declared if you want to allow the user to... well, logout.
Values in #comment reveal the default value we'll be using later on and act as a reference of what you are more likely to change.
User Entity
A user must have a role, but could have more. So let's build a UserRole Entity first for a ManyToMany relationship.
php bin/console make:entity userRole
All entities start with an id property. Add a role too.
php bin/console make:entity user
User needs the username, password and roles properties, but you can add more.
Let's edit the src/Entity/User.php file:
Add the UserInterface interface to your User class.
use Symfony\Component\Security\Core\User\UserInterface;
class User implements UserInterface
Edit the generated getRoles(), to make it return string array.
public function getRoles(): array
{
$roles = $this->roles->toArray();
foreach($roles as $k => $v) {
$roles[$k] = $v->getRole();
}
return $roles;
}
getSalt() and eraseCredentials() are functions to implement the UserInterface interface.
public function getSalt()
{
return null;
}
public function eraseCredentials()
{
}
Using the bcrypt algorithm (as we set in security.yaml) we don't need a salt. It generates automatically one. No, you don't store this salt anywhere and yes, it will produce different hash for the same password every time. But yes, it will work somehow (magic...).
If you need a different algorithm, that uses salt, you need to add a salt property on the User entity.
Homepage
For testing purposes we will create a homepage
php bin/console make:controller homepage
Edit the generated src/Controller/HomepageController.php file to change the root to /
#Route("/", name="homepage")
Login Controller
php bin/console make:controller login
Edit the generated src/Controller/LoginController.php file to make it like this:
<?php
namespace App\Controller;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;
use App\Form\LoginType;
class LoginController extends Controller
{
/**
* #Route("/login", name="login")
*/
public function index(AuthenticationUtils $authenticationUtils)
{
$error = $authenticationUtils->getLastAuthenticationError();
$lastUsername = $authenticationUtils->getLastUsername();
$form = $this->createForm(LoginType::class);
return $this->render('login/index.html.twig', [
'last_username' => $lastUsername,
'error' => $error,
'form' => $form->createView(),
]);
}
/**
* #Route("/logout", name="logout")
*/
public function logout() {}
/**
* #Route("/login_check", name="login_check")
*/
public function login_check() {}
}
Login Form
php bin/console make:form login
You don't have to associate it to the User entity.
Edit the generated src/Form/LoginType.php file to add this:
use Symfony\Component\Form\Extension\Core\Type\PasswordType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
replace this:
$builder
->add('_username')
->add('_password', PasswordType::class)
->add('login', SubmitType::class, ['label' => 'Login'])
;
and add this function, to prevent Symfony from changing the input names you requested above by enclosing them in login[...]
public function getBlockPrefix() {}
Login Template
Edit the templates/login/index.html.twig file to add this code in the {% block body %} ... {% endblock %}:
{% if error %}
<div>{{ error.messageKey|trans(error.messageData, 'security') }}</div>
{% endif %}
{{ form_start(form, {'action': path('login_check'), 'method': 'POST'}) }}
{{ form_widget(form) }}
{{ form_end(form) }}
Database Generation
php bin/console doctrine:migrations:generate
php bin/console doctrine:migrations:migrate
This should have generated your database, according to your User and UserRole entities.
Generate Password
The following command will provide you with a hashed password you can directly insert into the database. The password will be hashed with the algorithm specified in security.yaml.
php bin/console security:encode-password my-password
Hope this helps!
Thank you very much, the documentation lacks some important things, but this works very good. For others, check the order of the access-control entries, because one misplaced entry may block the whole process.
access_control:
- { path: ^/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/admin, roles: ROLE_ADMIN }
This was working, but this not
access_control:
- { path: ^/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/admin, roles: ROLE_ADMIN }
- { path: ^/, roles: IS_AUTHENTICATED_ANONYMOUSLY }

Ember-auth signin test fails with json

I am having some issues with testing my signin/signout and related features of my app. The app works, but the test fail.
For testing, I use a QUnit with testem (I also tried teaspoon)
test "after signin, should redirect user back to previous page", ->
visit '/library'
fillIn '.signin-email', 'example#example.com'
fillIn '.signin-password', 'examplepass'
click '.signin-btn'
andThen ->
equal(testing().path(), 'library', "Should redirect back to library (was #{testing().path()})")
After running the test, I get a failure:
(screenshot here )
Authentication: visiting restricted page as non authenticated user: after signin, should redirect user back to previous page (2, 0, 2)Rerun544 ms
{user_id: 2, auth_token: wVveiyDLuXBXu69pQ2XQwg}
Source:
at Test.QUnitAdapter.Test.Adapter.extend.exception (http://localhost:7357/public/assets/application-aad0a1b2c887cc25124c361787446e83.js:50149:5)
at superWrapper [as exception] (http://localhost:7357/public/assets/application-aad0a1b2c887cc25124c361787446e83.js:13374:16)
at Object.onerror (http://localhost:7357/public/assets/application-aad0a1b2c887cc25124c361787446e83.js:50009:22)
at onerror (http://localhost:7357/public/assets/application-aad0a1b2c887cc25124c361787446e83.js:20453:16)
at EventTarget.trigger (http://localhost:7357/public/assets/application-aad0a1b2c887cc25124c361787446e83.js:20286:22)
at null.<anonymous> (http://localhost:7357/public/assets/application-aad0a1b2c887cc25124c361787446e83.js:20439:14)
at EventTarget.trigger (http://localhost:7357/public/assets/application-aad0a1b2c887cc25124c361787446e83.js:20286:22)
at http://localhost:7357/public/assets/application-aad0a1b2c887cc25124c361787446e83.js:20588:17
Should redirect back to library (was signin)
Expected:
"library"
Result:
"signin"
Diff:
"library" "signin"
Source:
at http://localhost:7357/public/assets/spec/javascripts/integration/authentication_pages_spec.js.js:22:14
at andThen (http://localhost:7357/public/assets/application-aad0a1b2c887cc25124c361787446e83.js:50258:20)
at http://localhost:7357/public/assets/application-aad0a1b2c887cc25124c361787446e83.js:49817:21
at isolate (http://localhost:7357/public/assets/application-aad0a1b2c887cc25124c361787446e83.js:49989:14)
at http://localhost:7357/public/assets/application-aad0a1b2c887cc25124c361787446e83.js:49972:12
at invokeCallback (http://localhost:7357/public/assets/application-aad0a1b2c887cc25124c361787446e83.js:20463:19)
at null.<anonymous> (http://localhost:7357/public/assets/application-aad0a1b2c887cc25124c361787446e83.js:20513:11)
Also, auth.coffee:
App.Auth = Em.Auth.extend
request: 'jquery'
response: 'json'
strategy: 'token'
session: 'cookie'
modules: [
'emberData',
'authRedirectable',
'actionRedirectable'
]
signInEndPoint: '/signin'
signOutEndPoint: '/signout'
tokenKey: 'auth_token'
tokenIdKey: 'user_id'
tokenLocation: 'param'
emberData:
userModel: 'user' # create user model on login
authRedirectable:
route: 'signin'
actionRedirectable:
signInRoute: 'library'
# signInSmart: true
# signInBlacklist: ['signin']
signOutRoute: 'index'
I am unable to find the source of the error, so maybe it is something to do with ember-auth. Any ideas would be very appreciated.
Update 1 [Jan 4th]:
I've written an additional test, which passes only halfway. The test is simpler than the previous in that it does not check a redirect, but only checks that the user name appears in the UI after signin.
test "after signin, TEST", ->
visit '/library'
fillIn '.signin-email', 'user#example.com'
fillIn '.signin-password', 'foobargaz'
click '.signin-btn'
andThen ->
ok exists('.menu-signout'), "signout button exists"
The assertions passes, but I get an additional error reporting the returned JSON as seen in this screenshot. The screenshot basically shows:
[Fail] {user_id: 2, auth_token: wVveiyDLuXBXu69pQ2XQwg}
[Pass] signout button exists
Additionally, I've also run the tests by mocking the ajax requests with mockjax, but with the same failure.
Third, I should note that I had to patch "ember-auth-request-jquery.js" to make it work with ember testing as suggested here
I'm pretty sure you're failing to wait on the first visit to happen, so here's how I read it (I'm no CS person)
You're telling Ember to go to library
Before being sure it's finished navigating you're trying to fill in 2 fields and click a button (all of which probably doesn't exist)
then you check to see if it's library, but while waiting after you thought you clicked, really the page finishes rendering the login page from the visit
Here's what js2coffe says it'd kind of look like (my main point is the then after the visit).
test "after signin, should redirect user back to previous page", ->
visit("/library").then ->
fillIn ".signin-email", "example#example.com"
fillIn ".signin-password", "examplepass"
click(".signin-btn").then ->
equal testing().path(), "library", "Should redirect back to library (was " + (testing().path()) + ")"
Update 1/4: Documentation changed on me
Now we move to educated guess time. Looking through the Ember-auth code it might not be creating any timers/promises that Ember is aware of, in affect Ember thinks it's finished the signin process immediately. So the click promise is resolved immediately and you run your test immediately (andThen waits on the global testing promise to resolve). To test the theory you can do some terrible timeout and see if it does indeed redirect after some time
test "after signin, should redirect user back to previous page", ->
visit "/library"
fillIn ".signin-email", "example#example.com"
fillIn ".signin-password", "examplepass"
click ".signin-btn"
stop()
Ember.run.later this, (->
start()
equal testing().path(), "library", "Should redirect back to library (was " + (testing().path()) + ")"
), 5000
It turns out my coffeescript was not the best in the world.
The module function in QUnit should NOT compile to:
module('Authentication: visiting restricted page as non authenticated user', function() {
return setup(function() {
return Em.run(App, App.advanceReadiness);
});
});
but to:
module('Authentication: visiting restricted page as non authenticated user', {
setup: function() {
Ember.run(App, App.advanceReadiness);
},
// This is also new
teardown: function() {
App.reset();
}
});
Additionally, in my spec_helper.coffee file I had something like this:
QUnit.testStart(function() {
// FIXME: this below made it fail every time
// Ember.run(function() {
// return App.reset();
// });
Ember.testing = true;
});
QUnit.testDone(function() {
Ember.testing = false;
});
QUnit.done(function() {
return Ember.run(function() {
return App.reset();
});
});
which seems to have caused some issues, so I just deleted it and the tests now pass.

Symfony2 hold behavior when extending DefaultAuthenticationSuccessHandler

I want to be able to login in my app via the usual login form and using AJAX directly sending the user/password to the login_check path.
The idea is when user access via AJAX return Response with code 200 or 400 depending if the login success or fails.
Looking at other threads I finally decide to extend the default handlers DefaultAuthenticationSuccessHandler and DefaultAuthenticationFailureHandler to achieve this, export as services and specify in the success_handler property in my secure area.
File service.yml
services:
authentication.success_handler:
class: %mycustom.authentication.success_handler.class%
arguments: ['#security.http_utils', {} ]
public: false
tags:
- { name: 'monolog.logger', channel: 'security' }
authentication.failure_handler:
class: %mycustom.authentication.failure_handler.class%
arguments: ['#http_kernel', '#security.http_utils', {}, '#logger' ]
public: false
tags:
- { name: 'monolog.logger', channel: 'security' }
File security.yml
secured_meems_area:
pattern: ^/somrurl/
form_login:
login_path: /somrurl/login
check_path: /somrurl/api/login_check
success_handler: authentication.success_handler
failure_handler: authentication.failure_handler
require_previous_session: false
All this seems to work, except the behaviour of my extendend handler isn't like the original one. In the default implementation used by Symfony if you access a page/A and you are not logged on, Symfony redirects to the login page and after it you are redirected again to page/A. But this not occurs with my extended handler.
To solve it, I can specify a default_target_path when registering the handler as a service, but I want to understand why it doesn't follow the "normal" behavior.
Any ideas out there.
Thanks in advance.
SOLUTION !!!
After looking and test I found a solution here Symfony2 extending DefaultAuthenticationSuccessHandler
The idea is override the default symfony success/failure handlers instead of define my own and apply in the security.yml file.
File security.yml
secured_meems_area:
pattern: ^/somrurl/
form_login:
login_path: /somrurl/login
check_path: /somrurl/api/login_check
#
# DON'T USE !!!
#
# success_handler: authentication.success_handler
# failure_handler: authentication.failure_handler
#
require_previous_session: false
File service.yml. (NOTE the security. in the service name)
services:
security.authentication.success_handler:
class: %mycustom.authentication.success_handler.class%
arguments: ['#security.http_utils', {} ]
public: false
tags:
- { name: 'monolog.logger', channel: 'security' }
security.authentication.failure_handler:
class: %mycustom.authentication.failure_handler.class%
arguments: ['#http_kernel', '#security.http_utils', {}, '#logger' ]
public: false
tags:
- { name: 'monolog.logger', channel: 'security' }
This way we are overriden the default implementation with our own and don't need to specify the handlers in the security area.

Authentication fails silently in Symfony2

I'm having trouble getting authentication to work but it only appears to happen in very specific circumstances. Authentication is done via a third party API so I've written my own user provider class and inside that class is some code that syncs data between the API and Symfony, as part of that syncing process it determines which roles the user should have.
After doing this it sets up the relationships between the roles and user via a ManyToMany relationship.
The getRoles() method in my User object gets the role objects out of the database and turns it into an array of strings, the role names come from my database and all start with ROLE_.
If I login with an account that should have no extra roles it works fine, but if I login to an account that should have roles I just get sent back to the login screen with no error message.
I've checked the log and saw these entries:
security.INFO: User "test105#example.com" has been authenticated successfully [] []
event.DEBUG: Notified event "security.interactive_login" to listener "Pogo\MyBundle\Listener\LoginListener::onSecurityInteractivelogin". [] []
event.DEBUG: Listener "Symfony\Component\Security\Http\Firewall::onKernelRequest" stopped propagation of the event "kernel.request". [] []
event.DEBUG: Listener "Symfony\Bundle\FrameworkBundle\EventListener\RouterListener" was not called for event "kernel.request". [] []
event.DEBUG: Listener "Symfony\Bundle\AsseticBundle\EventListener\RequestListener" was not called for event "kernel.request". [] []
event.DEBUG: Notified event "kernel.response" to listener "Symfony\Component\Security\Http\Firewall\ContextListener::onKernelResponse". [] []
security.DEBUG: Write SecurityContext in the session [] []
event.DEBUG: Notified event "kernel.response" to listener "Symfony\Component\HttpKernel\EventListener\ResponseListener::onKernelResponse". [] []
event.DEBUG: Notified event "kernel.response" to listener "Symfony\Bundle\SecurityBundle\EventListener\ResponseListener::onKernelResponse". [] []
event.DEBUG: Notified event "kernel.response" to listener "Symfony\Bridge\Monolog\Handler\FirePHPHandler::onKernelResponse". [] []
event.DEBUG: Notified event "kernel.response" to listener "Sensio\Bundle\FrameworkExtraBundle\EventListener\CacheListener::onKernelResponse". [] []
event.DEBUG: Notified event "kernel.response" to listener "Symfony\Component\HttpKernel\EventListener\ProfilerListener::onKernelResponse". [] []
event.DEBUG: Notified event "kernel.response" to listener "Symfony\Bundle\WebProfilerBundle\EventListener\WebDebugToolbarListener::onKernelResponse". [] []
event.DEBUG: Notified event "kernel.request" to listener "Symfony\Bundle\FrameworkBundle\EventListener\RouterListener::onEarlyKernelRequest". [] []
event.DEBUG: Notified event "kernel.request" to listener "Symfony\Bundle\FrameworkBundle\EventListener\SessionListener::onKernelRequest". [] []
event.DEBUG: Notified event "kernel.request" to listener "Symfony\Component\Security\Http\Firewall::onKernelRequest". [] []
security.INFO: Populated SecurityContext with an anonymous Token [] []
event.DEBUG: Notified event "kernel.exception" to listener "Symfony\Component\Security\Http\Firewall\ExceptionListener::onKernelException". [] []
security.DEBUG: Access denied (user is not fully authenticated); redirecting to authentication entry point [] []
security.DEBUG: Calling Authentication entry point [] []
I don't understand how it can be authenticated at top, then as soon as it checks the firewall it finds itself with an anonymous token which is why it presumably sends me back to the login screen.
My firewall / access_control settings are:
firewalls:
public:
pattern: /.*
anonymous: true
tessitura_login:
login_path: /account/login
check_path: /secure/login_check
logout:
path: /secure/logout
target: /
access_control:
- { path: ^/secure/.*, role: ROLE_USER }
- { path: ^/admin.*, role: ROLE_ADMIN }
- { path: ^/account/login/?, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: /.*, role: IS_AUTHENTICATED_ANONYMOUSLY }
Any help with this would be massively appreciated, I've spent a few hours on this now and am completely stumped.
Got this silent fail issue when was using phone number as username and didn't specified username property in refreshUser() method, which should be:
public function refreshUser(UserInterface $customer)
{
$class = get_class($customer);
if( !$this->supportsClass($class) ) {
throw new UnsupportedUserException("Instances of \"{$class}\" are not supported");
}
return $this->loadUserByUsername($customer->getPhoneNumber()); // <-- This is it!
}
I think I'm not the only one who missed it, might help.
A broken session storage caused this for me. I was using PdoSessionHandler and disappointingly it gave no clear error or log message.
I've experienced the same. When my users logs in I check what role he has with a couple of statements like this:
if(true === $this->get('security.context')->isGranted('ROLE_MANAGER')){
//return redirect
}
if(true === $this->get('security.context')->isGranted('ROLE_USER')){
//return redirect
}
//throw error
Time to time some users get an error thrown in their face. I imagine that it is because of the same reason. The user is somehow authenticated but haven't got their role.
I can't reproduce the problem my self. I have just heard error reports from my users.
I've experienced the same. And for me it was because the /tmp partition was full so the session can be store on server side and avter redirect to the nex
I just experienced the same issue when logging in to my system where sessions are configured to be stored in memcache but memcached was not running. As said above unfortunately it gave no better error message.
Hope that helps someone to save some time ;-)
I had the same issue with the user login i have used the sonata admin bundle and i was also using the database session with PdoSessionHandler
session.handler.pdo:
class: Symfony\Component\HttpFoundation\Session\Storage\Handler\PdoSessionHandler
arguments: ["#pdo", %pdo.db_options%]
First issue i got when i create a group with lot of roles/permissions the data truncated in the field so i alter my roles field with longtext and changed the ROW_FORMAT=COMPRESSED
ALTER TABLE `fos_group` CHANGE `roles` `roles` LONGTEXT NOT NULL COMMENT '(DC2Type:array)';
ALTER TABLE `fos_group`
ENGINE=INNODB
ROW_FORMAT=COMPRESSED
KEY_BLOCK_SIZE=8;
It does the job and save all the roles/permissions into the field as complete serialized string.But user was unable to login with no error message then i have review the logs generated by symfony in app/logs dir it has
user has been authenticated successfully
and then redirect to dashboard but from dashboard the logs generated as
access denied (user is not fully authenticated)
the reason was the session data is truncated in the session table so i alter my session table as well and this does the job
ALTER TABLE `session` CHANGE `session_value` `session_value` LONGTEXT NOT NULL;
ALTER TABLE `session`
ENGINE=INNODB
ROW_FORMAT=COMPRESSED
KEY_BLOCK_SIZE=8;
I have also updated my.ini file and changed the file format to Barracuda by default file format is antelop
[mysqld]
innodb_file_per_table
innodb_file_format = Barracuda