CORS issue with Ambassador accessing AzureAD - kubernetes

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?

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.

Related

Logout from Keycloak does not logout Active Directory User

We have integrated KeyCloak server with Azure Active Directory as Identity Provider for SSO Login.
Log-in is working fine. However we facing problem with log-out, When user logs-out from web application, from our backend server side code we are making REST call to Keycloak server for below API.
https://keycloaktest:8443/auth/realms/<realmName>/protocol/openid-connect/logout
for this REST call we are getting 204 status code as response.
However when User tries to log-in in application again from browser it does not ask to enter credentials (active directory credentials).
In order to log-out User. We have access below URL
https://portal.azure.us/#home
and click log-out there.
https://portal.azure.us/Account/SignOut
Is there anyway to achieve this in backend i.e. when User clicks logout from browser
Just ran across this myself. The answer provided here: Logout user via Keycloak REST API doesn't work worked for me. Try adding client_id and refresh_token to your /logout request.

FARM Stack - SameSite="none"; Secure can't be set on logout API call

I have a backend based on the FARM stack by MongoDB (https://www.mongodb.com/developer/how-to/FARM-Stack-FastAPI-React-MongoDB/), with authentication (https://www.mongodb.com/developer/how-to/FARM-Stack-Authentication/).
Authentication works as it should on Fast API docs and Postman. When executing a successful user log in, it automatically sets the JWT HttpOnly cookie on the browser. When logged in, it removes the cookie again on logout.
When calling /login on front-end, it said following error in the Network tab:
As the error states, I managed to fix this by setting the cookie options on the backend as following, and I could afterwards successfully login from a react front-end:
Unfortunately, this doesn't work for the /logout call. This error occurs again, as the SET-COOKIE header tries to set an empty cookie, yet it can't due to the cookie having a SAMESITE="lax" as default, but I don't see a way to find out how to configure it for the /logout call in the backend.
My front-end /logout call looks like this, the same as /login:
How do I configure my front-end/back-end, so my front-end can successfully delete my cookie and successfully log out?

Jenkins Embeddable Build Status plugin gets redirected due to SSO

I'm trying to add Jenkins build status using the Embeddable Build Status plugin onto Github README.md file. I have SSO for Github and Jenkins and I assumed it will have the login info in the browser cookies or wherever it stored that info but looks like it doesn't work that way (The same URL works and picks up SSO info and doesn't prompt me when I open it from a browser. It just doesn't like Github pulling that info)
I see a 302 redirect on the Jenkins status badge link that is getting redirected to the SSO page and is expecting JS to be enabled for it to work which isn't possible on a Github README.md page (Even if that was possible I would not see a login prompt)
The console has a warning for this redirected URL request as Cross-Origin Read Blocking (CORB) blocked cross-origin response <the-URL> with MIME type text/html. See https://www.chromestatus.com/feature/5629709824032768 for more details.
I also set the Jenkins config to ViewStatus for anonymous uses based on JENKINS-17798 and I'm using the unprotected link but it still needs SSO
Is there a way I can fix this?
Read this first. Cors-Filter Plugin for Jenkins.
Before you go debugging. First make sure that CORS is enabled for the Jenkins instance. You can go to configure system in jenkins and then to CORS Filter:
A very short summary.
Access-Control-Allow-Origins - List domains that may access the jenkins url.
Access-Control-Allow-Headers - Headers that can be used to make actual request
Access-Control-Expose-Headers - List of headers browser are allowed to access.
Whenever one tries to go authenticating from one domain to another it usually gets redirected in jenkins if CORS Filter is not active. So try this first.

Understanding HTTP Session security mechanism in JHipster

I am trying to figure out how the JHipster uses HTTP session for securing application and logging the user.
So far I’ve managed to understand the flow like this:
1) on landing page home.component sends request to api/account
with session cookies (if there are ones)
if there is a valid session >> uses credentials from stored cookies and then login the user
if no >> backend server responds HTTP 401 and sends XSRF cookie in response
As I understand responsible for this is Spring Security
2) when there was no acitve session we can fill the login form and log in
that sends request to api/authentication (XSRF cookie from step 1 required)
if all ok >> responds HTTP 200 and sends new XSRF cookie
if no >> HTTP 403 and sends new XSRF cookie
3) when step 2 is successful then frontend sends credentials from login form to api/account
one more time Spring Security checks XSRF cookie value (from step 2 this time)
if all ok >> business logic for log in the user is invoked
But in all these steps we need to intercept the cookies sent by backend and send them back to be able to pass through CSRF protection. Which part of JHipster project is responsible for that? Does it use webpack/browsersync or there is some Angular code created by JHipster which I am missing?
EDIT
My problem appeared when I've made a lot of changes to generated project as I want to use custom templates/styling and the services generated by JHipster. I've linked the templates with jhipster services.
When I try to log in the user I get in spring console output like this:
Forbidden: Invalid CSRF Token 'null' was found on the request parameter '_csrf' or header 'X-XSRF-TOKEN'
From previuos request to api/authentication I get response with
Set-Cookie: XSRF-TOKEN=a129cb47-ec96-47be-aaae-69f90848c466; path=/
in browser network.
So it sets the cookie with wrong name I guess. I've change the cookie name manually in browser to: X-XSRF-TOKEN and resent the request. The new error looks like this:
Forbidden: Could not verify the provided CSRF token because your session was not found.
I don't understand the flow enough so I can't spot where is the problem. Maybe I've messed up and maybe there is some code generated by JHipster which is responsible for that. There are some classes in JHipster Angular frontend like StateStorageService. Do they take part in my problem or they are irrelevant to that issue?
I was facing the same issue while connecting a mobile app to the backend of spring boot. So basically angular has a method under the core functionalities called interceptors. Under the interceptors the response is gather and X-XSRF-TOKEN is captured and updated in Browser Cookie or in my case Ionic Local Storage as Cookie.

IBM Weather REST API 401 Keep getting CORS issues when access

I am getting a 401 and some cross domain issues when trying to access IBM Weather REST API from either client (browser) or server.
If I generate a URL and try and access it directly from a browser (eg paste it in it works fine and the JSON weather report is returned).
When I try and run the Javascript HTTP request from either the browser or server it seems like it's only allowed to run from an ibm.com domain.
Failed to load https://twcservice.au-syd.mybluemix.net/api/weather/v1/geocode/-33.00/151.00/forecast/daily/7day.json?units=m&language=en-US: The 'Access-Control-Allow-Origin' header contains multiple values 'https://*.ibm.com, https://*.ibmcloud.com', but only one is allowed. Origin 'http://localhost:3000' is therefore not allowed access.
I am using the free service on Bluemix. Is this restricted to only run via a Bluemix server? or are there some options I can pass when I create the service on Bluemix
Note, when I make the request I am using the credentials supplied via the Bluemix console. Again, this works via the browser URL bar, but not via code.
Update/More info: if I hit past the URL above into the browser (with creds) it works as above, then if hit it via the web app in the same session it works.
Hmmm. So the IBM server is sending the following response header:
Access-Control-Allow-Origin: https://*.ibm.com, https://*.ibmcloud.com
That's an invalid response from IBM. Unfortunately, I think your only option is to complain to IBM, and convince them to
Return a valid Access-Control-Allow-Origin response header (with only one value)
Allow people outside of IBM to access it
Without that, I fear you're out of luck.