I'm working on a web application that uses Angular for the frontend and a Spring Boot backend. We have implemented OAuth2 login via Microsoft's identity platform. Logging in works fine, but I've run into an issue when trying to implement the logout.
Here's what happens
- The user clicks 'Logout' in the Angular frontend.
- An HTTP request issent to a /logout endpoint in my Spring Cloud Gateway.
- The backend returns a 3XX redirect to Microsoft's logout URL, something like:
https://login.microsoftonline.com/12345-345-450c-be26-e9df0d55c2fb/oauth2/v2.0/logout?id_token_hint=...&post_logout_redirect_uri=http://localhost:9000
The Angular client tries to follow this URL and then I get a CORS error:
Access to XMLHttpRequest at 'https://login.microsoftonline.com/...' (redirected from 'http://localhost:9000/logout') from origin 'http://localhost:9000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
I don't understand why Angular is even trying to follow the redirect like a regular HTTP request. Isn't it supposed to be handled like a typical browser redirect?
Any idea what's going on here? And more importantly, how do I fix this?
Thank you in advance!
You should observe the response of your POST request and set
window.location.hrefwith the value of thelocationheader. Something like:Like that the request origin will be Keycloak (setting the window location to an external URI "exits" your Angular app to "enter" a new website).
With an OpenID Provider following the RP-Initiated Logout spec, this
logoutUriyou get from the gateway should point to your authorization serverend_session_endpointand contain the following request params:id_token_hintof the user to logout from the authorization serverpost_logout_redirect_uripointing back to your Angular appBut, to observe a
response, the HTTP status must be in2xxrange. The easiest way for that is probably to proxy an existingServerLogoutSuccessHandlerto change the response HTTP status. If your authorization server is fully compliant with RP-Initiated Logout (I have no sufficient experience withlogin.microsoftonline.comto be sure, but from what I can see from the logout URI you provide, it seems to be), using Spring'sOidcClientInitiatedServerLogoutSuccessHandleras delegate is a good option. Sample taken from there:The
post-logout-redirect-uriis expected in properties (should point to your Angular app, with a path accessible to anonymous users).