Hi All and sorry for the long email.
As you know, most AJAX frameworks send a X-Requested-With request header. This header
is quite useful if you want to handle AJAX requests differently than ordinary HTTP
requests.
For most cases, the keycloak.js is the perfect tool to enable user authentication and
token management to a client application using HTML5+AJAX. However, we may find use cases
where client configuration is restricted and you can't change it very deeply to
integrate with Keycloak.
Well, yes. These are requirements from WildFly/EAP Console (a.k.a HAL) :)
If you are not familiar about how the console works from a security PoV, you just need
to know that there is no specific configuration to secure the console itself, but to
secure the Domain Management API. In other words, the console isn't protected at all
and relies on the policies defined to the Domain Management API and on the authentication
that is performed by the browser (eg.: DIGEST).
(There are some reasons why the console isn't protected by the server. For
instance, the server is only concerned about protecting the domain management API and also
that the console is just one more client that can talk with that API.)
The console is basically a GWT application using XMLHttpRequest to send requests to
the server, where these requests are only accepted if they have some
authentication/identity cookie (DIGEST, BASIC or Keycloak Identity Cookie) which can be
handled by the browser and added to every single request to the server.
Thanks to Elytron, we can now protect the Domain Management API with any HTTP
mechanism we want without having to change wildfly-core or any other part of the server.
In the past few days I've been working on a Keycloak OIDC Adapter based on Elytron
APIs and using it to protected the Domain Management API using bearer tokens, which is
working nicely. However, using the same adapter, we must also be able to
"protect" the console and enable SSO. Which requires a different type of
authentication based on a redirection-based flow (Authorization Code Grant).
The XMLHttpRequest imposes some restrictions on how redirects can be handled, what
makes hard to handle 302 status code and redirect the user to another resource. That said,
I would like to propose a change to Keycloak OIDC adapters in order to better support
XMLHttpRequest requests:
- The adapter checks if the request contains a X-Requested-With=XMLHttpRequest. If
so, returns a response with a 403 status code and an Authorization header as follows:
Authorization:
as_uri="http://localhost:8081/auth/realms/elytron/protocol/openid-connect/auth?response_type=code&client_id=wildfly-cli&redirect_uri=http%3A%2F%2Flocalhost%3A9990%2Fmanagement&state=2%2F0e177443-e160-49d4-8937-6c7a17a49e62%24%23http%3A%2F%2Flocalhost%3A9990%2Fconsole%2FApp.html&login=true"
Where "as_uri" can be used by the client to actually redirect the user
to the authorization server / keycloak server.
The reason for a 403 and not a 401 is that some browsers will show a dialog if the
server responds with a 401. So we are basically telling the client that the request was
forbidden and that it must use "as_uri" to ask for authorization.
One important thing about this approach is that is up to server to tell to the client
where the authorization server is and how it should ask for authorization. The client is
pretty much decoupled from the authorization server and just need to know about how to
handle the Authorization header with the "as_uri" parameter.
Any thoughts ?
Regards.
Pedro Igor