Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Accessing routes protected with role ROLE_ADMIN return a 500 Internal Error whereas in prod.log i have a DeniedAccessException #3111

Closed
Rebolon opened this issue Aug 7, 2019 · 9 comments

Comments

@Rebolon
Copy link

Rebolon commented Aug 7, 2019

Hi,

I opned an issue here api-platform/admin#193 but i think that it's also linked to core package so i prefer to add it here.

I have an API with different routes. Some of them require ROLE_USER, and others require ROLE_ADMIN.
When i login with a user that have ROLE_ADMIN, everything works well.
When i login with a user that have ROLE_USER and try to access to route protected with a higher ROLE, then i have a 500 error instead of a 403.

For example if i use api-platform/admin to login then i can see this in devtools:
those routes are ok:

  • /api
  • /docs.jsonld
  • /Entrypoint
  • /all-routes-that-only-requires-ROLE_USER

All others routes just fail with a 500 Access Denied in dev or prod mode

Here are some informations about an Entity with ROLE_ADMIN:

/**
 * @ApiResource(
 *     iri="http://schema.org/Person",
 *     accessControl="is_granted('ROLE_ADMIN')",
 *     attributes={
 *          "access_control"="is_granted('ROLE_ADMIN')",
 *          "status_code"=403,
 *          "pagination_client_enabled"=true,
 *     })
... 

Here is the security part:

security:
    encoders:
        App\Entity\User:
            algorithm: sodium

    # https://symfony.com/doc/current/security.html#where-do-users-come-from-user-providers
    providers:
        # used to reload user from session & other features (e.g. switch_user)
        app_user_provider:
            entity:
                class: App\Entity\User
                property: email
    firewalls:
        dev:
            pattern: ^/(_(profiler|wdt)|css|images|js)/
            security: false

        api_login:
            pattern: ^/api/login$
            anonymous: false
            stateless: true
            json_login:
                check_path: api_login
                username_path: "%login_username_path%"
                password_path: "%login_password_path%"

        api:
            pattern: ^/api
            anonymous: false
            stateless: true
            guard:
                authenticators:
                    - App\Security\Authenticator
        main:
            anonymous: ~

            # activate different ways to authenticate
            # https://symfony.com/doc/current/security.html#firewalls-authentication

            # https://symfony.com/doc/current/security/impersonating_user.html
            # switch_user: true

    # Easy way to control access for large sections of your site
    # Note: Only the *first* access control that matches will be used
    #access_control:
    #    - { path: ^/admin, roles: ROLE_ADMIN }
        - { path: ^/profile, roles: ROLE_USER }
        - { path: ^/api, roles: ROLE_USER }

Here is the symfony log:

[2019-08-07 16:37:14] security.DEBUG: Access denied, the user is neither anonymous, nor remember-me. {"exception":"[object] (Symfony\\Component\\Security\\Core\\Exception\\AccessDeniedException(code: 403): Access Denied. at /pathToProject/vendor/api-platform/core/src/Security/EventListener/DenyAccessListener.php:76)"} []
[2019-08-07 16:37:14] request.ERROR: Uncaught PHP Exception Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException: "Access Denied." at /pathToProject/vendor/symfony/security-http/Firewall/ExceptionListener.php line 120 {"exception":"[object] (Symfony\\Component\\HttpKernel\\Exception\\AccessDeniedHttpException(code: 0): Access Denied. at /pathToProject/vendor/symfony/security-http/Firewall/ExceptionListener.php:120, Symfony\\Component\\Security\\Core\\Exception\\AccessDeniedException(code: 403): Access Denied. at /pathToProject/vendor/api-platform/core/src/Security/EventListener/DenyAccessListener.php:76)"} []

I have even tried to add this Exception into config/packages/api_platform.yaml: (which i expect to be managed natively)

api_platform:
  ...
  exception_to_status:
    ...
    Symfony\Component\Security\Core\Exception\AccessDeniedException: 403

You can test the app here:
https://petkennel.myalerts.org/admin
user admin: admin@localhost / pwd
user standard: userOne@localhost / pwd

Or you can also use POSTMAN:
POST uri: https://petkennel.myalerts.org/api/login
BODY : {"username":"admin@localhost","password":"pwd"}
Then you can call api routes with Basic HTTP authentication (no need of JWT on this project): just do a base_64 encode on email:the_token_you_receieved_on_login and add it to Header Authorization: Basic ...

Thanks for help

@Rebolon
Copy link
Author

Rebolon commented Aug 8, 2019

temporary fix:

api_platform:
  ...
  exception_to_status:
    ...
    Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException: 403

But to my mind it should be native to Symfony to catch this Exception and transform it to 403 instead keeping it to 500.
This is the same kind of problem than : symfony/symfony#28801 and that should be solved in symfony/symfony#28801

I opened this issue on Symfony: symfony/symfony#33044

@teohhanhui
Copy link
Contributor

teohhanhui commented Aug 8, 2019

Hmm... Do you have the symfony/debug component installed? Because FlattenException gets the HTTP status code from HttpExceptionInterface: https://github.com/symfony/symfony/blob/v4.3.3/src/Symfony/Component/Debug/Exception/FlattenException.php#L47-L50

I'm not fully sure, but I suspect FlattenException is also used in prod env (i.e. when debug is false). Might have something to do with why it's being moved to a separate component in Symfony 4.4.

@Rebolon
Copy link
Author

Rebolon commented Aug 9, 2019

to check i've just done:
composer install --no-dev -o
and after because i didn't see anything about debug i also did composer remove symfony/debug

It doesn't remove anything and i still can see the folder vendor/symfony/debug
But if it's not a component, i cannot remove it by this way.

With composer why symfony/debug i can see this:

symfony/http-kernel  v4.3.2  requires  symfony/debug (~3.4|~4.0)

So it seems impossible to remove

@teohhanhui
Copy link
Contributor

teohhanhui commented Aug 9, 2019

Oh, okay. So please ignore what I've said. Haha... I'm not sure what's going on.

@dunglas dunglas transferred this issue from api-platform/api-platform Sep 26, 2019
@MLDMoritz
Copy link
Contributor

Hey,

I noticed this in tests checking security on a resource.
Tests pass however.

 ==> EmailTest                  ✔  ✔  ✔  ✔  2019-10-05T00:41:54+00:00 [error] Uncaught PHP Exception Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException: "Access Denied." at /srv/api/vendor/symfony/security-http/Firewall/ExceptionListener.php line 130
✔  ✔  ✔  

I came up with exception_to_status but it just works in prod I think?

@felixgomez
Copy link

felixgomez commented Nov 22, 2019

I think the error is because the security exception goes through https://github.com/api-platform/core/blob/master/src/Action/ExceptionAction.php#L53 but it is a Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException (no Symfony\Component\ErrorHandler\Exception\FlattenException nor Symfony\Component\Debug\Exception\FlattenException) so the getClass() method doesn't exists.

$exceptionClass should be obtained by something similar to:

$exceptionClass = method_exists($exception, 'getClass') ? $exception->getClass() : get_class($exception);

@soyuka
Copy link
Member

soyuka commented Nov 25, 2019

This should be fixed by symfony/symfony#34411 discussed in #3246. Update ApiPlatform if you want symfony's error handler to work properly.

@stale
Copy link

stale bot commented Nov 5, 2022

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@stale stale bot added the wontfix label Nov 5, 2022
@stale
Copy link

stale bot commented Jan 4, 2023

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@stale stale bot added the stale label Jan 4, 2023
@stale stale bot closed this as completed Jan 11, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants