Custom web server for UI pages

Right, but there is no logged in user when you are trying to login/sign up/reset password and so on. That is what I am trying to say.

Why wouldn’t there be? How would one reset a password when there is no user? I think you need to read up on how keycloak works, or have a look at the project that I mentioned and you will see that it works with a standard yarn build process and an external keycloak.

It depends, with a proxy server as Ory does, you use Keycloak as just another API server, and saving configuration and so on that you would normally query using a Keycloak server itself.

Keycloak can already be used as an “API server” so no need to make things more complex by adding an proxy server.

There is a clear miscommunication or misunderstanding.

That is literally why I keep saying that it wouldn’t work. I am not sure if read the full thread, and what is your understanding of it.

Would you mind explaining what is the authenticated user for the following routes?

Sign In Page: My Account | Red Hat single sign-on
Reset Password Request Page: Reset your password | Red Hat IDP

Answer: None, there is no authenticated user in those pages.

I did take a look at the links you shared:

keycloak-admin-ui: a SPA application where you redirect the users to the Keycloak server in order to authenticate, therefore, this wouldn’t work for what we are asking for, once again, Keycloak is hosting the web-server for the HTML pages.

Sample theme for New Account Console: the example theme using React that is served by Keycloak server, therefore, this wouldn’t work for what we are asking for, once again, Keycloak is hosting the web-server for the HTML pages.

I think you need to read the thread and try to understand what the intent of the thread is. I think we are both stuck in a loop, and I am not sure what else to say.

The point is that Keyclaok ----> does not <---- serve the HTML pages from a theme and let an external server to do that.

Hopefully, @miguel response helps you to understand the intent.

To expand on this, using the OIDC nomenclature, what @yordis (and I) seem to want is the ability to use Keycloak as an Identity Provider (i.e., user store) but implement our own authorization server. Now, one would say, what’s the point of using Keycloak if you’re implementing your own authorization server? Well, the idea would be to use Keycloak as an API (i.e., there’s no HTML, CSS, and JS being used from Keycloak, just the HTTP APIs) to manage users (i.e., Identity Provider functionality) as well as an API to manage OAuth2 and OIDC flows from the custom authorization server. This is something that Ory does quite well (i.e., the separation of functionality into small “headless” modules).

The big question here is, can this be done with Keycloak? Are there APIs Keycloak exposes that allow the user to take the burden of implementing their own authorization server using Keycloak’s APIs (without having to re-implement the entire OIDC stack from scratch). It’s ok if the answer is “no”. In that case, for the specific needs we have of implementing a custom authorization server, Keycloak wouldn’t be a good solution and something like Ory Kratos and Ory Hydra would be better?

ahh okay, I’m sorry now I get it. You want all the pages to come form another server, not just the admin pages. Well I guess in that case you would need to have some sort of proxy as because of security reasons these pages must be served from keycloak.

What I still don’t see is how that would be a problem as it’s just 2 pages that you can’t serve yourself, but you can fully customize the look and feel of.

Ya ya, that is why we are trying to figure out or gather information about which APIs we would need in other to accomplish that proxy server.

I know this thread is a bit old, but the new admin console is able to be used from a different web server see GitHub - keycloak/keycloak-admin-ui: Keycloak Admin Console

Glad that change was made. Thank you!

@yordis @edewit hello all, I’ve been looking to solve a similar problem and found this thread.

It looks like many people had a hard time understanding the problem, so let me summarize:

  1. As part of the authentication protocol, a client redirects the user to, say auth.server/auth/realms/example/protocol/openid-connect/auth
  2. The user provides their credentials via HTTP POST to /auth/realms/example/login-actions/authenticate
  3. The user is redirected back to the client application

At no point in the process is any HTML, CSS, JS, or fancy responsive web UI explicitly part of the SAML or OpenID Connect flow. A user could fetch and type out the required HTTP requests in telnet, for example, but this would be very inconvenient.

To make this process easier, the Keycloak server kindly barfs out a HTML document, with some thoughtful <input/> tags, for your browser to automate the HTTP request part for you. (It also sets some cookies and provides some extra inputs to make sure someone didn’t trick your browser into doing this.)

If you wanted to handle the HTML part yourself, (and I do, because unfortunately the ones currently included by default are not very mobile-friendly, and customizing the .ftl files is cumbersome) there’s no fundamental reason you can’t, say, make an nginx proxy serve your own static files for /auth/realms/example/protocol/openid-connect/auth. However, Keycloak does make this difficult:

  • Some of the required state for the login process is in httpOnly cookie values.
  • There are additional required tokens that must be submitted, that are only provided when Keycloak renders the .ftl templates.

This could be solved if Keycloak had an API endpoint that provided the state tokens and metadata about the login process as e.g. JSON, and set the cookies it needs. This is not to implement a “resource owner password credentials grant” client, in the sense that a custom UI is part of the login process itself, and part of the identity provider service.

TL,DR the answer to what you’ve been asking this whole time:

The way to do this is not entirely painless, but gets you 95% to what you wanted.

  1. Create a new, base Keycloak theme
  2. Replace the HTML in the templates with a barebones HTML document. Maybe give it a <div id="container"></div> tag if that’s what your JS app is expecting.
  3. Add a <script> tag that includes your web app’s JS bundle from somewhere (you’re making this into what Webpack’s index.html does, essentially)
  4. Add a <script> section that copies the .ftl context into a JS variable. There are unfortunately a lot of these, I am not sure if there’s a quick way to dump the entire FTL context into a JSON string, or if that has sensitive data in it. It would look like e.g.
    <script>
        var kcState = {loginAction: "${url.loginAction}"};
    </script>
  1. Have your app implement the login/registration/etc. forms, submitting to window.kcState.loginAction for example.

And there you have it, you can write a JS app that handles all of the HTML rendering, and only relies on Keycloak for tokens and cookies. In fact, this is what the keycloak.v2 theme for the self-service account console does. Be sure to check it out for a real example.

TL;DR

  • One possible workaround I could think of is imitating the Keycloak frontend by loading the HTML sites with an Http-Client and extract the information needed (which is error-prone and cumbersome). But does this approach come with any security risks?
  • Is there something like an HTTP API (like Supabase Auth Endpoints that could be used?

Actual message

I didn’t want to bring up this topic 3 years later, but this is still a painpoint for many app developers, especially with the growing popularity of cross-platform UI frameworks and the limited cross-platform access to device services. And I am wondering if Keycloak does by now or can provide potential APIs to make the Keycloak frontend completely optional.

I can empathize the others and share their point of view. I think an easy to understand example is this: Someone wants to implement a native login and registration mask for a mobile app and use Keycloak as a headless user management system and auth server. The need to redirect the user to the browser and back seems unavoidable, since the flows of OIDC and OAuth 2 are strongly browser-based.

From what I have found across the internet is that the support for native apps without a browser (or so called “external user-agent”) was never part of OIDC or OAuth2 to begin with. The RFC8252 “OAuth 2.0 for Native Apps” describes in detail why that’s the case and why apps should follow the browser flow.

The main issue are first-party native apps installed on end-user devices (or external systems) and that should not store client secrets because it is considered insecure. If I want to use Keycloak’s features without the frontend, I either have to write a custom backend that uses a service account to extract the information needed and provide an custom HTTP API, or imitate the frontend by loading HTML documents and extracting information with methods like Regex matching.

For the latter I am curious about the security risks that come with it (if anyone can break it down for me this would be great).

If I take as an example the user registration, I can create a basic user if I simply load 2 websites, extract the information that are needed and send one POST request. However, the main issue is the lack of documentation, as there is nowhere documented what responses I can expect. And any change in the realm or client configuration may break the native registration flow.

An HTTP API would solve many limitations and allow native integrations for first-party (but still public) client apps. A great example is Supabase with its Auth endpoints where user registration is a single POST request. An HTTP API would allow keycloak flows like user registration and sign in to be integrated natively into first-party apps and for any other identity provider (if any configured) the app would still have to fetch information from the HTTP API first and then use an external user agent (like browser) to complete the according flow.

Does Keycloak offer anything similar to that?

@malliaridis Thank for the really well-reasoned and thorough message.

First of all, this is a community forum for Keycloak, and is rarely visited by the maintainers. I think your case should be brought up to them at the Keycloak GitHub Discussions.

On your specific question/idea, there are lots of opinions about this, and if you ask 4 people, you might get 5 different ones. My personal experience with the “auth endpoints” idea is that it can work, but requires an implementer that has excellent security knowledge. One of the reasons Keycloak hosts the pages for you is so they can control the variables they wouldn’t be able to if they were only exposing the endpoints.

I’ve audited more than one implementation of login screens using specifically supabase and a few other commercial offerings that use the same approach, and they all had fairly big issues. I don’t know what others’ experience is, but to paraphrase the first sentence, if you ask 4 independent security experts, you would probably only get 1 opinion on this.

@xgp Thanks for your reply. I agree that providing these endpoints would require excellent security knowledge and knowledge of how keycloak works in the background. The endpoints would require some kind of dynamic behavior in order to keep supporting all the configuration options currently available.

I thought of bringing this topic up as a feature request on Github, but as you can see this is not a straight forward approach and would probably bring up a lot of maintenance workload for the future. If I gain enough experience on the Keycloak implementation I might consider it though.