[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