[keycloak-dev] apps access to and refresh of facebook tokens

Marek Posolda mposolda at redhat.com
Fri Feb 27 07:17:57 EST 2015


One thing to consider: Does all identity brokers support refreshing of 
tokens? For example it seems that Facebook doesn't (not 100% sure) and 
instead they have long-lived access tokens. So when application wants to 
refresh expired Facebook access token, it would need to browser redirect 
to Keycloak with "k_idp_hint=facebook" and KC will need to redirect to 
Facebook and then back to app with refreshed token.

For minimum of HTTP requests needed, but good usability I would do it 
like this:

* Access token sent from KC to the application embeds all 3rd party 
access tokens accessible by configured claims. There is risk application 
doesn't need them all for particular request, but IMO it is better to 
have 1 HTTP request with bigger JSON accessToken response then another 
separate request from application to KC just to retrieve Facebook access 
token.

* Adapter has method on RefreshableKeycloakSecurityContext like this:

updateThirdpartyToken("facebook", 10, httpFacade)

which will update facebook access token just if it's going to expire in 
next 10 seconds. Otherwise no network calls needed. Adapter should know 
when is Facebook access token going to expire from the KC accessToken 
(It should have all needed info). If token is going to expire, 
HttpFacade may be needed to perform redirect to KC with idp_hint.

Maybe identity broker should allow to specify if provider supports 
refreshing tokens (in this case backend refresh from app to KC could 
happen), but otherwise it would really need to go through browser 
redirects IMO.

Marek

On 27.2.2015 07:08, Stian Thorgersen wrote:
> I don't see the need to include the facebook token into the Keycloak token. IMO the way an application would use it is (pseudo code not real code):
>
> function callInternalEndpoint() {
>    var internalToken = kc.getToken();
>    if (internalToken.isExpired()) {
>      internalToken = kc.updateToken()
>    }
>    invokeRestEndpointSecuredByKc(internalToken, someData);
>
> }
>
> function callExternalEndpoint() {
>    var facebookToken = kc.getToken("facebook");
>    if (facebookToken.isExpired()) {
>      facebookToken = kc.updateToken("facebook")
>    }
>    invokeFacebook(facebookToken, someData);
> }
>
> I just don't see the need to refresh all these tokens at the same time. In the first function the internal token is required, in the second the facebook token is required. If you have more linked identities to the same user it could get even worse. For example to call Facebook you'd end up refreshing Keycloak, Facebook, Google, Twitter, etc tokens. That's a lot of unnecessary calls.
>
> Also, it would be pretty complex to do. When does for example the internal token expire? I assume that would have to be the shortest amount of time for any of the included tokens to expire.
>
> I just think we're making something quite simple into something a lot more complex for no benefit.
>
>
> ----- Original Message -----
>> From: "Pedro Igor Silva" <psilva at redhat.com>
>> To: "Bill Burke" <bburke at redhat.com>
>> Cc: keycloak-dev at lists.jboss.org
>> Sent: Thursday, February 26, 2015 8:48:43 PM
>> Subject: Re: [keycloak-dev] apps access to and refresh of facebook tokens
>>
>> ----- Original Message -----
>>> From: "Bill Burke" <bburke at redhat.com>
>>> To: "Pedro Igor Silva" <psilva at redhat.com>
>>> Cc: keycloak-dev at lists.jboss.org
>>> Sent: Thursday, February 26, 2015 4:45:02 PM
>>> Subject: Re: [keycloak-dev] apps access to and refresh of facebook tokens
>>>
>>>
>>>
>>> On 2/26/2015 2:04 PM, Pedro Igor Silva wrote:
>>>> ----- Original Message -----
>>>>> From: "Bill Burke" <bburke at redhat.com>
>>>>> To: "Pedro Igor Silva" <psilva at redhat.com>
>>>>> Cc: keycloak-dev at lists.jboss.org
>>>>> Sent: Thursday, February 26, 2015 3:41:21 PM
>>>>> Subject: Re: [keycloak-dev] apps access to and refresh of facebook
>>>>> tokens
>>>>>
>>>>>
>>>>>
>>>>> On 2/26/2015 1:16 PM, Pedro Igor Silva wrote:
>>>>>> ----- Original Message -----
>>>>>>> From: "Bill Burke" <bburke at redhat.com>
>>>>>>> To: "Pedro Igor Silva" <psilva at redhat.com>
>>>>>>> Cc: keycloak-dev at lists.jboss.org
>>>>>>> Sent: Thursday, February 26, 2015 2:09:09 PM
>>>>>>> Subject: Re: [keycloak-dev] apps access to and refresh of facebook
>>>>>>> tokens
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> On 2/26/2015 11:09 AM, Pedro Igor Silva wrote:
>>>>>>>> ----- Original Message -----
>>>>>>>>> From: "Bill Burke" <bburke at redhat.com>
>>>>>>>>> To: keycloak-dev at lists.jboss.org
>>>>>>>>> Sent: Thursday, February 26, 2015 12:42:19 PM
>>>>>>>>> Subject: [keycloak-dev] apps access to and refresh of facebook
>>>>>>>>> tokens
>>>>>>>>>
>>>>>>>>> At least for openid connect, I think we hashed this through on our
>>>>>>>>> dev
>>>>>>>>> call today.
>>>>>>>>>
>>>>>>>>> * There will be a Protocol Claim Mapper that can add a facebook
>>>>>>>>> token
>>>>>>>>> and expiration claim to the application's access token.
>>>>>>>> I would create a specific claim set for that instead of individual
>>>>>>>> claims.
>>>>>>>> Something like:
>>>>>>>>
>>>>>>>> "k_act" : {
>>>>>>>>         "identity-provider": {
>>>>>>>>             "id" : "facebook",
>>>>>>>>             "access_token": "12312312",
>>>>>>>>             "expires": "12312321"
>>>>>>>>         }
>>>>>>>> }
>>>>>>>>
>>>>>>>> (k_act : keycloak authentication context)
>>>>>>>>
>>>>>>>> That way we can use this k_act for exchange information regarding the
>>>>>>>> authentication context when issuing access tokens or even id tokens.
>>>>>>>>
>>>>>>> Yeah, token mapping be able to generate any json you want.
>>>>>>>
>>>>>>>>> * the refreshToken endpoint will accept a "scope" parameter.  The
>>>>>>>>> application can then request the refresh of any external token by
>>>>>>>>> specifying this token in the "scope parameter.
>>>>>>>> I was thinking about adding a refreshToken endpoint to the identity
>>>>>>>> broker.
>>>>>>>> Isn't better ?
>>>>>>>>
>>>>>>> A different endpoint would require the identity broker to know if the
>>>>>>> app has permission to request it. Also, with my idea, you can refresh
>>>>>>> multiple things with one request.
>>>>>>>
>>>>>>>     From an application perspective we can provide a
>>>>>>> KeycloakSecurityContext.refreshToken(String... scope) method, then the
>>>>>>> app has one place to request the refresh of one or more claims.
>>>>>>>
>>>>>>> i.e.
>>>>>>>
>>>>>>> token = context.refreshToken("facebook", "google");
>>>>>>>
>>>>>>> String facebookToken = token.getClaim("broker.facebook.token");
>>>>>> I'm still not sure if this is right. Specially when using scopes for
>>>>>> that.
>>>>>>
>>>>>> Regarding app permissions, know if an app has an identity provider
>>>>>> enabled
>>>>>> and has access to retrieve its tokens is not enough ?
>>>>>>
>>>>> What does "app has an identity provider enabled" mean again?
>>>> Currently, you can enable/disable identity providers for each
>>>> application.
>>>> I'm also going to add another option to enable/disable token retrieval,
>>>> as
>>>> Stian suggested.
>>>>
>>> What does enable/disable entity provider per application mean?  A
>>> disabled "facebook" would mean that a "facebook" user couldn't visit the
>>> app?
>> It means that an application does not supports Facebook login. We just hide
>> the Facebook button from the login page for a particular application.
>>
>>>>>> And we can also provide a single place to request refresh for multiple
>>>>>> claims.
>>>>>>
>>>>> Err...that's the same thing I was suggesting.  IMO, most apps won't have
>>>>> to manually do a refresh, they can just rely on the adapter to do it for
>>>>> them.  The way I'm proposing requires no changes to adapter code and the
>>>>> user can let the adapter refresh things as appropriate.
>>>> Sorry, what I meant is the broker being the single place to refresh
>>>> tokens.
>>>> And not some where else.
>>>>
>>>> How are you going to specify which providers the user wants to
>>>> automatically refresh tokens ? keycloak.json ?
>>> In admin consonle, admin would configure the app to add the facebook
>>> token claim to the JWT access token.  When the application invokes
>>> refreshToken, this claim will be updated if needed.  It will all be a
>>> callback through the ProtocolMapper SPI I'm creating.
>>>
>>> If the application wants to refresh only one claim, then it would
>>> specify a "scope" with the refreshToken request.
>>>
>>> All this refreshing would happen between one API.  Then there is nothing
>>> broker specific for the application, only one URL to refresh everything.
>> Ok.
>>
>>>
>>> --
>>> Bill Burke
>>> JBoss, a division of Red Hat
>>> http://bill.burkecentral.com
>>>
>> _______________________________________________
>> keycloak-dev mailing list
>> keycloak-dev at lists.jboss.org
>> https://lists.jboss.org/mailman/listinfo/keycloak-dev
>>
> _______________________________________________
> 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