Wednesday, February 9, 2022

[FIXED] Is there a way to get allowed roles for a given URL?

Issue

I have some rules in security.yml that basically tell symfony which roles should be alowed to access some route/url. Is there a way to determine in the code for a given request which roles are allowed? I am intending to use this in an event listener.


Solution

You can use AccessMap from use Symfony\Component\Security\Http\AccessMapInterface;

AccessMap contain the mapping of your access_control configuration.

You can auto wire the service easily in your listener:

private AccessMapInterface $accessMap;
public function __construct(AccessMapInterface $accessMap)
{
    $this->accessMap = $accessMap;
}

Don't forget to register the service :

#services.yaml
services:

    #...

    Symfony\Component\Security\Http\AccessMapInterface: '@security.access_map'

Then you can use AccessMap to match your request using the method $this->accessMap->getPatterns($request) and access each configuration.

Example from one of my projet:

Symfony\Component\Security\Http\AccessMap {#8567 ▼
  -map: array:7 [▼
    0 => array:3 [▼
      0 => Symfony\Component\HttpFoundation\RequestMatcher {#8547 ▼
        -path: "^/login"
        -host: null
        -port: null
        -methods: []
        -ips: []
        -attributes: []
        -schemes: []
      }
      1 => array:1 [▼
        0 => "PUBLIC_ACCESS"
      ]
      2 => null
    ]
    1 => array:3 [▶]
    2 => array:3 [▶]
    3 => array:3 [▶]
    4 => array:3 [▶]
    5 => array:3 [▶]
    6 => array:3 [▶]
  ]
}

Let's try to see what role is required in my login page:

//$request is from my login page
dump($this->accessMap->getPatterns($request));

array:2 [▼
  0 => array:1 [▼
    0 => "PUBLIC_ACCESS"
  ]
  1 => null
]

So it should be easy to match your request in your listener, and use the result of getPatterns which contains the required roles for your request.

If you want to access a specific route configuration that is not your current request, you could do something like:

$this->accessMap->getPatterns(Request::create('/login', 'GET'));


Answered By - Dylan Kas

No comments:

Post a Comment

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