Keycloak does not respect redirect_uri on 302 response

I’ve been trying to figure out why keycloak would return the wrong location: header when the correct redirect_uri is passed in the request. This results in a 404 on the keycloak side because no endpoint exists at auth.example.net/api/auth. That endpoint only exists on ops.example.net/api/auth.

This is a nextjs/react/mui project that’s using keycloak for authentication.

Could this be a plugin missing from my docker deployment of quay.io/keycloak:latest? (v21.1.1 as of writing)
Other than proxy=edge behind an IIS 10 reverse proxy, it’s a fairly standard setup.

Navigating to ops.example.net/api/auth/callback/keycloak works after getting the 404 page. So this appears to be an issue with keycloak and the app residing on two different subdomains?

These are the headers that keep coming back:

REQUEST

Request URL: https://auth.example.net/realms/examplenet/protocol/openid-connect/auth?client_id=example-main&scope=openid%20email%20profile&response_type=code&redirect_uri=https%3A%2F%2Fops.example.net%2Fapi%2Fauth%2Fcallback%2Fkeycloak&state=<state>&code_challenge=<cc>&code_challenge_method=S256
Request Method: GET
Status Code: 302 
Remote Address: <home_public_IPv4>:443
Referrer Policy: strict-origin-when-cross-origin
RESPONSE

cache-control: no-store, must-revalidate, max-age=0
content-length: 0
date: Wed, 10 May 2023 05:04:14 GMT
location: https://auth.example.net/api/auth/callback/keycloak?state=<state>&session_state=<session guid>&code=<codeguid>
p3p: CP="This is not a P3P policy!"
referrer-policy: no-referrer
...

This is really unexpected, as after a successful login Keycloak will redirect the browser to the url in redirect_uri parameter, given that this url is pre-registered for the client.

A redirect_uri not registered would result in a bad request response.

Maybe there is something else redirecting the browser from http://ops.example.net/api/auth back to https://auth.example.net/api/auth?

If you follow the authentication flow in the browser console, you can check that.

What if, say, something in http://ops.example.net/api/auth or in front of it is redirecting the browser when some query parameter is present. Like, if you try going directly to https://ops.example.net/api/auth/callback/keycloak?state=foo&session_state=foo&code=foo maybe it’s redirecting, but now when you call it plainly with https://ops.example.net/api/auth/callback/keycloak?

1 Like

Given that IIS handles headers in a rather esoteric way, I would be willing to bet it’s interpreting one of the headers wrong. I’ll run wireshark on the internal side with the keycloak docker container to see if I can catch it changing the location value.

Other ideas I have may have to do with Server Name Indication, but I think that’s unlikely.

Edit:
I’ve confirmed that this is IIS modifying the 302 location header incorrectly. When I figure out the solution with IIS, I’ll post it so that it’s searchable by search engines.

It’s amazing what you can figure out after having someone else to talk through it.
Anyways, there’s an option in IIS that must be changed.

Thanks to this post on stack exchange (iis - Prevent ARR with UrlRewrite from re-writing Location header for a 302 redirect - Server Fault)

I already had “preserveHostHeader=True” but “reverseRewriteHostInResponseHeaders” was also set to true, changing this to False fixed the issue.

1 Like