Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Running User Interfaces and APIs behind keycloak gatekeeper

New to keycloak, and authentication in general, so sorry for missing something obvious, and not using accurate terminology.

I'm trying to run a simple Angular UI that talks to a Java (dropwizard) API. I'd like both of those to need auth. I'm (almost) able to get them running fine behind keycloak and keycloak gatekeeper using a single realm and a confidential client. In this case gatekeeper has an upstream-url that is a traefik instance, that then routes to either the UI or API docker container. Something like:

Gatekeeper upstream-url ----> Traefik (my.domain/*)  ----> UI (my.domain/ui/*)
                                                     \---> API (my.domain/api/*)

This works fine until the session times out, and when the user on the (already loaded) UI page clicks a button that tries to send an ajax request to hit the API (eg https://my.domain/api/getstuff), then Gatekeeper redirects (ie 301) that to the the keycloak login page. This redirect is a little nonsensical for an API request...

At this point both my UI and API projects are auth agnostic (ie they are not running any of the adapters etc just yet - I'm relying on the docker setup to prevent "direct" access to UI and API for now. I'll add the adapters once I need to know something about the user). I can see in https://www.keycloak.org/docs/latest/securing_apps/index.html#configuration-options the autodetect-bearer-only option which seems to describe my issue, ie

It allows you to redirect unauthenticated users of the web application to the Keycloak login page, but send an HTTP 401 status code to unauthenticated SOAP or REST clients instead as they would not understand a redirect to the login page

but seems to apply at the adapter layer, ie after gatekeeper in my scenario. this seems similar too.

I think I want unauthenticated (eg never logged in, or timed out) access requests to https://my.domain/ui/* to be redirected to the keycloak login page, but https://my.domain/api/* to 401.

And from https://my.domain/ui/somepage the ajax request to https://my.domain/api/getstuff to use the JWT/token/cookie that the browser has from the login (which is working now).

How do I do this? What stupidly obvious step have I missed!?

like image 585
IveGotNoIdea Avatar asked Oct 08 '19 10:10

IveGotNoIdea


1 Answers

Unfortunately, you cannot tell Gatekeeper to return 401(403) response codes instead of redirect. There is similar issue: https://issues.jboss.org/browse/KEYCLOAK-11082

What you can do is to remove Gatekeeper completely and implement public client authentication on frontend (JS adapter) and bearer-only client on backend (Java Adapter). If your Java application serves frontend you can implement only confidential client authentication and return 401(403) response for /api/* requests.

like image 180
Vadim Ashikhman Avatar answered Nov 18 '22 08:11

Vadim Ashikhman