[keycloak-dev] token service

Pedro Igor Silva psilva at redhat.com
Wed Mar 15 07:24:12 EDT 2017


On Tue, Mar 14, 2017 at 7:32 PM, Bill Burke <bburke at redhat.com> wrote:

> 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
>

Why you need to send "provider" ? If you are already sending "
requested_token_type", the provider is implicit, right ?

Or if you don't send "requested_token_type" you can allow users to specify
the default token type to be issued.


> "requested-token-type" - OPTIONAL.  "id", "access", "offline", or
>

I think we have a great opportunity here to also support use cases where
you need to exchange a SAML assertion with an OAuth2/OIDC token. There is a
specific standard for that, but I think a STS would be perfect for this.

I remember some people asking for this and I think it will be a great win
for enterprise use cases and legacy systems.



> "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
>

Same comments I did to "external to Keycloak" exchange. In this particular
case, I think we can also provide some integration with identity brokering
functionality.

For instance, suppose I have a KC token and I want to obtain a Facebook AT.
I know we have ways to do that today, but I think that using a STS is much
more neat. In this case, we also don't need to send the provider, but we
can make this completely configurable from admin console. E.g.: associate
token types with a OOTB/custom identity providers. Maybe we can even define
a Token Exchange Identity Provider, which can be configured to integrate
with an external STS.


>
>
> 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.
>

Not sure you remember. But when we were discussing SAML on the earlier days
of Keycloak, I mentioned a API for Security Token Service that we had in PL
for years (I think Stefan did it). Plus a simplified version of this API in
PL JEE/IDM. One of the things that I liked most in PL is that the STS is
the backbone for the IdP. What I mean is, the IdP don't care about how a
token is issued/revoked/validated/renewed, but delegate this to STS. Being
responsible to basically implement the communication/protocol between the
involved parties.


>
>
>
>
>
>
>
>
>
>
>
>
>
> _______________________________________________
> keycloak-dev mailing list
> keycloak-dev at lists.jboss.org
> https://lists.jboss.org/mailman/listinfo/keycloak-dev
>


More information about the keycloak-dev mailing list