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

Check user token on unprotected route? #301

Closed
Yanaro opened this issue Jan 16, 2017 · 6 comments
Closed

Check user token on unprotected route? #301

Yanaro opened this issue Jan 16, 2017 · 6 comments

Comments

@Yanaro
Copy link

Yanaro commented Jan 16, 2017

Is there anyway to check for user on unprotected route in case they provide the token? The idea is that I want to get user login status everywhere on the site without getting JWT expired / invalid if the requested route is not protected.

@chalasr
Copy link
Collaborator

chalasr commented Jan 16, 2017

Hello,

There are different ways to achieve this, the simplest being to configure the jwt listener (guard authenticator) on the unprotected firewall, beside the anonymous listener, e.g:

security:
    # ...
    firewalls:
        secure:
            pattern: ^/api
            stateless: true
            guard:
                authenticators:
                    - lexik_jwt_authentication.jwt_token_authenticator

        unsecure:
            pattern: ^/unsecure
            anonymous: true
            stateless: true
            guard:
                authenticators:
                    - lexik_jwt_authentication.jwt_token_authenticator
            # You may have the form login on this one
            #form_login:
            #    check_path: /login
            #    require_previous_session: false
            #    success_handler: lexik_jwt_authentication.handler.authentication_success
            #    failure_handler: lexik_jwt_authentication.handler.authentication_failure

    access_control:
        - { path: ^/unsecure, roles: [IS_AUTHENTICATED_ANONYMOUSLY, IS_AUTHENTICATED_FULLY] }
        - { path: ^/api, roles: IS_AUTHENTICATED_FULLY }

If a valid token is passed, you'll be able to retrieve the user from the controller of your unprotected route through $this->getUser(), if no token was passed, it will be null.
One thing to be aware of: If someone sends an invalid token to your unprotected route, he will get a 401 failure response as for the secured firewall (exceptions are thrown even if you allows anonymous, invalid credentials should never be passed).

Hope this helps you.

@Yanaro
Copy link
Author

Yanaro commented Jan 16, 2017

I actually tried that solution but getting 401 is pretty undesirable since what I want is either null user / anon or user with correct credential to render the page.

@chalasr
Copy link
Collaborator

chalasr commented Jan 16, 2017

You should have a look at #298, we give a trick to change this behavior. It will be documented soon

@Yanaro
Copy link
Author

Yanaro commented Jan 17, 2017

It works but it's kind of hacky IMO although i have only skimped through the spec so i'm unsure, or maybe it's how symfony normally works? I don't have much experience in symfony anyhow. Thanks for answering me.

@chalasr
Copy link
Collaborator

chalasr commented Jan 17, 2017

Yeah, the authentication fails at the first exception thrown no matter if the current firewall allows anonymous requests or not, there's no built-in way to bypass that.
You're welcome.

@chalasr chalasr closed this as completed Jan 17, 2017
@oliver-schulz
Copy link

I think i found a solution to handle a request on an unprotected route when the client sends an expired token.

  1. Create your own JwtTokenAuthenticator and decorate the existing JwtTokenAuthenticator
  2. Inject @security.access_map as argument
  3. Check if the request has a role "IS_AUTHENTICATED_ANONYMOUSLY"
  4. Abort JwtTokenAuthenticator process if needed

You can also extend this example by checking if the token is valid and only abort the authenticator when the token is invalid.

The benefit from this solution is not to separate your api endpoints by secure and public access.

The solution in #298 does not work to handle this problem. The code example also does not work in SF4.

public function supports(Request $request)
{
    $supports = $this->decorated->supports($request);
    list($accessMap) = $this->accessMap->getPatterns($request);
    if (is_array($accessMap) && in_array('IS_AUTHENTICATED_ANONYMOUSLY', $accessMap, true)) {
        $supports = false;
    }

    return $supports;
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants