-
Notifications
You must be signed in to change notification settings - Fork 35
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Signed-off-by: Julien Veyssier <[email protected]>
- Loading branch information
Showing
1 changed file
with
42 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
### Token exchange | ||
|
||
If your IdP supports token exchange, user_oidc can exchange the login token against another token. | ||
|
||
Keycloak supports token exchange if its "Preview" mode is enabled. See https://www.keycloak.org/securing-apps/token-exchange . | ||
|
||
:warning: Your IdP need to be configured accordingly. For example, Keycloak requires that token exchange is explicitely | ||
authorized for the target Oidc client. | ||
|
||
The type of token exchange that user_oidc can perform is "Internal token to internal token" | ||
(https://www.keycloak.org/securing-apps/token-exchange#_internal-token-to-internal-token-exchange). | ||
This means you can exchange a token delivered for an audience "A" for a token delivered for an audience "B". | ||
In other words, you can get a token of a different Oidc client than the one you configured in user_oidc. | ||
|
||
In short, you don't need the client ID and client secret of the target audience's client. | ||
Providing a token for the audience "A" (the login token) is enough to obtain a token for the audience "B". | ||
|
||
user_oidc is storing the login token in the user's Nextcloud session and takes care of refreshing it when needed. | ||
When another app wants to exchange the current login token for another one, | ||
it can dispatch the `OCA\UserOIDC\Event\ExchangedTokenRequestedEvent` event. | ||
The exchanged token is immediately stored in the event object itself. | ||
|
||
```php | ||
if (class_exists('OCA\UserOIDC\Event\ExchangedTokenRequestedEvent')) { | ||
$event = new OCA\UserOIDC\Event\ExchangedTokenRequestedEvent('my_target_audience'); | ||
try { | ||
$this->eventDispatcher->dispatchTyped($event); | ||
} catch (OCA\UserOIDC\Exception\TokenExchangeFailedException $e) { | ||
$this->logger->debug('Failed to exchange token: ' . $e->getMessage()); | ||
} | ||
$token = $event->getToken(); | ||
if ($token === null) { | ||
$this->logger->debug('ExchangedTokenRequestedEvent event has not been caught by user_oidc'); | ||
} else { | ||
$this->logger->debug('Obtained a token that expires in ' . $token->getExpiresInFromNow()); | ||
// use the token | ||
$accessToken = $token->getAccessToken(); | ||
} | ||
} else { | ||
$this->logger->debug('The user_oidc app is not installed/available'); | ||
} | ||
``` |