I'm new into symfony, and I'm trying to create my own authentication. (I've external auth system so I've declared my User class and UserProvider) I've configured some routes, controllers and security yml, but when I send login form I've end up on error that says
Full authentication is required to access this resource.
Here is my config for security:
security:
encoders:
App\Domain\User\ValueObject\User: bcrypt
providers:
UserProvider:
id: App\Providers\UserProvider
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
login:
pattern: ^/login
anonymous: ~
login_others:
pattern: ^/login/.*$
anonymous: ~
register:
pattern: ^/register.*$
anonymous: ~
bye:
pattern: ^/bye
anonymous: ~
main:
provider: UserProvider
pattern: ^/.*
form_login:
# submit the login form here
check_path: user.login.check
# the user is redirected here when they need to log in
login_path: /login
logout:
path: /logout
target: /login
invalidate_session: false
# Easy way to control access for large sections of your site
# Note: Only the *first* access control that matches will be used
access_control:
- { path: ^/login$, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/login/.*$, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/register.*$, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/bye$, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/.+$, roles: ROLE_USER }
And my controller for routes looks like this:
class LoginController extends Controller
{
/**
* @param AuthenticationUtils $authUtils
* @param TokenStorageInterface $tokenStorage
* @return Response
*
* @Route("/login", name="user.login", methods="GET")
*/
public function loginAction(
AuthenticationUtils $authUtils,
TokenStorageInterface $tokenStorage
) {
if (!is_null($tokenStorage->getToken()) && in_array('ROLE_USER', $tokenStorage->getToken()->getRoles())) {
return $this->redirect($this->generateUrl('dashboard'));
}
$error = $authUtils->getLastAuthenticationError();
$lastUsername = $authUtils->getLastUsername();
return $this->render('user/login.twig', [
'error' => $error,
'last_username' => $lastUsername,
]);
}
/**
*
* @Route("/login_check", name="user.login.check", methods={"POST"})
*/
public function loginCheckAction()
{
}
Any idea what I'm doing wrong? I'm almost sure it's configuration problem, but it appears that I don't understand it.
I've eventually figured out a bit more working configuration
security:
encoders:
App\Domain\User\ValueObject\User: bcrypt
providers:
UserProvider:
id: App\Security\UserProvider
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
main:
anonymous: ~
provider: UserProvider
pattern: ^/.*
form_login:
login_path: user.login
logout:
path: /logout
target: user.login
invalidate_session: false
# Easy way to control access for large sections of your site
# Note: Only the *first* access control that matches will be used
access_control:
- { path: ^/login.*$, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/register.*$, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/.+$, roles: ROLE_USER }
As you see I don't have configured check path for my form_login. That is because It didn't want to replace anonymous user token for the logged one, so I eventually created my own endpoint for login check and did it manually that looks like this:
/**
* @param Request $request
* @param PasswordAuthenticator $authenticator
* @param UserProvider $provider
* @param Session $session
* @param TokenStorageInterface $storage
* @return \Symfony\Component\HttpFoundation\RedirectResponse|Response
*
* @Route("/login/check", name="user.login.check", methods={"POST"})
*/
public function checkLoginUser(
Request $request,
PasswordAuthenticator $authenticator,
UserProvider $provider,
Session $session,
TokenStorageInterface $storage
) {
$token = $authenticator->createToken(
$request,
$request->request->get('_username'),
$request->request->get('_password'),
'UserProvider'
);
$authenticator->supportsToken($token, 'UserProvider');
try {
$newToken = $authenticator->authenticateToken($token, $provider, $token->getUser());
$storage->setToken($newToken);
$session->set('_security_main', serialize($newToken));
return $this->redirect($this->generateUrl('dashboard'));
} catch (CustomUserMessageAuthenticationException $e) {
$error = $e->getMessage();
}
return $this->render('user/login.twig', [
'error' => $error,
'last_username' => $request->request->get('_username'),
]);
}