Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Example regarding backend use #3

Open
Threnklyn opened this issue Jan 27, 2021 · 6 comments
Open

Example regarding backend use #3

Threnklyn opened this issue Jan 27, 2021 · 6 comments

Comments

@Threnklyn
Copy link

Hi Zakaria, thanks for this great example.
I've read your blog post about the possibility to add API-Key functionality to keycloak.
In your example the backend has to check the key.
Is there any way to return a signed JWT from keycloak if the api key is valid?
This would enable the usage of the same backend logic for oidc users and api users.

@zak905
Copy link
Owner

zak905 commented Feb 28, 2021

Hi @Kuchenm0nster, Sorry for the late reply. I am not sure if it's possible to generate an authenticated user token from the api key endpoint. I will check about that. In the meanwhile, if you want to obtain a token from a single request, you can look into client credentials oauth grant. I am not sure about your use case, but this grant is designed for service to service communication, and you don't need user interaction (like authentication_code), you just need to configure it from the keycloak admin. Here is an example request:

curl --request POST 'http://localhost:8080/auth/realms/your-realm/protocol/openid-connect/token' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'client_id=the-client-id' \
--data-urlencode 'client_secret=secret' \
--data-urlencode 'scope=email' \
--data-urlencode 'grant_type=client_credentials'

@zak905
Copy link
Owner

zak905 commented May 31, 2021

Hi @Kuchenm0nster, Sorry again for the late reply, I got distracted. I did some research. IMHO, it would not be a good practice (but it's possible) to generate an authentication token out of this api key endpoint because it would be in some way by-passing the security mechanisms set by OAuth2. Let's say we want to generate a token in the same way as keycloak does from our endpoint. Looking at the OAuth2 grants, we are left with either the password or client_credentials grants (authorization_code needs two steps, the first one involving user login and consent). For the password grant, you need to provide and to know the user password, which makes it a sensitive way of getting the authorized only used in highly trusted systems. Even if we know to which user belongs the api key, we cannot know the password because well, it's encrypted before storing. So if I would say the password grant is is also excluded, because you need to provide the password and the api key, which kills the whole concept why we are using an api key.
Now we are left with the client_credentials grant. The client_credentials relies on the service account associated with the keycloak client. If we copy the code used to generate the (JWT) token in our endpoint, the generated token will not bear the user identity but rather the service account identity. This could be a problem, because all users will have the same kind of permissions / restrictions, and the same identity. If this is still ok, then you can take a look at the code used to generate a token using client credentials here: https://github.com/zak905/keycloak/blob/master/services/src/main/java/org/keycloak/protocol/oidc/endpoints/TokenEndpoint.java#L678

@Threnklyn
Copy link
Author

Hi @zak905, thanks for your reply. We have decided against the usage of api keys. Maybe the Token Exchange might be suitable. The service account gets the impersonation role and can exchange its token for a token of a real user.

@adityakuchekar
Copy link

Hi @zak905 ,
Were you able to find out anything related to returning a signed JWT (access token) if the api key is valid?

@zak905
Copy link
Owner

zak905 commented May 24, 2023

Hi @adityakuchekar,

returning a signed JWT is possible, but it can be considered as an anti pattern since the OAuth flows (that are developped to ensure security would be by-passed. I am quoting a comment from a similar question I answered on my personal blog (the article can be found here):

Technically, it should be possible to generate an access token (with some hassle) from the api key endpoint. You can find some implementation details in this Keycloak class: https://github.com/zak905/keycloak/blob/master/services/src/main/java/org/keycloak/protocol/oidc/endpoints/TokenEndpoint.java. However, I see this as anti-pattern. Keycloak relies on protocols such OAuth2 (and OpenID connect) to generate tokens. OAuth2 follows some well defined specifications aimed at enforcing security and integrity of the tokens. By generating a token from the api-key endpoint, we are kind of by passing all these mechanisms.

If you are still not convinced, and want to generate a token from the API key endpoint, all the utils to generate a token can be found in the TokenManager: https://github.com/keycloak/keycloak/blob/main/services/src/main/java/org/keycloak/protocol/oidc/TokenManager.java

@adityakuchekar
Copy link

thanks for the suggestion @zak905

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants