49

My setup has three components:

  • A backend application (Python/Flask)
  • A frontend application (VueJS)
  • Keycloak

The frontend will use Keycloak to let users sign in and use the access tokens to authenticate requests to the backend. So far so good.

Now I want third party applications to be able to make authenticated requests against the backend and I am wondering how that can be realized using Keycloak? My idea is to issue a new set of credentials for each customer. Their application then talks to Keycloak to get access tokens. I can then use Keycloak to manage access control for all users of the API.

  • How would a 3rd party app be represented in Keycloak - client? user? ...?
  • Are there best practices for this kind of use case?
Marco Lamina
  • 3,326
  • 4
  • 22
  • 22

1 Answers1

61

I finally found a solution that works well and seems to be "the Keycloak way" to issue credentials to external applications. To create a new set of credentials, add a new Keycloak client and change the following settings:

  • Standard Flow Enabled: OFF
  • Direct Access Grants Enabled: OFF
  • Access Type: Confidential
  • Service Accounts Enabled: ON

The external application will use our newly created client's name as the client_id. The client_secret was generated automatically and can be found under the Credentials tab.

Granting Client Access to Your Services

If your Keycloak-protected services are configured to check the aud claim of incoming Bearer tokens, a second step is necessary. By default, the audience of the JWT tokens that Keycloak issues to your client will be set to your client's name, so they will be rejected by your services. You can use Client Scopes to modify that behavior:

  1. Create a new client scope
  2. Select "Audience Template"
  3. Select the service you'd like to grant your external applications access to and click "next"
  4. Add the scope to the client you just created (Client Scopes tab)

Keycloak will now add your service's name to the aud claim of all JWT tokens it issues to your new client. Check out the Keycloak documentation on Service Accounts for more details.

Exchanging Client Credentials for an Access Token

An external application can now use its credentials to obtain an access token from Keycloak's token endpoint:

POST {keycloak-url}/auth/realms/atlas/protocol/openid-connect/token

  • Set the Content-Type header to application/x-www-form-urlencoded
  • Authenticate the request with Basic Authentication, using your client id as the user and your client secret as the password
  • Set grant_type=client_credentials in the request body
Marco Lamina
  • 3,326
  • 4
  • 22
  • 22
  • 4
    Does this mean that it is necessary to create a new Keycloak client for each 3rd party application? – GGGforce Jul 27 '19 at 10:14
  • 3
    Yes, that is the idea. I haven't worked with Keycloak in a while though, so this approach might be out of date. – Marco Lamina Jul 29 '19 at 16:50
  • 7
    I'm pretty sure that's the exact model Keycloak wants: 1 client == 1 app – cacois Sep 03 '20 at 19:31
  • 6
    The problem with "the Keycloak way" is that nobody else in the world does it this way. It doesn't feel right. Everybody else just gives the developer an api key and done with it. – GGGforce Dec 21 '20 at 07:11
  • Service Account seems to be a workaround but we can't add "attributes" to a ServiceAccount right ? – Cocorico Feb 17 '21 at 09:57
  • 3
    @GGGforce if you check something like https://developers.google.com/identity/protocols/oauth2 you will see you are setting up a client and a secret – Keith Nicholas Apr 14 '21 at 10:28
  • Using a new client for every new app is really a bad resolution. And letting only administrator to use this way is awful. Every individual user may have the ability to define an api key. If the regular users are not allowed than some kind of api user concept should have been implemented. Better not to use Keycloak for this kind of requirements. Thank you Marco for your effords to get keycloak way – serkan Oct 14 '21 at 07:34
  • I cant say I find the approach wrong that 'every client app' has a 'keycloak client' configuration. Makes kind of sense doesn't it? What I would like to know is how I could avoid getting a token first and have something like a basic auth forward to keycloak. Is that still possible with the latest Keycloak versios? – schwaller Jun 16 '22 at 09:35
  • You may want to have a look at https://github.com/carbonrider/keycloak-api-key-module – CuriousMind Sep 08 '22 at 13:37