How can I make my spring boot application to log in to keycloak with given username and password?



I have a spring-boot application and I am using keycloak to authenticate users. 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.

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 was 200 (so the log in is success) then send another request to the confidential client to get back an access_token what is actually working?

Thanks in advance.

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 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.



Source: stackoverflow