Keycloak auth token

Hi,

What i need: keycloak auth token in registered client app.
What i did:

  • ran a keycloak instance
  • logged in in the admin console
  • registered an user (all user will be managed in keycloak),
  • registered an app (client protocol: openid-connect, acces type: confidential, direct access grants enabled on, i used root url, redirect urI and base url to point to my app, authentication flow browser->browser, direct grant->direct grant)
  • go to realm/account, log in
  • when i select my application the redirect works fine
    Question: How can I know in my app that the user is logged in in keycloak? I was thinking about receiving a token in the headers or read a cookie set by keycloak, only that there is no cookie, and I don;t know how I can get the token in the header/sent it from keycloak.

Is this a valid case where the user are managed in keycloak, and they get access to use an app registered as client?

Let me know if i can clarify more things as I am pretty new at this.

Thanks for posting the full flow you went through. To receive the token in your app, it really depends on how you are securing it. Have you picked which adapter you are using? For example, if you are using the Javascript adapter, you can set it up as documented here: Securing Applications and Services Guide. Then, when you are directed to the redirect url, it will force a challenge that will either cause a code to token exchange, or send the user to he login screen, if they don’t already have an sso session. Let us know if we can answer any questions about how to secure your application. Knowing more about what you’ve built would help (e.g. is it a Javascript SPA? A Java Spring Boot application? etc.)

I think there are 2 use cases here:

  1. User first logs in keycloak and from account console is selecting the application that he wants to use (a registered client). I think this is opening the Base URL from the client settings. In this case I still don’t know how to get the keycloak token in the app.
    But because I was struggling with this approach, I also tried to investigate the second case:
  2. User tries to access the app directly, and using the javascript adapter (thanks for the link) he will be prompted to log in using the keycloak login page.

For this second case I had the following flow:

  • from keycloak client page I went to the installation page and took the Keycloak OIDC json
  • I created a new react project with 2 simple routes, 1 simple component that does nothing, and a ‘secured’ component which is importing the keycloak-js
  • as soon as this component mounts, I execute
const keycloak = Keycloak('/keycloak.json');
keycloak.init({ onLoad: 'login-required' })
  .then(authenticated => {
     window.localStorage.setItem('keycloak', keycloak);
     window.localStorage.setItem('keycloakauth', authenticated);
     setKeycloak(keycloak);
     setAuthenticated(authenticated);
   })

Some observations:

  • if I have let’s say ‘http://localhost:3000/’ as the Redirect URI in the client setting, as soon as I hit the secured route, I get redirected to keycloak auth and I get the error ‘Invalid parameter: redirect_uri’
  • only if I have * for Redirect URI or I add * as another redirect, only then I get redirected to the keycloak login, and it’s also working, I get logged and redirected to my secured component/page
  • on localhost or 127.0.0.1:3000 there are no cookies and nothing in local storage
  • on 127.0.0.1:55700 (random port) where keycloak is running, I can see some cookies (KEYCLOAK_SESSION_LEGACY, KEYCLOAK_IDENTITY_LEGACY, KEYCLOAK_IDENTITY, AUTH_SESSION_ID_LEGACY, KEYCLOAK_SESSION, AUTH_SESSION_ID)

Issues:

  • I still don’t know how to obtain the token, my state is still default, the local storage is empty, no breakpoints activates in the then (because of redirects)

In the end I want to obtain the login token and cache it in my internal authentication service, because the client will consist of many apps, and I want to create my own token which I will validate between client apps, based on the token from keycloak.
I want to also expose a logout endpoint to be used in the keycloak client setting Backchannel Logout URL to invalidate my internal token when the user logs out of keycloak.

Does this make sense? Sorry for the long post and thanks.

Great detail. Check out the documentation for the Javascript adapter: Securing Applications and Services Guide

Once you init the Keycloak object and the user is logged in, you can get the token with keycloak.token.

Regarding your observations, you have to have a redirect uri specified in the client you have set up that matches the redirect specified when you init keycloak. Note, depending on how you access the page, it may be sending a different host for the redirect uri. E.g. if you are accessing it with http://localhost:3000/secured, but your keycloak client config specifies http://127.0.0.1:3000/* you’ll get a redirect uri error. This is annoying, but because the “code” in the OIDC code-to-token flow is passed in the redirect, it is essential from a security perspective that it is specified correctly.

Regarding use case 1, if the “base URL” you specify is a secured url, there will be a redirect to keycloak, but the user will not have to go through the login again, as there is already an active sso session.

Let me know if anything is unclear.

1 Like

Thanks for your time.

Seems to be working now when using the IP all over the place.
The keycloak.init promise is resolved and I can extract the token with keycloak.token.
This works both when I access the app first and I get redirected to keycloak’s login page and back to my app, and when I access keycloak’s user console first, log in directly and then select the app from the menu.