Spring Security OAuth2 with Keycloak - How to avoid login page, pass username and password

I created a post on Stack Overflow, before I found this forum.
Perhaps it is alright to post the link to not have to repeat it.

https://stackoverflow.com/questions/68847265/spring-security-oauth2-with-keycloak-how-to-avoid-login-page-pass-username-an

Thanks!

Without looking to deep in your question, I suppose you collect username and password in your application and want to use this data to login the user in keycloak.

This is called direct grant in openid connect. Keycloak supports it. Just call the endpoint with the credentials and you’ll receive a token.

[Update]
Having better read your question, I believe you only need to setup your spring application to use keycloak as its authentication service.

Right know, you have an authentication service being provided by spring security and using keycloak as another layer.

You just need one layer: keycloak. Your application will be a client of keycloak.

That is:

  • user access your application
  • get’s redirected to keycloak
  • login
  • gets redirected back to your application
  • application gets token from keycloak, gives user a session cookie
  • on returning requests, user presents session cookie and is admitted.

My Client application in fact will be a Spring MVC project, which presents the data returned by the endpoints of my webservice (backend, Resource Server) on HTML pages via Thymeleaf. You see in my post at Stack Overflow the simplified pom.xml, which includes the Thymeleaf dependencies.

I simplified the Client application leaving out all the stuff with Model and so.

I have to keep my webservice (Spring Boot backend, Resource Server) project separate from my frontend (Spring MVC) project.

And you’r right, my frontend application will collect some user credentials and use those for the authentication against the Keycloak. In fact in the example I could have hard coded username and password as fields in the controller of my Client (frontend) application. That’s why the user shall not enter these credentials himself, and that’s why there should not be a login page by Keycloak, no login page at all.

You are building an api. You need to secure it so only approved frontends can talk to it, but the frontend talks to the backend using its own credentials (a key), not user credentials (username and password).

This not the primary user case for oauth2.

Oauth2 is for cases when you, the user, want to give authorization for a service (like Trello) to access resources (like your calendar) in a service provider (like Google).

You login to Trello, it asks you to also login to google so Google asks you to authorize Trello’s access to your calendar. Trello now has a token and must include it in the request every time it tries to read your calendar on Google.

That being said, you can secure an api using oauth2, just using client credentials.

So now, your frontend application can use whatever method is want to authenticate its users and the backend will happily accept frontend requests if they come from the frontend.

Maybe this will help: https://www.baeldung.com/spring-webclient-oauth2#spring-security-5-support---the-client-credentials-flow

@weltonrodrigo I may have too quickly overlooked your hint direct grant in openid connect

I assume the grant type I have to use is Resource Owner Password Credentials, means password instead of authorization_code.

As I mentioned in my post, at Keycloak side I created a client with

Standard Flow Enabled ON
Direct Access Grants Enabled ON

so direct grant is already ON, but do I have to switch Standard Flow Enabled off or can it remain ON when using Resource Owner Password Credentials?

I find examples on the web for ROPC, but I couldn’t find any with Spring Boot Web, all show it with Postman or curl.

I simply don’t know how to modify my artifacts in the CLIENT application part in my post at Stack Overflow, so it does ROPC.

At OAuth Grant Types I see that Password Grant is considered Legacy.

And also it states
Because the client application has to collect the user's password and send it to the authorization server, it is not recommended that this grant be used at all anymore.

Well, this is true if is a third party application, but in my case the webservice (backend) and the client application (frontend) are mine, I can trust those :slight_smile:

I have to switch from basic authentication to OAuth2, that is simply a requirement I have to implement. And with basic authentication I don’t have a login page, username and password are passed as header via the WebClient from frontend to my webservcie

basicAuthHeader = 
    "basic " + Base64Utils.encodeToString((username + ":" + password).getBytes());
...
webclient.header(HttpHeaders.AUTHORIZATION, basicAuthHeader)

Now with OAuth2 I have to get rid of the login page as well.

If Password Grant is Legacy, it still can be used?

I updated my question in a new post at Spring Security OAuth2 with Keycloak - Implement Resource Owner Password Credentials grant type (password) - Stack Overflow

I cannot edit my initial post here to exchange the link.

I have an additional question to using Resource Owner Password Credentials grant type (password).

I access my frontend endpoint via http://localhost:8182/hello
Now for ROPC to work I have to submit the username and password as request parameters, and Spring will get the token with these credentials from Keycloak.

It would look like this http://localhost:8182/hello?username=myuser&password=mypassword

How is this transfered? Username and password are in plain text, or is there some encoding under the hood by Spring Web / WebFlux?

Does Keycloak expect plain text values for username and password? Is there some possibility to encode those values?

I assume that’s why the password grant type is considered insecure, but still, it depends on the environment the backend and frontend run.