Cypress - End-to-End Testing: OKTA Authentication with MFA
Abstract
This article provides a step-by-step guide on setting up OKTA authentication with Multi-Factor Authentication (MFA) in Cypress End-to-End (E2E) testing.
The official Cypress documentation outlines an approach for programmatic OKTA authentication.
Why authenticate programmatically?
Typically, logging in a user within your app by authenticating via a third-party provider requires visiting login pages hosted on a different domain. Since each Cypress test is limited to visiting domains of the same origin, we can subvert visiting and testing third-party login pages by programmatically interacting with the third-party authentication API to login a user.
But for several cases the OKTA account requires MFA (Multi-Factor Authentication) due to company/organization security policy. This can create challenges in the login process during automated testing.
To pass the MFA auth in your test, we need to:
- Consult your security team to determine if MFA can be temporarily disabled for test accounts.
- If MFA cannot be disabled, configure it to use Security Questions (view all OKTA MFA options here). This allows automation by providing predefined answers in test cases.
- Fetch the stateToken with
UserName/Password
- Submit the MFA Answers together with stateToken
- Fetch the sessionToken
- Set sessionToken via okta lib
- Get the ID Token + Access Token
The key step is to get the sessionToken with MFA answers (see OKTA API here)
Lets see how I do the command:
Cypress.Commands.add('loginByOktaApi', (username = 'testaccount', password = 'testaccount_1234') => { /** * Visit the homepage before initiating OKTA authentication to prevent postMessage errors * @see https://github.com/cypress-io/cypress/issues/16310#issuecomment-1279523540 */ cy.visit('https://localhost:3000'); return cy .request({ method: 'POST', url: `https://${process.env.OKTA_DOMAIN}/api/v1/authn`, body: { username, password } }) .then(({ body }) => { const user = body._embedded.user; const stateToken = body.stateToken; const factorId = body._embedded.factors[0].id; cy.request({ method: 'POST', url: `https://${process.env.OKTA_DOMAIN}/api/v1/authn/factors/${factorId}/verify`, body: { stateToken, answer: process.env.OKTA_MFA_ANSWER } }).then(({ body }) => { const sessionToken = body.sessionToken; const config = { issuer: `https://${process.env.OKTA_DOMAIN}/oauth2/default`, clientId: process.env.OKTA_CLIENT_ID, redirectUri: 'https://localhost:3000/auth/callback', scope: ['openid', 'email', 'profile'] }; const authClient = new OktaAuth(config); return authClient.token.getWithoutPrompt({ sessionToken }).then(({ tokens }) => { window.localStorage.setItem('okta-token-storage', JSON.stringify(tokens)); }); }); }); });
Consider using cy.session()
to persist authentication across tests, reducing login overhead. Note that this is still an experimental feature as of December 2022, and configuration adjustments may be required.
关于本文
文章标题 | Cypress - End-to-End Testing: OKTA Authentication with MFA |
发布日期 | 2022-12-02 |
文章分类 | Tech |
相关标签 | #Datatable #Excel #JS |
最近文章
留言板
PLACE_HOLDER
PLACE_HOLDER
PLACE_HOLDER
PLACE_HOLDER
PLACE_HOLDER
PLACE_HOLDER
PLACE_HOLDER
PLACE_HOLDER