Search code examples
javaauthenticationoauth-2.0keycloakopenid

Keycloak API keys support


We have an already existing system which uses an old Auth0 server for authentication and authorization. My goal is to integrate this system with Keycloak. In the Auth0 server we assign roles to users and these roles are mapped to a group of permission scopes, eg, "account:create", "user:create", etc are assigned to role "admin". We are planning on using keycloak Authorization services to replace Auth0 authorization. For it to work, we need to use keycloak bearer tokens.

Problem is, several users make requests to our API using an api-key (fix token). We basically make a request to the Auth0 server with api-key and it returns permission for that user. As we can't ask user to change the way the interact with our API (managament decision), i'm thinking on creating a custom authenticator, so when I request token endpoint (http://{ip}:{port}/auth/realms/{realm}/protocol/openid-connect/token) with an extra api-key header, I can check if there is an user with that api-key attribute assigned and get a bearer token for that user in return. The idea is to do this internally.

Is it a correct approach? If so, how do I implement the authenticator? Once I have found the user by api-key, how do I tell the authenticator which is the authenticated user?


Solution

  • Better late than never! I resolved this a while ago, but I wanted to share the solution, in case it helps someone:

    1. I saved the API keys as user attributes.
    2. I created a custom Keycloak Authenticator that checks if there is an user with the given API key.
    3. I created a custom direct grant flow to use the custom Authenticator that successfully authenticate the user either if an API key or usual username and password credentials are provided in the token endpoint.
    4. As the user only knows about API keys, I used an eviction cache whose key is the API key and whose value is the bearer token.

    You can find an example and more details in the following repo: