cypress: Azure AD B2C bad request when redirecting / using cy.origin()
Current behavior
We are trying to do a login with cypress, and we tried to use the “cy.origin” command. In local this worked well, as the domain of the login was a complete different one. Once we launched this in the pipeline, started complaining cypress that the “super domain” was the same one ( same error as this issue ).
As cypress identifies the login domain as the same domain, we assumed that then we could use the cypress commands directly in that page, so we did the following condition so that the code would be executed with origin or without depending of the environment:
const loginFunction = ({ username, password, emailInput, passwordInput, nextButton }) => {
cy.get(emailInput, { timeout: 5000 }).should('be.visible').type(username, { log: false });
cy.get(passwordInput).type(password, { log: false });
cy.get(nextButton).click();
};
// When localhost, we need the "origin command"
if (Cypress.config('baseUrl').includes('localhost')) {
cy.origin(
loginOrigin,
{
args: {
username: usernameForLogin,
password: passwordForLogin,
emailInput: LoginPage.emailInput,
passwordInput: LoginPage.passwordInput,
nextButton: LoginPage.nextButton
}
},
loginFunction
);
} else {
// When deployed, we don't need the "origin command"
loginFunction({
username: usernameForLogin,
password: passwordForLogin,
emailInput: LoginPage.emailInput,
passwordInput: LoginPage.passwordInput,
nextButton: LoginPage.nextButton
});
}
Problem comes that when we are doing the login in the CI ( not using the cy.origin ), one response of loading a page returns a 400 ( usually returns a 302 that page - With cy.origin or by normal usage of the login )
Same code executed in localhost, and using the cy.origin works just perfectly
Desired behavior
That the code works the same with or without origin
Test code to reproduce
Provided in the description
Cypress Version
12.5.1
Node version
18.13.0
Operating System
Windows 10 19042.2486
Debug Logs
No response
Other
SSO for the login used is Azure AD B2C
Frontend application is Angular with @azure/msal-angular
About this issue
- Original URL
- State: open
- Created a year ago
- Reactions: 6
- Comments: 59 (17 by maintainers)
+1 we really need this to be fixed
we have to bend over backwards to fix many of our tests and really can’t test for certain things when using workarounds mentioned
@AtofStryker Works like a charm =). Also checked it with a testcase where we test the complete password reset flow, which previously was failing and now works with the build from the branch.
@Xan0C This is really helpful. I have a feeling the cookie isn’t getting set in the browser in your case since its cross-origin / same-site, and the cookie jar logic doesn’t think it needs to be simulated since it is same-site, when in fact it does need to be simulated.
I wonder if we need to actually store the full origin string and then check to see if there is a sub domain in the simulation code so we still simulate cookies correctly on cross-origin / same-site requests from the AUT if the url of the AUT is an origin match.
could you try the changes in this branch and see if they also work for you? https://github.com/cypress-io/cypress/compare/same-origin-match-for-cookie-jar?expand=1
@mjhenkes similar on our side. We have an Angular app that uses angular-auth-oidc-client (oauth code flow) + Azure AD B2C.
We have our app available on: app.domain.xyz Our B2C login page is sitting on: login.domain.xyz
Everything works fine when we run Cypress and it tests the app running on localhost (and using cy.origin):
When we run tests with the app that is available on app.domain.xyz and we remove cy.origin (because of the same super domain Cypress error):
I believe that it’s a similar case to @mmonteiroc but we have a little different B2C configuration. When we wrap the actions on the B2C login page with cy.origin (inside cy.session) everything works fine. But when we remove cy.origin, B2C fails.
its currently building on https://github.com/cypress-io/cypress/commit/c7af4ad735758cbb9451ae34f080f9b52a3e7872
Hi @AtofStryker! Thanks for the fix! Would it be possible to have a permanent fix for this issue? It is quite unpleasant that once at 60 days (when pre-release build is not available anymore) to have our tests fail in the pipeline and be forced to downgrade to an older version - 10.9.0 - (which is the last working version) until a new pre-release build is available. Do you think you can help us? Thank you!
We have the same problem in our use case: Using cy.origin works when the login domain is under a different origin e.g. test.testlogin.com and application is under e.g. test.myapp.com On our prod system we have login.myapp.com and myapp.com and therefore can not use cy.origin. We did a workaround to simply repeat the failing bad request which does use the corrected cookie on the second try:
Without cy.origin the set-cookie header does not get applied correctly between 2 consecutive requests. I think this issue is related #26040 #25841
After some digging yesterday evening I’ve found that the response-middleware behaves differently if the login domain uses a different origin.
https://github.com/cypress-io/cypress/blob/9517def6b7a95a975b5eadc9454ff0541c8eca0e/packages/proxy/lib/http/response-middleware.ts#L432-L438
Removing those lines and therefore saving the cookie in the CookieJar solves the issue for our use case. I am not really sure why exactly this helps so at this point i am just guessing, it looks like “though-cookie” is responsible to sync the cookies between requests? And when using the same origin the call to https://github.com/cypress-io/cypress/blob/9517def6b7a95a975b5eadc9454ff0541c8eca0e/packages/proxy/lib/http/response-middleware.ts#L456 does not happen.
https://github.com/cypress-io/cypress/blob/9517def6b7a95a975b5eadc9454ff0541c8eca0e/packages/proxy/lib/http/util/cookies.ts#L240 https://github.com/cypress-io/cypress/blob/9517def6b7a95a975b5eadc9454ff0541c8eca0e/packages/server/lib/util/cookies.ts#L122
@mjhenkes @AtofStryker I just have done what @mjhenkes asked me, and for what I see, the requests are almost identical between both domains ( deployed / localhost ) The only difference, is the cookie itself, as is encoded depending on the timing, etc… but the same amount of cookies are sent, same payload, etc
I’ve the exact same setup and problem as @sebastiandenis: my Angular app is hosted on
app.domain.com
, my B2C login page is hosted onlogin.domain.com
and MSAL returns error AADB2C90255. Also, upgrading Cypress to 12.7.0 or enabling experimentalSkipDomainInjection does not work…Same behaviour in our side @flotwig @sebastiandenis
We face the issue only when using same “root domain” ( which is our case so we need to keep it like so ).
When we are outside of the same domain ( localhost for instance ), and we have to use cy.origin works perfectly fine ! So same question as @sebastiandenis, can we force the usage of cy.origin ?? Or maybe tell cypress how to consider a different origin?
/ping @mjhenkes as I see that @flotwig removed it self and added you 😃
@mmonteiroc we have encountered a similar issue. We also use Azure AD B2C.
Everything works fine for localhost and cy.origin wrapped around B2C SSO page. But when we open the app on an actual domain for example app.domain.xyz and we have our B2C login page on login.domain.xyz, we can’t use cy.origin (the same super domain) and we get the AADB2C90255 B2C error (_The claims exchange specified in technical profile ‘{0}’ did not complete as expected. You might want to try starting your session over from the beginning).
I have tried almost everything, still without success 😕