0% found this document useful (0 votes)
78 views7 pages

Cypress - IdentityServer - Cracking The OIDC Protocol - by Dev Shah - Tenets - Medium

The document describes a solution for using Cypress to programmatically log into an application that uses OpenID Connect (OIDC) authentication with IdentityServer4. It involves making a GET request to fetch the login page HTML, extracting the CSRF token, and using it to log in via a POST request to the /account/login endpoint. This sets the session cookies and allows Cypress to visit pages and behave as an authenticated user. The workaround cracks OIDC authentication without violating security by still requiring valid credentials.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
78 views7 pages

Cypress - IdentityServer - Cracking The OIDC Protocol - by Dev Shah - Tenets - Medium

The document describes a solution for using Cypress to programmatically log into an application that uses OpenID Connect (OIDC) authentication with IdentityServer4. It involves making a GET request to fetch the login page HTML, extracting the CSRF token, and using it to log in via a POST request to the /account/login endpoint. This sets the session cookies and allows Cypress to visit pages and behave as an authenticated user. The workaround cracks OIDC authentication without violating security by still requiring valid credentials.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 7

28/12/2020 Cypress <> IdentityServer: Cracking the OIDC protocol | by Dev Shah | Tenets | Medium

You have 2 free member-only stories left this month. Sign up for Medium and get an extra one

Cypress <> IdentityServer: Cracking the OIDC


protocol
Dev Shah
Oct 9 · 4 min read

Trying to login to OIDC flow with Cypress? Don’t break your head no more!

I have spent considerable amount of time researching ways to make Cypress work with
the OpenID Connect (OIDC) authentication flow. OIDC is a layer on top of OAuth 2.0.

In simpler words, it’s nearly impossible for Cypress to programmatically login to an


application which relies on OIDC. Let me save you some time and say 99% of your
searches won’t give a workable solution. It’s hard for a reason.

https://medium.com/tenets/cypress-identityserver4-cracking-the-oidc-protocol-6da42289731f 1/7
28/12/2020 Cypress <> IdentityServer: Cracking the OIDC protocol | by Dev Shah | Tenets | Medium

Every implementation of OAuth 2.0 will have a different solution based on the minor
differences in the authentication flows. This article will explain a solution for ASP.NET
Core’s framework of OIDC and OAuth 2.0 aka IdentityServer4.

Before diving into the solution for logging in to IdentityServer4, it’s important to
understand basic definitions and how the authentication flow works.

Some Basic Definitions


OAuth 2.0

It’s the industry-standard protocol for authorization. OAuth 2.0 focuses on client
developer simplicity while providing specific authorization flows for web applications,
desktop applications, mobile phones etc

OpenID Connect (OIDC)

OpenID Connect is a simple identity layer on top of the OAuth 2.0 protocol. It allows
Clients to verify the identity of the End-User based on the authentication performed by an
Authorization Server, as well as to obtain basic profile information about the End-User in
an interoperable and REST-like manner.

IdentityServer4

IdentityServer4 is an OpenID Connect and OAuth 2.0 framework for ASP.NET Core.
Basically Authentication as a Service if you will.

How does IdentityServer4 work?

https://medium.com/tenets/cypress-identityserver4-cracking-the-oidc-protocol-6da42289731f 2/7
28/12/2020 Cypress <> IdentityServer: Cracking the OIDC protocol | by Dev Shah | Tenets | Medium

Source

The above is a high level flow of how a generic OIDC authentication flow works.

1. User signs in with valid credentials

2. User gets redirected to callback URI for validation and session cookie is set

3. User requests a bearer token based on authorization code & credentials

4. Successfully logs in once token is returned

Where does Cypress break?


The issue with Cypress is when the browser redirects to another domain URI for
authentication it breaks. In other words at Step 2.

The whole point of OAuth 2.0 and its various implementations are to restrict anyone
from programmatically logging into a system. Especially bots and automated test
scripts.

Why does Cypress break?


Simply because these redirect URIs have a strict Content-Security-Policy (CSP)
directive where the iframe property `ancestors` is set to `none`.

Since Cypress works inside an iframe it breaks because of the CSP directive.

https://medium.com/tenets/cypress-identityserver4-cracking-the-oidc-protocol-6da42289731f 3/7
28/12/2020 Cypress <> IdentityServer: Cracking the OIDC protocol | by Dev Shah | Tenets | Medium

I will attempt to explain the solution by breaking it down into 3 simple steps.

Why we need to solve OAuth’s login problem?

If you don’t, you can’t login programmatically through APIs (because its
OAuth’s whole purpose) nor can you login through UI because the OAuth’s
URL redirect breaks Cypress.
Ultimately, your tests can’t login to your application which is a deal breaker.

Solution
I was able to find a solution for programmatically logging in using the dynamically
generated CSRF token hidden on the login page.

A CSRF token is a unique, secret, unpredictable value that is generated by the server-side
application and transmitted to the client in such a way that it is included in a subsequent
HTTP request made by the client. When the later request is made, the server-side
application validates that the request includes the expected token and rejects the request if
the token is missing or invalid.

Step 1:
Harness the power of cy.request() and send a GET request to the third party/server
website. If you do a normal cy.visit() to the site it will break Cypress because of the
CSP directive set on such authentication pages.

cy.request('GET', thirdPartyLoginPageUrl);

Step 2:
After getting the response from Step 1, fetch the hidden CSRF token which is
embedded on the third party’s HTML by the server.

const htmlDocument = document.createElement('html');

htmlDocument.innerHTML = response.body;
const loginForm = htmlDocument.getElementsByTagName('form')[0];
const requestVerificationToken =
loginForm.elements.__RequestVerificationToken.value;

https://medium.com/tenets/cypress-identityserver4-cracking-the-oidc-protocol-6da42289731f 4/7
28/12/2020 Cypress <> IdentityServer: Cracking the OIDC protocol | by Dev Shah | Tenets | Medium

You need requestVerificationToken to send a valid login request to IdentityServer.


Without the silver bullet (CSRF token), it will not work as it is auto-generated
dynamically by the server every time a user hits the page.

Step 3:
Use the CSRF token from Step 2 and login to the application through the
/account/login endpoint of IdentityServer4 with valid credentials.

When a successful response is returned, the response headers set session cookies for
the user.

Step 4:
Next, cy.visit() to your home page and Voila! You should be logged in.

All put together —

1 Cypress.Commands.add('IdentityServerAPILogin', (email, password) => {


2 cy.server();
3 cy.request('GET', thirdPartyServerUrl).then(response => {
4 // Parses the html response to fetch the CSRF token
5 const htmlDocument = document.createElement('html');
6 htmlDocument.innerHTML = response.body;
7 const loginForm = htmlDocument.getElementsByTagName('form')[0];
8 const requestVerificationToken = loginForm.elements.__RequestVerificationToken.valu
9
10 // Sends a valid request to thirdPartyServerUrl which sets the session cookies on a
11 cy.request({
12 method: 'POST',
13 url: thirdPartyServerUrl + '/account/login',
14 followRedirect: false,
15 form: true,
16 body: {
17 ReturnUrl: '',
18 Email: email,
19 Password: password,
20 __RequestVerificationToken: requestVerificationToken
21 }
22 });
23 });
24 });

cypress_oidc.js hosted with ❤ by GitHub view raw

Solution to your OIDC login headache

https://medium.com/tenets/cypress-identityserver4-cracking-the-oidc-protocol-6da42289731f 5/7
28/12/2020 Cypress <> IdentityServer: Cracking the OIDC protocol | by Dev Shah | Tenets | Medium

End notes
After a long exhausting search, trial and errors I found the above solution to be
effective and working 100% of the time for IdentityServer4.

In case this solution doesn’t help with your use case, try implementing custom
extension grants exclusively for Cypress client in IdentityServer.

Last but not the least, if you’re wondering this workaround can compromise security in
any way then you’re being paranoid (which is good). However, remember you can only
successfully login if you know the credentials.

That’s it folks! Hope the CSRF token workaround helps your purpose 😄
If you liked this article, you will find this interesting:

4 key results from migrating Selenium framework to


Cypress
Yeah, we all probably know why Cypress is a really great testing tool.
If you’re starting something then I’m sure…
medium.com

Sign up for Top Stories


By Tenets

A newsletter that delivers Tenet's most impactful stories to your inbox once a week. Take a look

Your email

Get this newsletter

By signing up, you will create a Medium account if you don’t already have one. Review our Privacy Policy for more information
about our privacy practices.

https://medium.com/tenets/cypress-identityserver4-cracking-the-oidc-protocol-6da42289731f 6/7
28/12/2020 Cypress <> IdentityServer: Cracking the OIDC protocol | by Dev Shah | Tenets | Medium

Cypress Oauth Testing Learning Technology

About Help Legal

Get the Medium app

https://medium.com/tenets/cypress-identityserver4-cracking-the-oidc-protocol-6da42289731f 7/7

You might also like