Hello, I know this subject has been beaten to death before, and I’ve spent a good portion of the last 24 hours trying to resolve this and drill down.
Here’s what I’ve got:
(I have to muddy the URLs because the forum software doesn’t allow new users to post more than 2 links)
Keycloak server running in container at
http://
foo:8080/
(minor obscuration), this has been working well for months.
Using the mozilla-django-oidc oidc authentication backend for Django.
Until now everything has worked find with pure Django, the browser does first party SSO renewal requests transparently.
Now I’m working on a React based client using openapi-client-axios to do the REST queries.
When I have the mozilla_django_oidc.middleware.SessionRefresh middleware enabled, it causes a session refresh every 15 minutes.
This middleware tries to detect XHR through Django’s (misguided) is_ajax() function, looking for these headers:
‘X-Requested-With’: ‘XMLHttpRequest’
If those headers are not present, the middleware simply generates a 302 redirect, which the axios based client tries to follow.
Normally you don’t want XHR following 302 redirects for authentication, but as a test when I redirect the browser window to the refresh_url, the auth framework ensures that I’m redirected back to my API get request, so the original data is fetched. I want this transparency in operation.
Try as I might, I cannot get Keycloak to emit the Access-Control-Allow-Origin header.
The XHR query has Origin set to this (this is minorly obscured, it’s not localhost and is being served from a django dev server):
http://
test-server:8081
Keycloak has “http://test-server:8081” (no trailing slash, just like the Origin header) set as the Web Origin.
I have withCredentials set to true as well, this is required so the cookies are furnished to KC when the 302 is made.
I’ve downloaded the KC source and scoured the Cors.java over and over, it clearly is supposed to create a Access-Control-Allow-Origin header.
The request is not a preflight request, it’s a GET that results in a 302 redirect back to the authentication endpoint; everything looks right in the headers and cookies, but I’m just not seeing results.
These are some of the request headers when the 302 redirect is fetched by the XHR client:
Host: foo:8080
Origin: h t t p://test-server:8081
Referer: h t t p://test-server:8081/
If Origin is set in the request headers, KC should respond with a Access-Control-Allow-Origin header if the Origin exists in the allowed origins:
if (allowedOrigins.contains(ACCESS_CONTROL_ALLOW_ORIGIN_WILDCARD)) {
response.getOutputHeaders().add(ACCESS_CONTROL_ALLOW_ORIGIN, ACCESS_CONTROL_ALLOW_ORIGIN_WILDCARD);
} else {
response.getOutputHeaders().add(ACCESS_CONTROL_ALLOW_ORIGIN, origin);
}
I just don’t understand why this code is never getting executed.
A hacky workaround is to just disable the middleware, but that would mean token idle timeouts don’t work and I would simply rely on receiving a 403 to indicate the end of session.