简体   繁体   中英

Symfony 2.8 - How to configure a firewall for any URL?

Whenever I deliberately - trying to custom error pages - try to access an undefined route, the server responds by a 500 error. Logs say :

request.CRITICAL: Exception thrown when handling an exception (Symfony\\Component\\Security\\Core\\Exception\\AuthenticationCredentialsNotFoundException: The token storage contains no authentication token. One possible reason may be that there is no firewall configured for this URL .

This exception is thrown after the NotFoundException, hence the 500 error. Thus, I tried to figure out how to configure a firewall for any URL, and more particularly for all of those who are already handled by a firewall, so that the credentials can actually be found. I came up to this UserBundle/Resources/config/security.yml :

security:
encoders:
    FOS\UserBundle\Model\UserInterface: sha512

providers:
    fos_userbundle:
        id: fos_user.user_provider.username

firewalls:
    dev:
        pattern: ^/(_(profiler|wdt))/
        security: false
    public:
        pattern:                    ^/(contact/faq)$
        anonymous:                  true
    secure:
        pattern:                    ^/
        form_login:
            provider:               fos_userbundle
            csrf_token_generator:   security.csrf.token_manager
            login_path:             fos_user_security_login
            check_path:             fos_user_security_check
            use_forward:            false
            failure_path:           null
            default_target_path:    /
            remember_me:            true
        logout:
            path:                   fos_user_security_logout
            target:                 /
        anonymous:                  true
        remember_me:
            secret:                 %secret%
            name:                   whatev
            lifetime:               31536000
            path:                   /
            remember_me_parameter:  _remember_me
            secure:                 true
            always_remember_me:     true
    default:
        anonymous: true

Everything's imported in my main security file, which consists of :

imports:
- { resource: "@UserBundle/Resources/config/security.yml" }

security:
    role_hierarchy:
        ROLE_ADMIN:       ROLE_USER
        ROLE_SUPER_ADMIN: ROLE_ADMIN

access_control:
    - { path: ^/, roles: IS_AUTHENTICATED_ANONYMOUSLY } # my try to match all routes...
    - { path: ^/login$, role: IS_AUTHENTICATED_ANONYMOUSLY }
    - { path: ^/register, role: IS_AUTHENTICATED_ANONYMOUSLY }
    - { path: ^/resetting, role: IS_AUTHENTICATED_ANONYMOUSLY }
    - { path: ^/administration/, role: ROLE_ADMIN }
    - { path: ^/user$, role: IS_AUTHENTICATED_FULLY }

Here is my error.html.twig under app/Resources/TwigBundle/views/Exception :

<!DOCTYPE html>
<html>
    <head>
        <meta charset="{{ _charset }}" />
        <title>An Error Occurred: {{ status_text }}</title>
    </head>
    <body>
        <h1>Oops! An Error Occurred</h1>
        <h2>The server returned a "{{ status_code }} {{ status_text }}".</h2>

        <div>
            Something is broken. Please let us know what you were doing when this error occurred.
            We will fix it as soon as possible. Sorry for any inconvenience caused.
        </div>
    </body>
</html>

Any clue on how to proceed?

Thanks a lot.

As pointed out by Federico, the issue comes from an event listener that was trying to execute :

public function add(Request $request)
{
    if($this->securityContext->isGranted('IS_AUTHENTICATED_FULLY')) {
        /* do stuff considering the user is logged in.
        ** This is wrong ; we can end up here while having a logged out user.
        */

Of course, when thinking twice about it, it seems dumb. Simply fix the whole problem by ensuring that you can indeed call isGranted() on the security context. To check this, you have to verify that :

  1. the security context's token isn't null ;
  2. this token's user is an instance of your User entity (the user is actually logged in).

This changes the above method to :

public function add(Request $request)
{
    if($this->securityContext->getToken() === null)
        return false;

    if(!$this->securityContext->getToken()->getUser() instanceof User)
        return false;

    if($this->securityContext->isGranted('IS_AUTHENTICATED_FULLY')) {
        // do stuff considering the user is logged in.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM