We implemented a custom AuthenticationFlow with Authorization Code Flow and its working perfectly fine for that use case.
There we used three custom execution steps integrating a legacy login with custom Authenticators - no problem.
The direct grant flow in the UI suggests we can integrate using the same method, building a multistaged flow for direct grant and chaining the execution steps. This would enable us to reuse the existing login page without “breaking” the UX by redirecting to keycloak.
We guessed this way we can use any HTTP Client like cURL or a Javascript client to execute this flow - executing custom legacy logins and obtaining a token in the end.
Although we set the AUTH_SESSION_ID cookie in the first execution step the session is lost in the second execution Step.
Digging deeper we found that on every request from the CURL client a new session gets initialized - regardless of any AUTH_SESSION_ID cookie set.
The code explains this behaviour: keycloak/TokenEndpoint.java at master · keycloak/keycloak · GitHub
RootAuthenticationSessionModel rootAuthSession = new AuthenticationSessionManager(session).createAuthenticationSession(realm, false);
AuthenticationSessionModel authSession = rootAuthSession.createAuthenticationSession(client);
A bit further down maybe a hint we are on the wrong track:
// Remove authentication session as “Resource Owner Password Credentials Grant” is single-request scoped authentication
We don’t want to operate against core keycloak principles.
Are we wrong trying to use multiple execution steps with Resource Owner Password Credentials Grant?