Buy

Authorization with Access Control

Before we keep going with authentication and make it possible to login, let’s try out our first piece of authorization and start denying access!

Head back to security.yml. The easiest way to deny access is via the access_control section. Let’s use its regular expression coolness to protect any URLs that start with “/new” or “/create”.

Roles are given to a user when they login and if you’re not logged in, you don’t have any. Here, we’re saying that you at least need ROLE_USER to access these URLs:

# app/config/security.yml
security:
    # ...
    access_control:
        - { path: ^/new, roles: ROLE_USER }
        - { path: ^/create, roles: ROLE_USER }

Try it out! When we try to add an event, we’re redirected to /my-login-url. Hey! I know that URL! That’s what we put for the login_path config key.

So here’s the magic that just happened behind the scenes:

  1. We tried to go to /new. Since our anonymous user doesn’t have any roles, the access controls kicked us out;
  2. The firewall saves the day. Instead of giving us an access denied screen, it decides to give us a chance to login. The form_login key in tells the firewall that we want to use a good old fashioned login form, and that the login form should live at /my-login-url.

It’s our job to actually create the login page. And since we haven’t yet, we see the big ugly 404 error.

More access_control options

The access_control has a few more tricks to it. Head over to the Security chapter of the book and find the section on access_control. I want you to read this, but the most important thing to know is that only one access_control entry is matched on a request. Symfony goes down the list, finds the first match, and uses only it to check authorization. I’ll show you an example during the last chapter.

There’s also other goodies, like different access controls based on the user’s IP address or depending on which hostname is being accessed. You can even make it so that a user is redirected to https.

Leave a comment!

  • 2016-04-21 rchdevel

    Hello Ryan,

    thank you so much for your answer! yeap, finally I solved like this (using a kernel.request) and works like a charm...

    many thanks once again,
    Richard

  • 2016-04-19 weaverryan

    Hi Richard!

    Hmm. I would add a kernel.request listener for this. There, IF the user is logged in and they are not linked to the sub-domain, you can take some action - like redirecting them to the main domain or rendering a special response/template that says they don't have access (you could also simply throw an AccessDeniedException, which will render the standard 403 error template).

    Your setup might have some edge-cases I don't know about, which would make this messier than I'm describing - but this is definitely where I'd start. So, I think you and I were thinking fairly closely on this :).

    Cheers!

  • 2016-04-18 rchdevel

    Hello Ryan,

    how could I achieve an authorization based on sub-domain ?
    each sub-domain has it's own configuration and a user is linked to one or more sub-domains.
    so when a user is logged in (switch sub-domain), I should check if he has authorization on that sub-domain. What event should I use to make the decision?
    - I think kernel.request is not the good one, but neither security.interactive_login

    just can't figure out an elegant solution for this.
    any idea?

    many thanks in advance,
    Richard