Issue
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.
Solution
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 you configured your Spring App correctly, and if the Keycloak client that your users will be authenticated against use Authorization Code Flow
(i.e., Standard flow Enabled on Keycloak), the user logins into your app, gets redirect to Keycloak, and authenticate itself. If the user is successfully authenticated, the user will be redirected (probably) back to your app, and that app will get back, among others, an access token. That access token can then be used to perform actions on behalf to 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 not using a pure web-browser application, or a mobile phone, but rather a spring-boot application with a secure backend, you should use a confidential client
.
You are mixing stuff 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 our without the client being confidential. With a public client
the request for a token from Keycloak:
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.
Answered By - dreamcrash
Answer Checked By - Willingham (JavaFixing Volunteer)