[keycloak-dev] token service

Pedro Igor Silva psilva at redhat.com
Wed Mar 15 12:40:35 EDT 2017


On Wed, Mar 15, 2017 at 12:01 PM, Bill Burke <bburke at redhat.com> wrote:

>
>
> On 3/15/17 7:24 AM, Pedro Igor Silva wrote:
>
>
>   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.
>
>
> provider matches up with a Keycloak ComponentModel which matches up to a
> Keycloak ProviderFactory which knows how to do the translation.  Need some
> way of finding the service that can handle the translation of the external
> token.
>
> The requested_token_type in my proposal is the catagory of token you want,
> not its actual type
>

I understand that. Being the token I want, I can still provide ways to
configure their corresponding providers or a default (in case
requested_token_type is not provided) in admin console. It seems to be just
a 1:1 mapping between a token type and the corresponding provider. I think
clients of the token exchange api should not be aware of providers in KC,
but about the token types they use/need.


>
>
>
>> "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.
>
>
> I still think we should have a separation between external and internal
> exchanges.
>

That should be fine. But are you planning to support the exchange of SAML
assertions for OIDC/OAuth2 tokens ?


>
>
>
>
>
>> "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.
>
> An STS could be used to convert a Facebook AT into a Keycloak one, but not
> vice versa.  For Facebook, Google etc. a browser protocol is required in
> many cases to obtain the external token.  With Identity Brokering you are
> delegating authentication to another IDP.  Keycloak doesn't know how the
> user will be authenticated.  For instance, with Google a user may require
> authentication via SMS.  FYI, this is why the "Client Initiated Account
> Linking" protocol was just implemented.  There's also a lot of brokers that
> can only do logout via a browser protocol.
>
> I see what you mean though.  We already have the beginnings of an STS that
> is spread out in different classes and services.
>

Yeah. I understand Facebook or Google don't wllow token exchanges. But we
do provide an endpoint to obtain the token previously stored for a identity
provider. As you noticed, my point is that we could use the token exchange
for that and centralize such services in a single place.

And nothing stop us to support integration with external STSs by just
setting up things in admin console, just like we do for brokering. For
instance, suppose I have a business partner that supports OAuth2 Token
Exchanges and I need to access services protected by this partner's domain.


>
>
>
>
>>
>>
>> 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.
>
>
> We already have this separation.  Authentication is independent of
> protocol and we have a common data model that isn't protocol specific.  We
> also do not map from a brokered SAML assertion to a client's OIDC access
> token.  The brokered SAML assertion is mapped into a common data model
> which is then mapped to the OIDC access token.
>
> I see what you are saying though.  Token Exchange should be done in
> conjunction with refactoring and rewriting the Identity Brokering SPI as
> the two are related.  This also probably has an effect on Client
> configuration as I could see an STS-only based client that is just
> interacting with the STS.
>

>
> Bill
>
>


More information about the keycloak-dev mailing list