Can I mark a single URI endpoint as anonymous? - symfony

I have read the docs and followed this similar question:
Allow anonymous access to specific URL in symfony firewall protected bundle
Using Symfony 4.1.4 I have tried the following:
access_control:
- { path: ^/rpi/service/application/quote/approve, roles: IS_AUTHENTICATED_ANONYMOUSLY}
- { path: ^/rpi, roles: ROLE_USER }
- { path: ^/erp, roles: ROLE_USER }
However when I access the first URI as anonymous I am prompted by the http_basic_ldap login screen. Any ideas?

You need
anonymous: true
in your firewall, as in the default configuration config/packages/security.yml:
security:
# https://symfony.com/doc/current/security.html#where-do-users-come-from-user-providers
providers:
in_memory: { memory: ~ }
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
main:
anonymous: true
Anonymous authentication means that the user is authenticated and has a token, but it is an anonymous token.
If you do not have anonymous: true, the AnonymousAuthenticationListener will never run for your firewall, and never create an anonymous token.

Related

Public Access with Symfony's AbstractAuthenticator

I'm exploring the new system for User Authentication using the new AbstractAuthenticator class in my symfony 5 project.
My symfony app will contain a mix of routes, some will only be accessible to authenticated users and some for unauthenticated users (public access)
My security.yaml file looks something like this:
security:
enable_authenticator_manager: true
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
main:
custom_authenticators:
- App\Security\JwtAuthenticator
access_control:
- { path: ^/auth/login, roles: PUBLIC_ACCESS }
- { path: ^/auth, roles: ROLE_USER }
I have also setup a route to auth/login
However, when I access the url https://myapp.test/auth/login I get the following message:
{"message":"Invalid credentials."}
If I remove the custom authenticator directive from security.yaml the url loads as expected.
Below is the authenticate function from the Authenticator class:
public function authenticate(Request $request): PassportInterface
{
return new SelfValidatingPassport(new UserBadge($request->get('email));
}
if I access /auth/login with a valid user matching the email address provided and with the ROLE_USER role, the page will load as expected. If I access it without providing an email address, the page will return the following (from the onAuthenticationFailure method):
{"message":"Invalid credentials."}
If I understand correctly, as stated in Symfony docs, the PUBLIC_ACCESS should skip authenticating the user and load the /auth/login route, while everything else under /auth/ should be protected. But I cannot get the PUBLIC_ACCESS directive to work.
I resolved it by changing the location of custom_authenticators like that:
security:
enable_authenticator_manager: true
firewalls:
main:
json_login: # that is my login for rest api
provider: user_provider
check_path: api_login
api:
pattern: ^/api
custom_authenticators: # here is the location for my custom authenticator
- App\Security\Authenticator
stateless: true
access_control:
- { path: ^/login, roles: PUBLIC_ACCESS }
I hope it helps!

Symfony: Can I use both JWT + oAuth to authenticate different users?

Before explain why what I need your help, just keep in mind that I am totally new on Symfony 3.4, so please be lenient with me.
What I try to create is a RESTful API.
For the admin section, I'd like my users to log in every day in order to access the application dashboard. I already do that, by using the LexikJWTAuthenticationBundle with a token that expires every 24 hours.
Then, my API will have several client applications that should access my data using an access token, but not using JWT. Those client applications will be mobile apps ( implemented on React Native ) and desktop apps ( implemented on Electron).
The way I thought I should authorize those applications to access my API is by providing them with an Authentication token using the oAuth protocol.
So, the basic question is, if I could config both authorization methods ( JWT + oAuth ) at the same time for the same resources.
So, for example, let's say I have the following endpoint: /api/v1/repository/chocolates.
With the jms_serializer I am able to choose what data I want to display on each group, so for a user has the ROLE_ADMIN I can display all the product information, while for the user has the ROLE_SOME_GRANT will only be possible to see the title and the description.
So is it possible to access the /api/v1/repository/chocolates either by using the JWT token my admins have or by using the oAuth token my client apps will have?
For the moment my app/config/security.yml has the following setup:
# To get started with security, check out the documentation:
# https://symfony.com/doc/current/security.html
security:
encoders:
FOS\UserBundle\Model\UserInterface: bcrypt
role_hierarchy:
ROLE_ADMIN: ROLE_USER
ROLE_NUTRITIONIST: ROLE_USER
ROLE_SUPER_ADMIN: ROLE_ADMIN
# https://symfony.com/doc/current/security.html#b-configuring-how-users-are-loaded
providers:
fos_userbundle:
id: fos_user.user_provider.username_email
firewalls:
# disables authentication for assets and the profiler, adapt it according to your needs
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
oauth_token:
pattern: ^/oauth/v2/token
security: false
oauth_authorize:
pattern: ^/oauth/v2/auth
security: false
api_user_management:
pattern: ^/api/v1/user/(login|request\/reset|password\/reset)
anonymous: true
stateless: true
api_user_management_safe:
pattern: ^/api/v1/user/(login|request\/reset|password\/reset)
anonymous: true
stateless: true
api_user_login:
pattern: ^/api/v1/login
stateless: true
anonymous: true
form_login:
check_path: /api/v1/login
require_previous_session: false
username_parameter: username
password_parameter: password
success_handler: lexik_jwt_authentication.handler.authentication_success
failure_handler: lexik_jwt_authentication.handler.authentication_failure
logout: true
#############################################
## HERE IF I CHANGE THE fos_oauth to false
## I CAN ACCESS MY ENDPOINT : /api/v1/register/new/user
## WHILE IF THAT IS TRUE I GET THE ERROR MESSAGE:
##
## {
## "error": "invalid_grant",
## "error_description": "The access token provided is invalid."
## }
#############################################
api_access:
pattern: ^/api/v1
stateless: true
#lexik_jwt: ~
guard:
authenticators:
- lexik_jwt_authentication.jwt_token_authenticator
fos_oauth: true
access_control:
- { path: ^/api/v1/user/request/reset, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/api/v1/user/password/reset, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/api/v1/user/update, role: IS_AUTHENTICATED_FULLY }
- { path: ^/api/v1/user/((?!request)|(?!password)|(?!update)), role: IS_AUTHENTICATED_FULLY }
- { path: ^/api/v1/register/new/user, role: IS_AUTHENTICATED_FULLY }
- { path: ^/api/v1/, role: IS_AUTHENTICATED_FULLY }
So, based on that security setup do you think there's a way to have multiple authorization services in my application?

Symfony - Security / routing setup to enable password protected user pages

I'm pretty new to Symfony although I've managed to set up a working site, with role based authentication and firewalls I'm really struggling working out how to build a system that allows users to login and have access to a page that only they and admin has access to.
What I really want is a dynamic security role which enables the user in the current session access to their own private page and blocks everyone else...
Here's my actual config:
security:
encoders: #define the encoders used to encode passwords
Symfony\Component\Security\Core\User\User: plaintext
IntuitByDesign\UserBundle\Entity\User: bcrypt
role_hierarchy:
ROLE_ADMIN: [ROLE_USER]
providers:
chain_provider:
chain:
providers: [in_memory, user_db]
in_memory:
memory:
users:
admin: { password: adminpass, roles: ROLE_ADMIN }
user_db:
entity: {class: IntuitByDesignUserBundle:User, property: username }
firewalls:
main:
logout: true
pattern: /.*
form_login:
login_path: login
check_path: login
default_target_path: /user
logout:
path: /logout
target: /
security: true
anonymous: true
access_control:
- { path: /login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: /logout, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: /user, roles: ROLE_ADMIN }
- { path: /user-page/, roles: ROLE_USER}
- { path: /.*, roles: IS_AUTHENTICATED_ANONYMOUSLY }
Any hints on how to do this?
Update: After login I would like to redirect page that only the specific logged in user can see.
I thought a way that this might be achieved could be with matching the session username with the user path?
You could check in the redirected action, if the user is logged in. If yes, load the data according to the user. e.g. you load the needed data by his user id.
So every user sees the data which is related with himself.
You can find more information about user authentication handling in this question: How to check if an user is logged in Symfony2 inside a controller?
look FosUserBundle
you can create a system of user easily

Best way to handle single user authentication?

I'm working on a small app with Symfony 2.5, and I'd like to know what is the best way to handle security, but just for only one user. I could do this with an .htaccess but maybe their exists some light and quickly installable sf2 bundle which could do the job. I don't want role stuff, or profile, just a way to authenticate myself.
Symfony2 let's you easily use http authentication. Together with the in_memory provider, you have a perfect solution for your use case.
From the docs:
security:
firewalls:
secured_area:
pattern: ^/
anonymous: ~
http_basic:
realm: "Secured Demo Area"
access_control:
- { path: ^/admin/, roles: ROLE_ADMIN }
# Include the following line to also secure the /admin path itself
# - { path: ^/admin$, roles: ROLE_ADMIN }
providers:
in_memory:
memory:
users:
ryan: { password: ryanpass, roles: 'ROLE_USER' }
admin: { password: kitten, roles: 'ROLE_ADMIN' }
encoders:
Symfony\Component\Security\Core\User\User: plaintext

Symfony2 logout issue

I am testing Security environnement within Symfony2 and hav problem with log out process
Here is my security.yml file
security:
firewalls:
secured_area:
pattern: ^/
anonymous: ~
switch_user: true
logout:
path: /logout
target: /
http_basic:
realm: "Secured Demo Area"
access_control:
- { path: ^/item, roles: [ 'ROLE_USER' ] }
providers:
in_memory:
users:
collector: { password: collector, roles: 'ROLE_USER' }
admin: { password: admin, roles: 'ROLE_ADMIN' }
encoders:
Symfony\Component\Security\Core\User\User: plaintext
Problem is that when I go to mysite.site/app_dev.php/logout it does redirect me to "target" but does not log out active user.
Does anyone know where am i wrong ?
Since you are using HTTP authentication, the reason might be that your browser caches your credentials and relogins automatically. Try using HTML form authentication and see if the problem persists.

Resources