I have a spring-boot application and I am using keycloak to authenticate users. I am planning to make an endpoint in my application that waits a username and a password, it logs-in to keycloak and if the username/password is valid ask for an access token and give it back to the user.
How can I make this log-in to keycloak?
As I see I need to have a public
client to make my keycloak use username/password, but this does not contain any resource_id
so I need an access_token
from a confidential
client.
Should I ask for an access_token
from the public client, and if the response code is 200
(so the login is successful) then send another request to the confidential
client to get back an access_token
that is actually working?
Thanks in advance.
Advertisement
Answer
I am planning to make an endpoint in my application what waits a username and a password, it logs into the keycloak and if the username/password is valid ask for an access token and give it back to the user.
If we assume that
- the Spring App is configured correctly;
- the Keycloak client that the users will be authenticating against uses
Authorization Code Flow
(i.e., Standard flow Enabled on Keycloak), or even betterAuthorization code flow with PCKE
then when a user logins into your app, the user gets redirected to Keycloak for authentication. The user is redirected (probably) back to your app (if the authentication is successful), and your app receives, among others, an access token. That access token can then be used to perform actions on behalf of the authenticated user.
As I see I need to have a public client to make my keycloak use username/password, but this does not contain any resource_id so I need an access_token from a confidential client.
From the RFC 6749 OAuth 2.0 specification one can read:
confidential
Clients capable of maintaining the confidentiality of their credentials (e.g., client implemented on a secure server with restricted access to the client credentials), or capable of secure client authentication using other means.public
Clients incapable of maintaining the confidentiality of their credentials (e.g., clients executing on the device used by the resource owner, such as an installed native application or a web browser-based application), and incapable of secure client
Since you are neither using a pure web browser application nor a mobile phone but instead a spring-boot application with a secure backend, you should use a confidential client.
You are mixing up concepts if you mean that you want to use “Resource Owner Password Credentials Grant” (i.e., Direct Access Grants Enabled in Keycloak). You can still used with your application without having to use a confidential client. With a public client the request for a token from Keycloak looks like:
POST -d "client_id=<client_id>" -d "username=<username>" -d "password=user_password" -d "grant_type=password" <KEYCLOAK_HOST>/auth/realms/<REALM_NAME>/protocol/openid-connect/token>
with a confidential client:
POST -d "client_id=<client_id>" -d "client_secret=<client_secret>" -d "username=<username>" -d "password=user_password" -d "grant_type=password" <KEYCLOAK_HOST>/auth/realms/<REALM_NAME>/protocol/openid-connect/token>
you got the extra field -d "client_secret=<client_secret>"
.
Bear in mind, however, that:
The resource owner password credentials grant type is suitable in cases where the resource owner has a trust relationship with the client, such as the device operating system or a highly privileged application. The authorization server should take special care when enabling this grant type and only allow it when other flows are not viable.