Symfony2 version 2.0.23, login with users from database always return: 'The presented password is invalid' - security

I'm trying to set up 2 firewall with 2 different providers and encoders in my security.yml that looks like this:
security:
encoders:
Devsign\UserBundle\Entity\AgentUser:
algorithm: sha512
iterations: 5000
encode_as_base64: true
Devsign\UserBundle\Entity\PressUser:
algorithm: sha512
iterations: 5000
encode_as_base64: true
providers:
agent_secured_area:
entity: {class: Devsign\UserBundle\Entity\AgentUser } # using a custom repository to login with username or email, details in AgentUserRepository.php
press_secured_area:
entity: {class: Devsign\UserBundle\Entity\PressUser, property: username }
firewalls:
agent_secured_area:
pattern: /(it|en)/reserved/
provider: agent_secured_area
anonymous: ~
form_login:
check_path: /it/reserved/login-check
login_path: /reserved/login
logout:
path: /reserved/logout
target: /
press_secured_area:
pattern: /(it|en)/press/
provider: press_secured_area
anonymous: ~
form_login:
check_path: /it/press/login-check
login_path: /press/login
logout:
path: /press/logout
target: /
access_control:
agent_login:
path: /reserved/login
roles: IS_AUTHENTICATED_ANONYMOUSLY
agent_register:
path: /reserved/register
roles: IS_AUTHENTICATED_ANONYMOUSLY
agent_area:
path: /(it|en)/reserved/.*
roles: ROLE_AGENT
press_login:
path: /press/login
roles: IS_AUTHENTICATED_ANONYMOUSLY
press_register:
path: /press/register
roles: IS_AUTHENTICATED_ANONYMOUSLY
press_area:
path: /(it|en)/press/.*
roles: ROLE_PRESS
I get no exception but when I try to login against agent_secured_area i get always: 'The presented password is invalid'.
I created the first user password and salt using this code in a controller:
$factory = $this->get('security.encoder_factory');
$user = new \Devsign\UserBundle\Entity\AgentUser();
$encoder = $factory->getEncoder($user);
$salt = $user->getSalt();
$password = $encoder->encodePassword('grab', $salt);
die("pwd: $password - salt: $salt");
And then i fill the database field password and salt with the echoed values.
Can someone spot the error?
UPDATE 1
I made some test setting in the config_dev.yml:
web_profiler:
toolbar: true
intercept_redirects: true
verbose: true
1) I try to go to /it/reserved/info but it is access protected so I'm redirected correctly to /it/reserved/login
2) I try to login from /it/reserved/login posting the form to /it/reserved/login-check
3) Thanks to web_profile: intercepts_redirects: true I can see the debug toolbar in /it/reserved/login-check and I'm correctly authenticated with the correct Role: ROLE_AGENT. By the way looking in the doctrine section of the profiler I see two queries against my user table, the first one with parameter username NULL and a second one with the correct username.
4) Then I'm redirected to /it/reserved/info where for some reason I see a single query against my user table with parameter username NULL. Infact in /it/reserved/info I'm not authenticated anymore. So I'm redirected again to /it/reserved/login.
So I think the problem is that query with parameter username null, someone knows where it's coming from? Maybe from some misconfiguration on security.yml?

Related

Symfony access control forbids user with correct role

security.yml:
role_hierarchy:
admin: [test, simple]
providers:
database:
entity: { class: UserBundle:User, property: username }
firewalls:
dev:
pattern: ^/(_(profiler|wdt|error)|css|images|js)/
security: false
prod:
pattern: ^/
provider: database
anonymous: true
form_login:
login_path: public_login
check_path: public_login_check
default_target_path: dashboard
always_use_default_target_path: true
csrf_provider: form.csrf_provider
logout:
path: logout
target: public_login
access_control:
- { path: ^/(.+), roles: admin }
- { path: ^/$, roles: IS_AUTHENTICATED_ANONYMOUSLY }
When i login, I get 403 forbidden exception. Then i check profiler/security, and roles looks like that:
Roles [ROLE_USER, admin]
When i switch access control to:
- { path: ^/(.+), roles: ROLE_USER }
It works fine.
Why the hell my access control doesn't allow me to access pages with "admin" role, but does with "ROLE_USER" ?
My goal is to drop built-in roles (like ROLE_USER, ROLE_ADMIN etc), because I'm writing application for existing database, which contains already defined roles for users, so i want to use them.
I have confirmed that 'ROLE_' prefix is required - its because symfony by default use its own RoleVoter implementation.
To get rid of this prefix, custom RoleVoter is needed. To do that you need to create custom class implementing RoleVoterInterface, make it service and tag it with 'security.voter', to enforce security layer to use it instead of default one.
Read more about implementing own RoleVoters on this example.
You are not using the right syntax for roles in the Security configuration
you should change
- { path: ^/(.+), roles: admin }
To:
- { path: ^/(.+), roles: ROLE_ADMIN }

"Undefined class Security" in Symfony2

I have created a simple login system with Symfony2. I have followed the instruction given in --
http://symfony.com/doc/current/book/security.html#using-a-traditional-login-form
I have created everything told in the tutorial.
This is my error, I am getting -
Attempted to load class "Security" from namespace "Symfony\Component\Security\Core" in C:/XAMPP/xamppfiles/htdocs/symfony/src/Custom/TestBundle/Controller/SecurityController.php line 15. Do you need to "use" it from another namespace? Perhaps you need to add a use statement for one of the following: Sensio\Bundle\FrameworkExtraBundle\Configuration\Security.
I am using PHPStorm. Even my IDE is showing like,
My security.yml is look like --
security:
encoders:
Symfony\Component\Security\Core\User\User: plaintext
role_hierarchy:
ROLE_ADMIN: [ROLE_USER]
providers:
chain_provider:
chain:
providers: [in_memory]
in_memory:
memory:
users:
admin: {password: pass, roles: ROLE_ADMIN}
firewalls:
main:
pattern: /.*
form_login:
login_path: /login
check_path: /login_check
default_target_path: /
logout:
path: /logout
target: /
security: true
anonymous: true
access_control:
- { path: /login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: /.*, roles: IS_AUTHENTICATED_ANONYMOUSLY }
You need to check version of your Symfony2 application and version of documentation

Entity Provider: No encoder has been configured for account

I'm trying to setup a login system using the Doctrine Entity Provider but I always get this error:
No encoder has been configured for account "Prefix\MainBundle\Entity\Admin"
Here is my setup:
security.yml
security:
encoders:
Prefix\MainBundle\Entity\Admin:
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:
administrators:
entity: { class: PrefixMainBundle:Admin, property: username }
firewalls:
administrators:
pattern: ^/admin/
anonymous: ~
provider: administrators
form_login:
login_path: /admin/login
check_path: /admin/login_check
access_control:
- { path: ^/admin/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/admin, roles: ROLE_ADMIN }
I have the Entity created and implements the UserInterface but I can't make it work, it'd great if someone could shed some light on this.
Move the provider to be under the form login:
form_login:
login_path: /admin/login
check_path: /admin/login_check
provider: administrators
I am assuming you the error when trying to login using a form.
And while not directly related, you should replace your login paths with named routes.

app.user is not accessible from unsecured area

How is it possible to get app.user from unsecure area?
So I have secured area which starts from ^/user.
But I need to display logout form on area which is accessible for everyone and not secured. How is this possible? My security.yml:
security:
encoders:
Symfony\Component\Security\Core\User\User: plaintext
###:
algorithm: sha512
encode-as-base64: true
iterations: 10
###:
algorithm: sha512
encode-as-base64: true
iterations: 10
role_hierarchy:
providers:
admin:
name: admin
entity: { class: ###, property: login }
user:
name: user
entity: { class: ###, property: login }
firewalls:
admin:
pattern: ^/admin
form_login:
login_path: ###_login
check_path: ###_login_process
default_target_path: /admin/dashboard
anonymous: ~
logout:
path: /admin/logout
target: /admin/login
provider: admin
remember_me:
key: "###"
lifetime: 604800
path: /
domain: ~
user:
pattern: ^/user
form_login:
login_path: ###_login
check_path: ###_login_process
default_target_path: ###
anonymous: ~
logout:
path: /user/logout
target: /user/login
provider: user
remember_me:
key: "###"
lifetime: 604800
path: /
domain: ~
access_control:
- { path: ^/admin/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/admin/, roles: ROLE_ADMIN }
- { path: ^/user/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/user/, roles: ROLE_USER }
Well I changed a little bit my security.yml. So currently everything works ok.
user:
pattern: ^/
access_control:
- { path: ^/, roles: IS_AUTHENTICATED_ANONYMOUSLY }
...
UPDATE 1
It seems that line in access_controll is not required. Moreover by some reason(might be cache) anonymoous users were accessing /user areas
You can get app.user in some unsecured area because Symfony security relies on 2 different mechanisms: authentication and authorization.
Authentication is defined by firewalls. As soon as you get under a firewall, you get a token and eventually a app.user, even if it is anonymous.
Authorization is related to access_control rules. It is a second step, you can't put access control rules outside of a firewall. There you will deal with the ROLE requirement, in example if ROLE_ANONYMOUS is enoug, if you want ROLE_USER...
One more thing: to complexify a little further, a firewall can allow or disallow anonymous users. By default it is true, as it is required to have you login and login_check paths under yoru firewall though you cant' require there users to have a role other than ROLE_ANONYMOUS (if you do so, you will have an infinite loop).

Symfony2 Security.yml

I'm trying to take advantage of Symfony's authentication and authorization capabilities however I'm somewhat confused as to what my security.yml file should look like.
I'm looking to accomplish the following objectives:
1) The routes / and /join (are avilable to everyeone - no login required).
2) all other routes require a login/password.
3) the /adimin route should be futher restricted to admin users only.
4) all users should be authenticated against the database.
I have item 4 figured out (I think) - see below. I'm not sure what the administrators: word means though. Does that mean only administrators use the User class? Should that say users: or something else?
security:
encoders:
MySite\Bundle\Entity\User:
algorithm: sha1
encode_as_base64: false
iterations: 1
providers:
administrators: (??? what doest his mean ???)
entity: { class: MySiteBundle:User }
More Importantly --
For Items 1, 2, and 3 I'm not sure what to put. I have a bunch of entries under the firewalls: section and the access_control: sections however It just doesnt work or make sense. Can someone post what the security.yml should look like just by the goals I'm looking to accomplish in numbers 1 - 3?
Here is a configuration exemple from what I understood from your needs:
security:
encoders:
"MySite\Bundle\Entity\User": { algorithm: sha1, encode_as_base64: false, iterations: 1 }
providers:
database: { entity: "MySite\Bundle\Entity\User" }
firewalls:
dev:
pattern: ^/(_profiler|_wdt|css|js)
security: false
main:
pattern: ^/
provider: database
anonymous: true
# the rest of your firewall's config
access_control:
- { path: ^/(join)?$, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/, roles: IS_AUTHENTICATED_FULLY }
We configure the password encoder for the user entity and we define a provider for it.
Then we define a dev firewall to deactivate security for the debug/profiler/asset pathes and a main one that will be the real firewall for the application. This last firewall will use the previously defined user provider and allow anomymous users (important!).
Finally in the access control map, we first define a rule for the pathes allowed to anonymous users and then a generic rule that requires the user to be fully authenticated for the rest of the site.
For anyone else asking this or a similiar question, I've managed to get this working using the following settings in security.yml.
security:
encoders:
MySite\Bundle\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:
database:
entity: { class: MySiteBundle:User }
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
prod:
pattern: ^/
provider: database
anonymous: true
form_login:
check_path: /login_check
login_path: /login
default_target_path: /home
always_use_default_target_path: true
logout:
path: /logout
target: /
access_control:
- { path: ^/admin, roles: ROLE_ADMIN }
- { path: ^/build, roles: ROLE_USER }
- { path: ^/join, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/, roles: IS_AUTHENTICATED_ANONYMOUSLY }

Resources