custom authentication provider with anonymous user - symfony

I have a question I didn't really find an answer for.
I have to maintain a Symfony application which uses a custom authentication and user provider. The provider works as aspected and the user can login correctly.
However, I need to make a few routes accessible for anonymous users. They should also be accessible when the user is not fully authenticated.
So I tried to adjust the access_control configuration in the security.yml to make these URLs accessible:
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
main:
pattern: ~
anonymous: ~
internal_api:
provider: fos_userbundle
check_path: /api/user/login
logout:
path: /api/user/logout
access_control:
- { path: ^/api/init, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/api/resources, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/, roles: ROLE_USER }
Unfortunately this does not work. The users still can't access these routes, as long as they are not fully authenticated.
So my question is: What is necessary to provide the role IS_AUTHENTICATED_ANONYMOUSLY via a custom authentication provider? Can it be done or do I just have to adjust my security.yml settings?
Best regards

Because the routes you want make accessible by anonymous are behind your main firewall and protected by your path: ^/ access_control, you have to create a specific firewall for them.
Add this in the firewalls of your security.yml :
api_resources:
pattern: ^/api/resources
anonymous: ~
api_init:
pattern: ^/api/init
anonymous: ~
And it should works.

Related

Symfony how to have multiple signed in users

I am developing and application in symfony, with a pulic access where users logs in with a login form and an admin section with another login form and another user provider.
I've created a LoginFormAuthenticator for each area, and two firewalls to select the correct authenticator in each area. This is my security.yaml:
security:
providers:
admin_provider:
entity:
class: App\Entity\AdminUser
property: email
web_provider:
entity:
class: App\Entity\User
property: email
firewalls:
admin:
pattern: '^/admin'
anonymous: true
provider: admin_provider
guard:
authenticators:
- App\Security\AdminLoginFormAuthenticator
logout:
path: /admin/logout
target: /
main:
anonymous: true
provider: web_provider
guard:
authenticators:
- App\Security\LoginFormAuthenticator
logout:
path: /logout
Now I am adding an /api to the project, and both users should be able to access, managing the access rights diferently if the user is a public user or is an admin user.
When developing a controller in the /api area, I am unable to get the user when logged via the admin.
The question is, How in /api I can get the AdminUser if it is logged in or the User (in this order) when accessing $this->getuser() or $this->denyAccessUnlessGranted() ?
I've tried to add the App\Security\AdminLoginFormAuthenticator in main firewall and add a chain_provider in main.provider. But it is not working.
Thank you.
The firewalls should share a "common context", for being able to access the same connected users. I think that wording comes from Symfony 2, where the SecurityContext was the service storing the user & authorization.
You need to modify slightly your configuration, and then $this->getUser() and $this->denyAccessUnlessGranted() will return/use the same User object for both firewalls.
firewalls:
admin:
pattern: '^/admin'
context: my_app_context
anonymous: true
# ...
main:
anonymous: true
context: my_app_context
# ...
No need for a common provider or a custom guard. Though it may be easier to have the same User class everywhere, or at least common role for clarity.

Sonata password without User entity

I've done some research but I can't find a way to set up a password (or login/password) for my admin dashboard without having an Entity User. I'm looking for something like a password in the parameters file or something like that. Is this possible ?
You need a User Entity but luckily this is standard available in the Symfony framework. You also need a way to authenticate a user. You could think about a php login-form or a HTTP basic authentication form. You can add users directly in security.yml under the providers section. And do not forget to restrict access to the /admin routes. You can easily follow this document
The most simple setup for app/config/security.yml is this:
security:
providers:
in_memory:
memory:
users:
admin:
password: kitten
roles: 'ROLE_ADMIN'
encoders:
Symfony\Component\Security\Core\User\User: plaintext
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
main:
anonymous: ~
http_basic: ~
access_control:
- { path: ^/admin, roles: ROLE_ADMIN }
Now you are able to go to the /admin route and then you have to login with user: admin and password: kitten

How to make some pages not require authentication in Symfony

Currently, any page I go to in my Symfony2 web app well direct the user to log in (if they aren't already logged in). This is okay - except there is one set of pages (my webservices, which will be under /webservice/*) which I don't want to force authentication from. Because it is a JSON webservice that will not be user facing, obviously I don't want it trying to redirect to a log in form.
This is my current security.yml firewall:
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
login:
pattern: ^/$
security: false
secured_area:
pattern: ^/
form_login:
check_path: my_app_authentication_login
login_path: my_app_authentication_homepage
username_parameter: form[username]
password_parameter: form[password]
default_target_path: my_app_task_homepage
always_use_default_target_path: true
logout:
path: my_app_authentication_logout
target: my_app_authentication_homepage
What do I have to do to make /webservice/* exempt from authentication?
You need to add to your security.yml file (this must be before your secured_area, order matters):
your_whatever_name:
pattern: ^/webservice/
security: false
Check doc for more info

Symfony 2 Custom User Provider & Authentication

I'm working on a project where a segment of the site is secured. The credentials for the users who auth are stored in QuickBase (an online database with a custom API) and the passwords are encrypted using a custom hash.
Can someone give me a high-level take on what classes I will need to build and implement to support authenticating these users from a web service and using my own password hash mechanism?
Here is my security.yml:
security:
firewalls:
secured_area:
pattern: ^/account
provider: quickbase_users
form_login:
login_path: /login
check_path: /login_check
access_control:
- { path: ^/admin, roles: ROLE_ADMIN }
providers:
quickbase_users:
id: quickbase_user_provider
encoders:
Symfony\Component\Security\Core\User\User: plaintext
Here are my routes:
login:
pattern: /login
defaults: { _controller: JMLWebsiteBundle:Security:login }
login_check:
pattern: /login_check
I'm currently getting this error after submitting a user/pass at /login:
Unable to find the controller for path "/login_check". Maybe you forgot to add the matching route in your routing configuration?
Create your User class that implements Symfony\Component\Security\Core\User\UserInterface.
Create a custom encoder service:
Create a service that implements Symfony\Component\Security\Core\Encoder\PasswordEncoderInterface
Register that service as encoder for your User class in security.yml:
security:
encoders:
MyCustomBundle\Entity\User: # Class/interface from point #1
id: my.encoder.service # Service id from point #2.1
Create a custom user provider:
Create a service that implements Symfony\Component\Security\Core\User\UserProviderInterface
Register that service as user provider in security.yml:
security:
[...]
providers:
my_custom_user_provider:
id: my.user_provider.service # Service id from point #3.1
Check out FOSUserBundle to see an example of implementation of custom user provider.

Why doesn't Symfony2 require me to login even after I've configured the security?

This is my security setup for my Symfony2 project:
security:
providers:
main:
users:
asa: { pasword: test, roles: ROLE_USER }
firewalls:
application:
pattern: /.*
http_basic: true
security: true
logout: true
Even though I've followed the documentation, setup a user, require authentication for the whole site, it still allows me to access it as an anonymous user. The logs say "Populated SecurityContext with an anonymous Token"
I'm using the latest version of the sandbox where '.config' was removed from 'security.config'
This wasn't working because I was missing
access_control:
- { path: /.*, role: ROLE_USER }
Looking at the logs and some of the vendor code, the firewalls section attempted to find my user, but without access_control it didn't have any need to force me from being an anonymous user.

Resources