Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings
Discussion options

I am trying to implement authentication for my API's by having a JSON based login. I am using the documentation provided here: https://symfony.com/doc/6.4/security.html#json-login. However the authentication mechanism fails to set the #[CurrentUser] and my Login Controller has NULL for the $user object.

My config/packages/security.yaml

security:
    password_hashers:
        Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface: 'auto'
    providers:
        app_user_provider:
            entity:
                class: App\Entity\User
                property: uuid
    firewalls:
        dev:
            pattern: ^/(_(profiler|wdt)|css|images|js)/
            security: false
        main:
            pattern: ^/api/
            lazy: true
            provider: app_user_provider
            json_login:
               check_path: app_user_login
               username_path: username
               password_path: password
            login_throttling: null
            logout:
               path: /logout

The User provider is an entity class and the attribute is "uuid". The entity has been generated using the MAKER bundle.

My Login Controller class is as follows

namespace App\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\Routing\Attribute\Route;
use Psr\Log\LoggerInterface;
use App\Entity\User;
use Symfony\Component\Security\Http\Attribute\CurrentUser;


final class AppUserLoginController extends AbstractController
{
    #[Route('/user/login', name: 'app_user_login', methods: ['POST'])]
    public function index(#[CurrentUser] ?User $user, LoggerInterface $logger): Response
    {

      if (null === $user) {
        $output = array(
            'Status' => 'ERROR',
            'Message' => 'Missing Credentials',
        );
        $logger->error(implode($output));
        $response = new JsonResponse($output, 401);
      } else {

        $token = rtrim(strtr(base64_encode(random_bytes(32)), '+/', '-_'), '=');

        $output = array(
            'Status' => 'SUCCESS',
            'Message' => 'Welcome' . $user->getUserIdentifier(),
            'user' => $user->getUserIdentifier(),  //making it easy for the UI to extract the user info
            'token' => $token,
        );
        $logger->error(implode($output));  //USed only during dev to help in debugging
        $response = new JsonResponse($output, 200);
      }

      return $response;
    }
}

When I access the route using Curl
curl -H 'Content-Type: application/json' -d '{"username":"SRIDHARPANDU", "password":"my-password"}' -X 'POST' 'http:/localhost:8000/user/login'
I get
{"Status":"ERROR","Message":"Missing Credentials"}

I var_dump the $user object and its set to NULL. According to the documentation the Security bundle is expected to pick up the username and passwword from the JSON payload based on the following entries in the security.yaml

               username_path: username
               password_path: password

It is then supposed to find a matching user in the user entity by querying the uuid property based on the following entry in the security.yaml

        app_user_provider:
            entity:
                class: App\Entity\User
                property: uuid

Followed by passing the $userto the controller specified in the security.yaml

            json_login:
               check_path: app_user_login

Im my case the $user object is set to NULL. Wondering if I have misconfigured anything.

You must be logged in to vote

Your main firewall pattern is ^/api/ so it won’t match /user/login.

Replies: 1 comment · 3 replies

Comment options

Your main firewall pattern is ^/api/ so it won’t match /user/login.

You must be logged in to vote
3 replies
@sridharpandu
Comment options

Thanks. I got it working by changing the regex pattern from ^/api/ to ^/.

I am still trying to get my mind around the firewall concepts. I thought that the firewall restriction and hence the authorization is forced only when the URL matches the route specified in the firewall. In my case I wanted only those that had "api" in the route to require authorization and other routes to be accessible without authorization, especially the login and password change controllers.

@MatTheCat
Comment options

Firewalls just allow a user to be authenticated by the configured authenticators; it doesn’t “force” anything.

If you want to configure authorization you can configure access controls: https://symfony.com/doc/current/security.html#access-control-authorization

@sridharpandu
Comment options

Noted. Thank you.

Answer selected by sridharpandu
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Category
🙏
Q&A
Labels
None yet
2 participants
Morty Proxy This is a proxified and sanitized view of the page, visit original site.