I am new in symfony2 and I am trying to learn login page in symfony2 but system gives me this error
The security context contains no authentication token. One possible reason may be that there is no firewall configured for this URL.
My security.yml code is:
security:
encoders:
Symfony\Component\Security\Core\User\User: plaintext
role_hierarchy:
ROLE_ADMIN: ROLE_USER
ROLE_SUPER_ADMIN: [ROLE_USER, ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH]
providers:
in_memory:
memory:
users:
user: { password: userpass, roles: [ 'ROLE_USER' ] }
admin: { password: admin, roles: [ 'ROLE_ADMIN' ] }
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
login:
pattern: ^/demo/secured/login$
security: false
emp:
pattern: ^/emp
form_login:
check_path: acme_radixemp_logincheck
login_path: acme_radixemp_login
logout:
path: acme_radixemp_logout
target: demo
#anonymous: ~
#http_basic:
# realm: "Secured Demo Area"
access_control:
- { path: ^/emp, roles: ROLE_ADMIN }
And I am trying to run /emp from url
And my login function in controller is :
public function loginAction(Request $request)
{
$login = new user();
$form = $this->createFormBuilder($login)
->add('Username','text',array('attr' => array('size' => '50',"value"=>"",'class'=>'form-control','placeholder'=>"Please Enter Your Username")))
->add('Password', 'password',array('attr' => array('size' => '50',"value"=>"",'class'=>'form-control','placeholder'=>"Enter Your Password")))
->add('login', 'submit',array('attr' => array('class '=>"btn btn-success btn-lg","style"=>"margin-top:15px")))
->getForm()
;
$form->handleRequest($request);
$session = $this->getRequest()->getSession();
$url = $this->generateUrl("emp");
$loginurl = $this->generateUrl("acme_radixemp_login",array("login"=>"fail"));
$postData = $request->request->get('form');
if(!empty($postData)) {
$repository = $this->getDoctrine()->getRepository('AcmeRadixempBundle:user');
$user_name = $repository->findOneBy(array('username' => $postData['Username'],'password'=>$postData['Password']));
if($user_name=="") {
return $this->redirect($loginurl);
} else {
//$this->get('security.context')->isGranted('ROLE_ADMIN');
if(TRUE ===$this->get('security.context')->isGranted('ROLE_ADMIN') )
{
$session->set('username', $postData['Username']);
return $this->redirect($url);
}
}
}
}
return $this->render('AcmeRadixempBundle:Default:login.html.twig',array('login'=> $form->createView()));
}
What did I forgot to do ?
Your check_path and login_path are not standard. If the actions for your settings are not implemented and the correct paths are not registered, your login functionality won't work.
I'd suggest you follow the example in the Symfony book:
Using a Traditional Login Form
I followed it step-by-step and it worked immediately. For simple logins you won't be needing to create the loginAction or logoutAction at all, the Symfony will do everything for you. The only thing you need to create (and you can copy-paste it from the link I've sent you) is the login form. You can find all other more complex information in the book and the cookbook, both available freely on the Symfony website.
Hope this helps.
Related
I'm using HWIOAuthBundle with Symfony 4.1.
My custom user provider gets called and returns a valid user, however the user is not logged in after the redirect. The web profiler shows: logged in as anon; anonymous token; firewall main
I've simplified the provider class below for brevity and it's only considering twitter right now. The conditions around $source are so I can add more later.
I have used xdebug to make sure loadUserByOauthuserResponse() is being called and that users are both being created in the case of a new user, or the existing user is being returned when it exists.
Question: If loadUserbyOauthUserResponse() IS returning a valid user entity, then what could be preventing it from creating a valid session with this user?
<?php
namespace App\Security;
...
class OAuthProvider extends OAuthUserProvider
{
...
public function loadUserByOAuthUserResponse(UserResponseInterface $response): User
{
/** #var EntityManager $em */
$em = $this->container->get('doctrine.orm.entity_manager');
$repo = $em->getRepository('App:User');
$source = $response->getResourceOwner()->getName();
$email = null;
$data = [];
$newUser = false;
// Set email and socialUser.
if ($source === 'twitter') {
$data = $response->getData();
$email = $data['email'];
}
// Check if this user already exists in our app.
$user = $repo->findOneBy(['email' => $email]);
if ($user === null) {
$newUser = true;
$user = new User();
$user->setPassword($this->strand(32));
}
// Set session and user data based on source.
if ($source === 'twitter') {
$name = $data['name'];
if ($newUser) {
$user->setNickName($name);
$user->setEmail($email);
$em->persist($user);
$em->flush();
}
}
return $user;
}
}
hwi_oauth.yaml
hwi_oauth:
# list of names of the firewalls in which this bundle is active, this setting MUST be set
firewall_names: [main]
# https://github.com/hwi/HWIOAuthBundle/blob/master/Resources/doc/2-configuring_resource_owners.md
resource_owners:
twitter:
type: twitter
client_id: '%env(TWITTER_ID)%'
client_secret: '%env(TWITTER_SECRET)%'
options:
include_email: true
services.yaml:
app.oauth_aware.user_provider.service:
class: App\Security\OAuthProvider
arguments: ['#service_container']
security.yaml:
security:
# https://symfony.com/doc/current/book/security.html#where-do-users-come-from-user-providers
encoders:
App\Entity\User: bcrypt
role_hierarchy:
ROLE_ADMIN: ROLE_USER
ROLE_SUPER_ADMIN: ROLE_ADMIN
providers:
app_users:
entity: { class: App\Entity\User, property: email }
hwi:
id: app.oauth_aware.user_provider.service
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
main:
provider: app_users
anonymous: ~
remember_me:
secret: "%env(APP_SECRET)%"
lifetime: 2592000
path: /
guard:
authenticators:
- App\Security\LoginFormAuthenticator
entry_point: App\Security\LoginFormAuthenticator
logout:
path: /logout
target: /
oauth:
resource_owners:
twitter: "/login/check-twitter"
default_target_path: /
login_path: /
failure_path: /user-login
oauth_user_provider:
service: app.oauth_aware.user_provider.service
switch_user: ~
access_control:
- { path: ^/login$, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/register, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/recover, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/admin/, role: ROLE_ADMIN }
I had the same problem until I found in logs "Token was deauthenticated after trying to refresh it."
And after that I found this solution.
Token was deauthenticated after trying to refresh it
I added isEqualTo and did not logged me out.
I try to create a connection system with form.
But I still get the message: "Bad credentials."
security:
encoders:
Symfony\Component\Security\Core\User\User: plaintext
Tp\Bundle\AppBundle\Entity\User: plaintext
providers:
in_memory:
memory:
users:
user: { password: userpass, roles: [ 'ROLE_USER' ] }
admin: { password: adminpass, roles: [ 'ROLE_ADMIN' ] }
tp:
entity: { class: TpAppBundle:User, property: email }
firewalls:
# disables authentication for assets and the profiler, adapt it according to your needs
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
login:
pattern: ^/login$
security: false
tp:
pattern: ^/
provider: tp
#anonymous: ~
form_login:
login_path: login
check_path: login_check
default_target_path: user_index
always_use_default_target_path: true
logout:
path: logout
target: login
<?php
namespace Tp\Bundle\AppBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\Security\Core\SecurityContext;
class SecurityController extends Controller
{
public function loginAction()
{
$request = $this->getRequest();
$session = $request->getSession();
// get the login error if there is one
if ($request->attributes->has(SecurityContext::AUTHENTICATION_ERROR)) {
$error = $request->attributes->get(SecurityContext::AUTHENTICATION_ERROR);
} else {
$error = $session->get(SecurityContext::AUTHENTICATION_ERROR);
$session->remove(SecurityContext::AUTHENTICATION_ERROR);
}
return $this->render('TpAppBundle:Security:login.html.twig', array(
// last username entered by the user
'email' => $session->get(SecurityContext::LAST_USERNAME),
'error' => $error,
));
}
}
class User implements UserInterface {
...
In my date base,
User
email:test#test.com
password: test
But unable to connect.
I still have the same message: Bad credentials.
Have you any idea?
Do you need more?
Thank you very much
I'm trying to use FOS UserBundle to manage users on my project.
Here is my security.yml file :
security:
encoders:
Symfony\Component\Security\Core\User\User: plaintext
FOS\UserBundle\Model\UserInterface: sha512
role_hierarchy:
ROLE_ADMIN: ROLE_USER
ROLE_SUPER_ADMIN: ROLE_ADMIN
providers:
in_memory:
memory:
users:
user: { password: userpass, roles: [ 'ROLE_USER' ] }
admin: { password: adminpass, roles: [ 'ROLE_ADMIN' ] }
fos_userbundle:
id: fos_user.user_provider.username
firewalls:
main:
pattern: ^/
form_login:
provider: fos_userbundle
csrf_provider: form.csrf_provider
logout: true
anonymous: true
access_control:
#- { path: ^/login, roles: IS_AUTHENTICATED_ANONYMOUSLY, requires_channel: https }
- { path: ^/login$, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/register, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/resetting, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/admin/, role: ROLE_ADMIN }
I have manually set my user's rights in my controller like below :
public function testGroupsAction( UserInterface $user )
{
$user->addRole("ROLE_ADMIN");
$this->getDoctrine()->getManager()->persist($user);
$this->getDoctrine()->getManager()->flush();
echo "<pre>";
\Doctrine\Common\Util\Debug::dump($user->getRoles());
echo "</pre>";die;
}
the $user->getRoles() function returns me an array with all my user's roles :
array (size=3)
0 => string 'ROLE_SUPER_ADMIN' (length=16)
1 => string 'ROLE_ADMIN' (length=10)
2 => string 'ROLE_USER' (length=9)
(ROLE_SUPER_ADMIN has been added during my tests)
However when i try to reach a route like "/admin/my/route"n i've got a 403 access forbidden.
Any idea why Symfony doesn't want my user to access admin pages?
Edit :
When i look in the profiler, the user only has [ROLE_USER]...
Thank you.
I finally got it working.
Thanks to Zizoujab, I tried FOSUserBundle's commands to promote a user :
> php app/console fos:user:promote myUser
It worked perfectly well. However, as I have no ssh access nor any other command line tool on my server, i needed to do it via PHP code.
So i went to the Command code FOS\UserBundle\Command\PromoteUserCommand which uses the FOS\UserBundle\Util\UserManipulator to do actions on the user.
So if you want to modify your User directly in your controller, you can use it, but I don't know if it is the best way to do it. Just call it via your container like this :
/**
* #Route("/user/{id}", name="test_user")
* #ParamConverter("user" , class="MyBundle:User")
*/
public function testUserAction( UserInterface $user )
{
$userManipulator = $this->container->get("fos_user.util.user_manipulator");
$userManipulator->addRole($user,'ROLE_ADMIN');
return new Response();
}
Hope it helps.
I am trying to make my Symfony2 website redirect logged in users to another page when trying to access the login page.
This is my security.yml:
security:
encoders:
Cocoa\LoginBundle\Entity\User:
algorithm: sha512
role_hierarchy:
ROLE_ADMIN: ROLE_USER
ROLE_SUPER_ADMIN: [ ROLE_USER, ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH ]
providers:
administrators:
entity: { class: CocoaLoginBundle:User, property: username }
firewalls:
admin_area:
pattern: ^/administration
form_login:
login_path: login
check_path: login_check
logout:
path: /administration/logout
invalidate_session: true
target: /
access_control:
- { path: ^/login, roles: IS_AUTHENTICATED_ANONYMOUSLY}
- { path: ^/administration, roles: ROLE_ADMIN }
And this is my controller:
class LoginController extends Controller {
public function loginAction() {
if (false === $this->get('security.context')->isGranted('IS_AUTHENTICATED_FULLY')) {
return $this->redirect($this->generateUrl('public_homepage'));
}
$request = $this->getRequest();
$session = $request->getSession();
if ($request->attributes->has(SecurityContext::AUTHENTICATION_ERROR)) {
$error = $request->attributes->get(SecurityContext::AUTHENTICATION_ERROR);
} else {
$error = $session->get(SecurityContext::AUTHENTICATION_ERROR);
$session->remove(SecurityContext::AUTHENTICATION_ERROR);
}
return $this->render('CocoaLoginBundle:Login:login.html.twig', array(
'last_username' => $session->get(SecurityContext::LAST_USERNAME),
'error' => $error));
}
public function loginCheckAction() {
}
}
If I access the login page as anonymous user I do see the login form. But after I log in and load the login page I get a 500 server error:
The security context contains no authentication token. One possible reason may be that there is no firewall configured for this URL.
A proposed fix I read in another topic is to put the login page behind a firewall. I did that but still error 500.
What am I doing wrong?
Thanks!
It's probably because you have only IS_AUTHENTICATED_ANONYMOUSLY role for path ^/login set in security.yml. So then there is no authentication token allowed to be passed to LoginController.
You should try either to add ROLE_ADMIN also for ^/login path in the access_control, or include ^/login under ^/administration so it will become ^/administration/login.
And as condition in LoginController you should try to use
if($securityContext->isGranted('IS_AUTHENTICATED_REMEMBERED')) {
return $this->redirect($this->generateUrl('public_homepage'));
}
I have this website with a login form and after I successfully logged in, I am redirected to the index. But when I click the back button, it lets me still view the login form which is not good. I want only the login form to be accessible by anonymous viewers only and not users who have logged in already. Is there a simple way to do this in symfony2? thanks
Here is my security.:
jms_security_extra:
secure_all_services: false
expressions: true
security:
encoders:
Mata\UserBundle\Entity\User:
algorithm: sha1
encode_as_base64: false
iterations: 1
role_hierarchy:
ROLE_ADMIN: ROLE_USER
ROLE_SUPER_ADMIN: [ROLE_USER, ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH]
providers:
user_db:
entity: { class: MataUserBundle:User, property: username }
firewalls:
secured_area:
pattern: ^/
anonymous: ~
form_login:
check_path: /login_check
login_path: /login
logout:
path: /logout
target: /
access_control:
- { path: ^/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/, roles: ROLE_USER }
This may not be the best or proper way to do it, but its been the only way I could figure it out.
In my loginAction method I do this (see the $secured variable). If the user session is authenticated then I redirect them to the home/index page. I don't know of a way to do it via the firewall config because I don't believe the login page would ever have a firewall attached to it.
/**
* #Route("/login", name="login")
* #Template()
*/
public function loginAction()
{
$request = $this->getRequest();
$session = $request->getSession();
// if the session is secured (user is logged in)
// then $secured will be an object with various user information.
$secured = unserialize($session->get('_security_secured'));
if ($secured) {
return $this->redirect($this->generateUrl('home'));
}
// get the login error if there is one
if ($request->attributes->has(SecurityContext::AUTHENTICATION_ERROR)) {
$error = $request->attributes->get(SecurityContext::AUTHENTICATION_ERROR);
} else {
$error = $session->get(SecurityContext::AUTHENTICATION_ERROR);
}
return array(
'last_username' => $session->get(SecurityContext::LAST_USERNAME),
'error' => $error,
'embed' => $request->isXmlHttpRequest()
);
}
With symfony 4 you can solve it with allow_if :
access_control:
- { path: /login, allow_if: "!is_authenticated()" }
here's the list of expressions available within allow_if string
http://symfony.com/doc/current/security/expressions.html#security-expression-variables