[keycloak-user] Keycloak logout not working for “bearer-only” application exposing REST services

Stian Thorgersen sthorger at redhat.com
Wed Feb 7 02:54:03 EST 2018


That perhaps may be a bit over simplified answer ;)

When a session is logged out (through admin console, account management or
from an application) the whole session and all associated tokens are
invalidated.

However, bearer only clients verify tokens offline (without consulting the
server). There's two options to mitigate this. First is to use a short
expiration on access tokens. Second is to make the bearer only service call
the token introspection endpoint for every request.

For non-bearer clients they the Keycloak adapters have a admin URL that can
be configured for the clients. This will make Keycloak send a logout
request to logout which will invalidate the HTTP session and clear
associated tokens. If you don't do this you rely on the access token
timeout to make the client refresh the token to be aware that the session
is removed.

On 6 February 2018 at 13:31, Sebastien Blanc <sblanc at redhat.com> wrote:

> yeah with Keycloak you can not invalidate a particular token that would be
> too much state to handle for the server.
>
> On Mon, Feb 5, 2018 at 7:57 PM, Dan Nemes <dan.nemes at ymail.com> wrote:
>
> > Hello,
> >
> > I'm coming back after trying to invalidate the token.
> >
> > I have implemented the steps written in the previous mail and the token
> > has been successfully invalidated and it was no longer possible to access
> > the REST services using it.
> >
> > The problem with this workflow is the fact that all tokens that have been
> > generated before that "not_before" field are invalidated. In my case this
> > isn't correct because I must support multiple users logged in at the same
> > time.
> >
> > I have also tried to implement the same steps by executing the revocation
> > endpoint for a specific client application (instead of using it on a
> realm
> > level (eg. *http://localhost:8180/auth/admin/realms/demo/clients/{
> client_id}
> > <http://localhost:8180/auth/admin/realms/demo/clients/%7Bclient_id%7D> *
> > and *http://localhost:8180/auth/admin/realms/demo/push-revocation
> > <http://localhost:8180/auth/admin/realms/demo/push-revocation>*) but
> this
> > doesn't seem to work because the users can still access the REST services
> > (but I don't think this will work either for my case).
> >
> > Is there a way to invalidate only one specific token so that the REST
> > services are not accessible anymore using that specific token?
> >
> > Thank you,
> > Dan Nemes
> >
> >
> >
> > On Sunday, January 21, 2018 4:57 PM, Sebastien Blanc <sblanc at redhat.com>
> > wrote:
> >
> >
> > Hi,
> >
> > Thx a lot for the sample, I could reproduce your issue. Keep in mind that
> > you bearer-only app just verify the signature of the token, it has no
> > session with your kc server. It will validate it until it's valid (if you
> > wait the access token lifespan (5min by default) you will see it does not
> > work anymore).
> >
> > So how to invalidate the token ?
> > 1. Be sure to set an admin URL for your bearer client :
> > http://localhost:8080/TestRestProject/rest/service
> > 2. Then after your do the logout, you must also invocate the revocation
> > endpoint :
> >   2.1 You can do that through the admin console in sessions > revocation
> > and you push the new notBefore value
> >   2.2 You use the admin REST endpoint to invalidate the token  , it's a 2
> > step flow : update the notBefore value of the realm by doing a PUT on the
> > realm and then calling the POST revocation endpoint.
> > Check the network console of your browser to see the flow when you are in
> > the admin console and check the admin REST doc)
> >
> > Hope this helps,
> >
> > Sebi
> >
> >
> > On Sun, Jan 21, 2018 at 1:19 PM, Dan Nemes <dan.nemes at ymail.com> wrote:
> >
> > Hello,
> >
> > Thank you for your quick response.
> >
> > I am using keycloak-3.4.0 and wildfly-10.1.0.Final.
> > I have just added on github the projects I have created for working with
> > keycloak. You can find them here: https://github.com/ NemesDan/keycloak
> > <https://github.com/NemesDan/keycloak>
> >
> > Please note that these projects have been started as a POC of how
> keycloak
> > can be used so there are other functions that are out of the scope of the
> > problem I'm having. I am still in the learning phase of how keycloak can
> be
> > used at it's full potential.
> >
> > NemesDan/keycloak
> > keycloak POC projects
> > <https://github.com/NemesDan/keycloak>
> >
> >
> > There are multiple maven projects on this branch.
> > 1. Project GSDKeycloakProject with 3 modules: customer-app,  product-app
> > and database-service. The last mentioned module is the bearer-only
> > application in which the REST services are implemented.
> >     database-service: contains two classes ProductService
> > and CustomerService which implement REST services that are accessible
> only
> > to logged users that have the correct role assigned.
> >
> > 2. KeycloakAccess - should be ignored, out of the scope of the problem
> >
> > 3. RestClientApplication - a maven web project in which the entire
> > workflow is implemented. This simulates a client application that will
> > login a user using keycloak, retrieve a token and use that token to
> access
> > the "database-service" bearer-only application.
> >
> >     In class RestService you can find the following implemented REST web
> > services
> >         3.1 GET request on *http://localhost:8080/
> > TestRestProject/rest/service/ login
> > <http://localhost:8080/TestRestProject/rest/service/login>* -> redirects
> > user to the keycloak login page to perform the login. After login,
> keycloak
> > redirects the user to to *http://localhost:8080/
> > TestRestProject/rest/service/ user_logged_in
> > <http://localhost:8080/TestRestProject/rest/service/user_logged_in> .*
> At
> > this point the code is exchanged for token.
> >         3.2 GET request on *http://localhost:8080/
> > TestRestProject/rest/service/ call_database/{param}
> > <http://localhost:8080/TestRestProject/rest/service/
> call_database/%7Bparam%7D>*
> >             - *{param}* could be either *products *or *customers*
> > *            - *this web service call will use the token from step 3.1 to
> > access the database-service bearer only REST services
> >         3.3 GET request on {URL}/logout or {URL}/logout_2
> >             - these requests were created in order to test the logout
> > functionality but it seems that the database-service REST services are
> > still accessible after the logout has been performed which after my
> > knowledge means that the token has not been invalidated
> >
> > The key point of these projects is to avoid using any keycloak classes to
> > implement the client application because we do not want to force the
> > clients to use a specific library.
> >
> > If I missed something please let me know.
> > I appreciate your help.
> >
> > Thank you,
> > Dan Nemes
> >
> >
> >
> > On Sunday, January 21, 2018 12:11 PM, Sebastien Blanc <sblanc at redhat.com
> >
> > wrote:
> >
> >
> > Hi,
> >
> > Which version of Keycloak are you using ? Which adapters are you using
> for
> > the client and bearer-only apps ? We need this info. And yes sharing your
> > project (through github for instance) could be really helpful.
> >
> >
> >
> > On Sun, Jan 21, 2018 at 10:17 AM, Dan Nemes <dan.nemes at ymail.com> wrote:
> >
> > Hello,
> > I am unable to logout an user. The logout works for a "confidential"
> > applications but it doesn't for a "bearer-only" application (the REST
> > services are still accessible after logout).
> > I have the following configuration:
> >
> >    - I have one "database" client application defined in Keycloak having
> > access type "bearer-only" (created with the intent of exposing REST web
> > services protected by Keycloak based on user roles)
> >    - I have one "rest_service" client application defined in keycloak
> > having access type "confidential" (created with the intent of logging in
> > users and allowing access to the "bearer-only" REST services after a
> > successful login). The below described workflow is implemented in this
> > application using REST web services
> > I am performing the following steps:
> >    - An http GET request is performed on URL http://localhost:8180/
> > auth/realms/demo/protocol/ openid-connect/auth
> > <http://localhost:8180/auth/realms/demo/protocol/openid-connect/auth>
> which
> > redirects the user to the login page handled by Keycloak
> >    - The user performs the login using his credentials (using the
> > credentials of a user defined in Keycloak)
> >    - Keycloak redirects the user to the "redirect_uri" which was passed
> in
> > step 1. In this step Keycloak also provides as request parameters the
> > "state" and "code" values.
> >    - After the user has been redirected back to the application I
> exchange
> > the "code" received in step 3 for a token doing a POST request on
> http://localhost:8180/auth/
> > realms/demo/protocol/openid- connect/token
> > <http://localhost:8180/auth/realms/demo/protocol/openid-connect/token>
> which
> > is done successfully
> >    - After the access token is available I proceed to access the
> > "bearer-only" REST web services.
> > note: the REST web services exposed by the "bearer-only" service are not
> > accessible unless the user has been logged in and it has the correct
> "role"
> > assigned to it.Problem: As stated at the start of the post the user is
> > still able to access the "bearer-only" REST web services after the logout
> > has been done. The only thing that seems to work is the logout from the
> > "confidential" application (the user is not able to access the
> application
> > unless he logs in again).If I perform the logout of the user then the
> REST
> > web services exposed by the bearer-only application are still accessible.
> > In the Keycloak server I get the following WARN message: " Some clients
> > have been not been logged out for user adminuser in demo realm:
> > rest_service"I tried implementing the logout in three ways:
> >    - A redirect to URL http://localhost:8180/ auth/realms/demo/protocol/
> > openid-connect/logoutpassing
> > <http://localhost:8180/auth/realms/demo/protocol/openid-
> connect/logoutpassing>
> > in the redirect_uri and client_id parameters
> >    - A POST request to http://localhost:8180/auth/
> > realms/demo/protocol/openid- connect/logoutpassing
> > <http://localhost:8180/auth/realms/demo/protocol/openid-
> connect/logoutpassing>
> > in the Authorization Bearer in the header and the client_id,
> refresh_token,
> > client_secret and redirect_uri
> >    - A REST service exposed by the "bearer-only" service which does the
> > following method call: HttpServletRequest request.logout()
> > Neither of the above methods is working.PS: I did not want to go in to
> > many details because even so the post is long enough. If I missed
> something
> > please tell me and I will provide the additional information (if
> possible I
> > can also attach the actual projects)
> > Thank you,Dan Nemes
> >
> > |  | Virus-free. www.avg.com  |
> >
> > ______________________________ _________________
> > keycloak-user mailing list
> > keycloak-user at lists.jboss.org
> > https://lists.jboss.org/ mailman/listinfo/keycloak-user
> > <https://lists.jboss.org/mailman/listinfo/keycloak-user>
> >
> >
> >
> >
> >
> >
> >
> >
> _______________________________________________
> keycloak-user mailing list
> keycloak-user at lists.jboss.org
> https://lists.jboss.org/mailman/listinfo/keycloak-user
>


More information about the keycloak-user mailing list