kubernetesazure-active-directorycorsambassador

CORS issue with Ambassador accessing AzureAD


What I have:
a WebApp (ReactJs), an Api (Spring-Boot) each running on a single pod in Kubernetes and an Ambassador wrapped around these (WebApp and Api are having the same domain), my Identity Provider is Azure AD. In Azure AD I configured a Web-redirect URI for my WebApp.

My Problem:
Accessing the WebApp the first time directs me to microsoft login screen, after entering my credentials I get redirected to my WebApp. When I let the browser tab with my WebApp open, don't use it for 1/1,5 hours and go back and click a button in my WebApp (which triggers a call to my API) I get this CORS error:

Access to XMLHttpRequest at 
'https://login.microsoftonline.com/{tenantId}/oauth2/v2.0/authorize?client_id={clientId}&redirect_uri={ambassador-redirectUri}&response_type=code&scope=openid&state={state}'
(redirected from 'https://mydomainname/api/webapp/people') from origin 'https://mydomainname' 
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

Obviously my access token expired and my application tries to reach the identity provider to get a new one, but my Idp does not allow this.

I followed these steps for setting up Ambassador with Azure AD: https://www.getambassador.io/docs/edge-stack/latest/howtos/sso/azure/ but it seems like I missed something. Anyone a clue what it could be?


Solution

  • The logon flow via the https://login.microsoftonline.com page that you initially experience works only because the URL you want to access (that is, the URL of your WebApp) is in the browser's address bar, hence is used to load a page into the browser tab.

    You cannot repeat the same logon flow for an XMLHttpRequest, because this has no address bar and browser tab. Even if the redirection were allowed, the Javascript code of your WebApp could not do anything with the HTML response it would receive from https://login.microsoftonline.com.

    If one of your API endpoints (such as https://mydomainname/api/webapp/people) detects that the session is expired, it should not respond with a redirection to https://login.microsoftonline.com, but rather with a specific error code like

    HTTP/1.1 403 Forbidden
    Content-Type: application/json
    
    {"error": "Session expired",
     "redirect": "https://mydomainname/login"}
    

    and when your WebApp receives this, it should present a button to the user labeled

    Session expired, press to login again

    and pressing this button should open https://mydomainname/login in a new browser tab, which will then automatically redirect to https://login.microsoftonline.com and so on. After the user has closed that tab again, your WebApp can repeat the API request.