+1. That is the most recent version of token exchange. Sorry Bill, just got
those from my bookmarks.
On Wed, Mar 15, 2017 at 4:30 AM, Schuster Sebastian (INST/ESY1) <
Sebastian.Schuster(a)bosch-si.com> wrote:
Have you seen the current version of [2] at
https://tools.ietf.org/html/
draft-ietf-oauth-token-exchange-07 ? This one looks very different and
probably better...
Regards,
Sebastian
-----Ursprüngliche Nachricht-----
Von: keycloak-dev-bounces(a)lists.jboss.org [mailto:keycloak-dev-bounces@
lists.jboss.org] Im Auftrag von Bill Burke
Gesendet: Dienstag, 14. März 2017 23:33
An: keycloak-dev <keycloak-dev(a)lists.jboss.org>
Betreff: [keycloak-dev] token service
There seems to be momentum building around token services, particular
features around:
* Token downgrades. Reducing the scope of an access token when delegating
to a separate less trusted service. For example, you have a token with
admin priveleges and you want to remove those privleges before re-using the
token against another service.
* Token exchanges. Ability to convert a foreign token to and from a
Keycloak one. For example, if you want to trust tokens issued by some
proprietary IBM IDM.
* Trusting tokens from other Keycloak domains. (Although I think this can
fall under token exchanges).
* Token revalidation (I think we have this).
There are some specs around this that Pedro pointed me to:
[
1]https://tools.ietf.org/html/draft-richer-oauth-chain-00
[
2]https://tools.ietf.org/html/draft-campbell-oauth-sts-01
<
https://tools.ietf.org/html/draft-campbell-oauth-sts-01>
I don't think they are either missing things we need or too complex for
our needs.
* Token downgrades, or token redelgation/chaining
I don't want to require apps to know the exact scope they have to
downgrade to if they want to reduce the scope when interacting with another
service. Let's provide an additional extension to [1] and supply a
"client" parameter in which the clientId of the redelegation you want to
perform is used. The token returned would be a union of the access token's
scope and the configured scope of the target client.
* Token exchanges
For [2] Keycloak just doesn't have all the concepts that are spoken about
here. I also don't think the spec is good enough. Coverting tokens would
be handled by a Token Exchange SPI. A provider would be configured per
realm and implemented on top of the ComponentModel SPI.
Each of these provider instances would handle either converting from an
external token to a realm token and/or from a realm token to an external
token. There will also be a rest endpoint on the realm to convert from
external to Keycloak and a separate REST endpoint for converting from
Keycloak to an external token.
From externl to Keycloka:
This would be a form POST to /token/convert-from with these additional
form parameters
"token" - REQUIRED. string rep of the token "provider" - REQUIRED. id
of
transformer register in the realm for the token type "requested-token-type"
- OPTIONAL. "id", "access", "offline", or
"refresh". Default is "access".
"scope" - OPTIONAL. Same as oauth scope.
This operation is analogous to the code to token flow. Here we are
creating a token tailored to the authenticated client. So all scope
configurations and mappers that the client has are applied. This means that
the client must be registered as an OIDC client. The SPI would look
something like this:
interface TokenExchangeFromProvider extends Provider {
Transformer parse(ClientModel client, Map<String, String>
formParameters);
interface Transformer {
UserModel getUser();
IDToken convert(IDToken idToken);
AccessToken convert(AccessToken accessToken);
}
}
The getUser() method returns a user that was authenticated from the
external token. The convert() methods just gives the provider the
flexibility to do further transformations on the returned token.
The runtime would do something like this:
ClientModel authenticatedClient = ...;
ComponentModel model = realm.getComponent(formParams.get("provider"));
TokenExchangeFromProvider provider =
session.getProvider(TokenExchangeFromProvider.class, model); Transformer
transformer = provider.parse(formParams); UserModel user =
transformer.getUser(); if
(formParam.get("requested-token-type").equals("access"))
{
AccessToken accessToken = generateAccessToken(authenticatedClient,
user, ...);
accessToken = transformer.convert(accessToken).
}
Something similar would be done for converting a Keycloak token to an
external token:
This would be a form POST to /token/convert-to with these additional form
parameters
"token" - REQUIRED. string rep of the token "provider" - REQUIRED. id
of
transformer register in the realm for the token type
interface TokenExchangeToProvider extends Provider {
ResponseBuilder parse(ClientModel client, Map<String, String>
formParameters);
}
Since we're crafting something for an external token system, we give the
provider complete autonomy in crafting the HTTP response to this operation.
_______________________________________________
keycloak-dev mailing list
keycloak-dev(a)lists.jboss.org
https://lists.jboss.org/mailman/listinfo/keycloak-dev
_______________________________________________
keycloak-dev mailing list
keycloak-dev(a)lists.jboss.org
https://lists.jboss.org/mailman/listinfo/keycloak-dev