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

Permission request page #88

Open
rjwebdev opened this issue Jul 8, 2019 · 6 comments · May be fixed by #177
Open

Permission request page #88

rjwebdev opened this issue Jul 8, 2019 · 6 comments · May be fixed by #177
Labels
enhancement New feature or request

Comments

@rjwebdev
Copy link
Contributor

rjwebdev commented Jul 8, 2019

When authentication is using the grant type authorization_code, the user should be redirected after loging in succesfully to a page where permissions are asked to the user.

If the user allows the application using his login data, he should be redirected to the original application where he will be logged in to. If he doesn't give permissions, the user should be redirected to the application without being logged in.

For example: https://developer.okta.com/blog/2018/04/10/oauth-authorization-code-grant-type#get-the-users-permission

@j4-m
Copy link

j4-m commented Sep 23, 2019

I've also been looking into how this part of the Oauth2 spec can be supported by this bundle.

I don't know how the AuthorizationRequestResolveEvent can be used to achieve this as it's will involve a redirect. There's not a whole lot going on in the controller so we could just implement our own to achieve this and define the route authorize route in our app bundle.

@marvin-SL
Copy link

marvin-SL commented Oct 11, 2019

Im still a newbie with oauth2 and I was wondering about this permission page. When I send a GET request to /authorize I'm instantly redirected to the redirect_uri registered for the client.
But does this mean the user is by default giving permission even without the permission page ? I was supposed to get an access_token but i've got nothing.
Or does it means authorization_code flow doesnt work at all ?

@metasearch7
Copy link

metasearch7 commented Dec 26, 2019

Is this problem resolved?

after entering the login and password, the authorization request is not displayed, but a redirect is immediately performed

/?&error=access_denied&error_description=The+resource+owner+or+authorization+server+denied+the+request.&hint=The+user+denied+the+request&message=The+resource+owner+or+authorization+server+denied+the+request.

How to make an authorization request?

@HypeMC HypeMC added the enhancement New feature or request label Mar 18, 2020
@mehdibo
Copy link

mehdibo commented Apr 16, 2020

To anyone having the same problem as @metasearch7, this is what I did:

Create AuthRequestResolve:

<?php

namespace App\EventListener;

use Trikoder\Bundle\OAuth2Bundle\Event\AuthorizationRequestResolveEvent;

final class AuthRequestResolve
{

    public function onAuthRequestResolve(AuthorizationRequestResolveEvent $event): void
    {
        // TODO: if using 3rd party clients, make sure the user approves access
        $event->resolveAuthorization(TRUE);
    }
}

Add this in services.yaml:

App\EventListener\AuthRequestResolve:
  tags:
    - { name: kernel.event_listener, event: trikoder.oauth2.authorization_request_resolve, method: onAuthRequestResolve }

I think maybe in the onAuthRequestResolve is where you ask the user to review the app's permissions.

@spideyfusion spideyfusion linked a pull request Apr 20, 2020 that will close this issue
@dluces
Copy link

dluces commented Apr 24, 2020

Check out #177 for documentation on this. If you would like to have an intermediate page, I've done this in the event handler (though I'm not sure what the best practices are for this):

    public function onAuthorizationRequest(AuthorizationRequestResolveEvent $event): void
    {
        $request = $this->requestStack->getCurrentRequest();

        // only handle post requests for logged-in users:
        // get requests will be intercepted and shown the login form
        // other verbs we will handle as an authorization denied
        // and this implementation ensures a user is set at this point already
        if ($request->getMethod() !== 'POST' || null === $event->getUser()) {
            $event->resolveAuthorization(AuthorizationRequestResolveEvent::AUTHORIZATION_DENIED);
            return;
        }

        if (!$request->request->has('action')) {
            // 1. successful login, goes to grant page
            $content = $this->twig->render('security/grant.html.twig', [
                'scopes' => $event->getScopes(),
                'client' => $event->getClient(),
                'grant' => static::AUTHORIZATION_GRANT,
                // very simple way to ensure user gets to this point in the
                // flow when granting or denying is to pre-add their credentials
                'email' => $request->request->get('email'),
                'password' => $request->request->get('password'),
            ]);

            $response = new Response(200, [], $content);
            $event->setResponse($response);
        } else {
            // 2. grant operation, either grants or denies
            if ($request->request->get('action') == static::AUTHORIZATION_GRANT) {
                $event->resolveAuthorization(AuthorizationRequestResolveEvent::AUTHORIZATION_APPROVED);
            } else {
                $event->resolveAuthorization(AuthorizationRequestResolveEvent::AUTHORIZATION_DENIED);
            }
        }
    }

security/grant.html.twig:

<form method="post">
    {% if app.user %}
        <div class="mb-3">
            You are logged in as {{ app.user.username }}, <a href="{{ path('api_logout') }}">Logout</a>
        </div>
    {% endif %}

    <h1 class="h3 mb-3 font-weight-normal">Grant Permissions</h1>
    <input type="hidden" name="_csrf_token"
           value="{{ csrf_token('authenticate') }}"
    >
    <input type="hidden" name="email"
           value="{{ email }}"
    >
    <input type="hidden" name="password"
           value="{{ password }}"
    >

    <p>Grant the following permissions:</p>
    <ul>
        {% for scope in scopes %}
            <li>{{ scope }}: {{ scope }}</li>
        {% endfor %}
    </ul>

    <button class="btn btn-lg btn-primary" type="submit" name="action" value="{{ grant }}">
        Grant
    </button>

    <button class="btn btn-lg btn-primary" type="submit" name="action" value="Deny">
        Deny
    </button>
</form>

Any improvements to this approach would be appreciated.

@paul999
Copy link

paul999 commented May 9, 2020

Just as note for others trying the code above,
if ($request->getMethod() !== 'POST' || null === $event->getUser()) {
should be
if ($request->getMethod() !== 'POST' && null === $event->getUser()) {
Otherwise you will directly get a denied for your request.
Another change that is needed is that the default provided routes (Might only apply if you use symfony flex?) doesn't allow POST go /authorize, so instead of including the default route file, you will need to define the routes yourself.

With those changes it works perfectly, thanks!

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

Successfully merging a pull request may close this issue.

8 participants