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

[WIP] Add documentation for authorization code grant #177

Open
wants to merge 4 commits into
base: v3.x
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,7 @@ security:

* [Basic setup](docs/basic-setup.md)
* [Controlling token scopes](docs/controlling-token-scopes.md)
* [Authorization code grant](docs/authorization-code-grant.md)
* [Password grant handling](docs/password-grant-handling.md)

## Development
Expand Down
123 changes: 123 additions & 0 deletions docs/authorization-code-grant.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
# Authorization code grant

Authorization code grant has two steps

1. Getting authorization code
2. Getting token from authorization code

## Requirements

To use authorization code grant `trikoder_oauth2.authorization_server.grant_types.authorization_code.enable` must be set to `true` (it is set to `true` by default).

### Example: config

```yaml
# /packages/trikoder_oauth2.yaml

trikoder_oauth2:
v-m-i marked this conversation as resolved.
Show resolved Hide resolved
authorization_server:
grant_types:
authorization_code:
enable: true
```

After authorization code grant is enabled, token and authorization endpoints must be set.
It can be done by including `Resources/config/routes.xml` which will provide `/authorize` or `/token` endpoints or manually by setting

1. Controller `Trikoder\Bundle\OAuth2Bundle\Controller\AuthorizationController::indexAction` with `GET` method for authorization endpoint
2. Controller `Trikoder\Bundle\OAuth2Bundle\Controller\TokenController::indexAction` with `POST` method for token endpoint

### Example: custom setup

```yaml
# /routes/trikoder_oauth2.yaml

oauth2_authorization_code:
v-m-i marked this conversation as resolved.
Show resolved Hide resolved
controller: Trikoder\Bundle\OAuth2Bundle\Controller\AuthorizationController::indexAction
path: /oauth2-authorization-code

oauth2_token:
controller: Trikoder\Bundle\OAuth2Bundle\Controller\TokenController::indexAction
path: /api/token
```

After assigning routes, listener for `trikoder.oauth2.authorization_request_resolve` must be configured.

`\Trikoder\Bundle\OAuth2Bundle\Event\AuthorizationRequestResolveEvent` (whose name is `trikoder.oauth2.authorization_request_resolve`) consist of three important methods which have to be used

1. `setUser(?UserInterface $user)` and `resolveAuthorization(bool $authorizationResolution)` when user is already logged in when accessing authorization endpoint
2. `setResponse(ResponseInterface $response)` when user needs to log in before authorization server can issue authorization code

`\Trikoder\Bundle\OAuth2Bundle\EventListener\AuthorizationRequestUserResolvingListener` with priority value `1024` calls `setUser(?UserInterface $user)` if user is logged in, so make sure your listener has lower priority than it.

### Example: services.yml and php class

```yaml
BestNamespace\OAuthLogin\Listener\AuthorizationCodeListener:
tags:
- { name: kernel.event_listener, event: 'trikoder.oauth2.authorization_request_resolve', method: onAuthorizationRequestResolve }
```

```php
<?php

declare(strict_types=1);

namespace BestNamespace\OAuthLogin\Listener;

use Nyholm\Psr7\Response;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Trikoder\Bundle\OAuth2Bundle\Event\AuthorizationRequestResolveEvent;

final class AuthorizationCodeListener
{
private $urlGenerator;
private $requestStack;

public function __construct(
UrlGeneratorInterface $urlGenerator,
RequestStack $requestStack
) {
$this->urlGenerator = $urlGenerator;
$this->requestStack = $requestStack;
}

public function onAuthorizationRequestResolve(AuthorizationRequestResolveEvent $event): void
{
if (null === $event->getUser()) {
$event->setResponse(new Response(302, [
'Location' => $this->urlGenerator->generate('login', [
'returnUrl' => $this->requestStack->getMasterRequest()->getUri(),
]),
]));

return;
}

$event->resolveAuthorization(AuthorizationRequestResolveEvent::AUTHORIZATION_APPROVED);
}
}
```

After listener is configured new client can be registered.

### Example: cli

```
bin/console trikoder:oauth2:create-client best_client not_so_secret --redirect-uri "https://www.bestclient.com/" --grant-type "authorization_code" --scope "user.view"
```

This example assumes scope `user.view` is already registered scope inside `trikoder_oauth2` configuration

### Example: config

```yaml
# /packages/trikoder_oauth2.yaml

trikoder_oauth2:
v-m-i marked this conversation as resolved.
Show resolved Hide resolved
scopes:
- 'user.view'
```

After client is registered he can communicate with your server using authorization code grant.