PHPFixing
  • Privacy Policy
  • TOS
  • Ask Question
  • Contact Us
  • Home
  • PHP
  • Programming
  • SQL Injection
  • Web3.0

Sunday, January 16, 2022

[FIXED] symfony 5 custom authentication for API REST

 January 16, 2022     fosrestbundle, rest, symfony, symfony5     No comments   

Issue

I'm working on a project with Symfony 5. I created the User entity, created the authentication flow on security.yaml and all works well: if user wants to access to protected area, login page was shown and authentication process works! So good!

Now, I want to build an API REST with FOSRest Bundle. I've created a specific controller for expose some routes:

/**
 * @Rest\Route("/api")
 *
 */

class APICustomController extends AbstractController
{
    ...
    /**
    * @Rest\Get("/shoes")
    * @param Request $request
    * @Method({"GET"})
    *
    * @return JsonResponse
    */
    public function getShoes(Request $request){

        ....
        return JsonResponse::fromJsonString(array('msg' => 'OK'));

    }

}

Here my security.yaml

security:
    enable_authenticator_manager: true
    encoders:
        App\Entity\User:
            algorithm: auto

    role_hierarchy:
        ROLE_ADMIN: ROLE_USER
        ROLE_VIEWER: ROLE_USER

    providers:
        # used to reload user from session & other features (e.g. switch_user)
        app_user_provider:
            entity:
                class: App\Entity\User
                property: username
        api_user_provider:
            entity:
                class: App\Entity\User
                property: api_token
    firewalls:
        dev:
            pattern: ^/(_(profiler|wdt)|css|images|js)/
            security: false
        main:
            lazy: true
            provider: app_user_provider
            guard:
                authenticators:
                    - App\Security\DealmapLoginAuthenticator
            logout:
                path: app_logout

        api:
            stateless: true
            lazy: true
            guard:
                authenticators:
                    - App\Security\TokenAuthenticator
            pattern: ^/api/
            provider: api_user_provider

    access_control:
        - { path: ^/login$, role: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/api, role: IS_AUTHENTICATED_FULLY }

I followed the steps given here: https://symfony.com/doc/current/security/guard_authentication.html

The problem is the call below

curl -X GET \
  http://www.example.com/api/shoes \
  -H 'cache-control: no-cache' \
  -H 'content-type: application/json' \
  -H 'x-auth-token: test'

it is protected by the main firewall (so it returns me the login page), and not by api as expected. I expect to receive an error message in json format.

What's wrong??

Thanks in advance


Solution

OK, I found the solution!

I'm posting it here in case someone might need it in the future.

The configuration was all correct, but the reason why the path /api/shoes was managed by the main firewall was due to the order of execution of the rules.

The firewall main handles all the rules, while the api one handles only the ones with the ^/api pattern, so the most stringent rules should go first in the firewall definition in the security.yaml, as below:

security:
    enable_authenticator_manager: true
    encoders:
        App\Entity\User:
            algorithm: auto

    role_hierarchy:
        ROLE_ADMIN: ROLE_USER
        ROLE_VIEWER: ROLE_USER

    providers:
        # used to reload user from session & other features (e.g. switch_user)
        app_user_provider:
            entity:
                class: App\Entity\User
                property: username
        api_user_provider:
            entity:
                class: App\Entity\User
                property: api_token
    firewalls:
        dev:
            pattern: ^/(_(profiler|wdt)|css|images|js)/
            security: false
        api:
            stateless: true
            lazy: true
            guard:
                authenticators:
                    - App\Security\TokenAuthenticator
            pattern: ^/api/
            provider: api_user_provider
        main:
            lazy: true
            provider: app_user_provider
            guard:
                authenticators:
                    - App\Security\DealmapLoginAuthenticator
            logout:
                path: app_logout

    access_control:
        - { path: ^/login$, role: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/api, role: IS_AUTHENTICATED_FULLY }


Answered By - mardif
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg
Newer Post Older Post Home

0 Comments:

Post a Comment

Note: Only a member of this blog may post a comment.

Total Pageviews

Featured Post

Why Learn PHP Programming

Why Learn PHP Programming A widely-used open source scripting language PHP is one of the most popular programming languages in the world. It...

Subscribe To

Posts
Atom
Posts
Comments
Atom
Comments

Copyright © PHPFixing