【问题标题】:Azure OAuth with Cypress: Infinite Loop带有 Cypress 的 Azure OAuth:无限循环
【发布时间】:2021-02-18 13:54:20
【问题描述】:

尝试设置赛普拉斯以针对 Azure AD 测试使用 OAuth 的应用程序。我的login 命令定义如下:

Cypress.Commands.add('login', () => {
    return cy.request('POST', Cypress.env('AccessTokenUrl') +
        '?grant_type=' + Cypress.env('GrantType') +
        '&client_id=' + Cypress.env('ClientId') +
        '&client_secret=' + Cypress.env('ClientSecret'))
})

这是我在测试中所说的:

        cy.login().then(response => {
            expect(response.status).to.eq(200)
            expect(response.body).to.have.property('access_token')
            expect(response.body).to.have.property('token_type', 'Bearer')

            const {access_token, expires_in, id_token} = response.body
            cy.setCookie('access_token', access_token)
        })

        cy.visit('my-url')

验证通过。登录响应包含一个有效的令牌。但是,ct.visit 调用会因无限递归而失败,因为像 &iframe-request-id=[some uuid] 这样的参数会一遍又一遍地添加到 login.microsoftonline.com URL 中,直到最终返回 HTTP Error 414. The request URL is too long.

以下是 URL 的样子,为了清晰起见,部分信息已被编辑并采用了一些格式:

https://login.microsoftonline.com/
    [tenant-id]/oauth2/v2.0/authorize
    ?response_type=code
    &client_id=[client-id]
    &redirect_uri=[my-url]
    &scope=openid+profile+email+https%3A%2F%2Fgraph.microsoft.com%2Fuser.read
    &iframe-request-id=1a9fdcbd-6b9e-46c8-93e3-ce0edf62b600
    &iframe-request-id=b5b5cf2b-e0a6-4d92-9e55-cf32208ab900
    &iframe-request-id=8471e17f-1d36-48f7-8419-f54e14b3b100
    &iframe-request-id=56113dad-6029-4a37-9758-5828f93f0300
    &iframe-request-id=51c06224-98f1-4b83-a8f2-84f8dfe9aa00
    &iframe-request-id=09775645-505c-42e0-ac56-1335b5a7ba00
    &iframe-request-id=5c98158b-b202-41fe-9d65-8fbfe4e46500
    &[and-so-on]

我在网上找到了各种关于使用 Puppeteer 作为 Azure AD SSO 任务的建议,但没有一个适合我的目的。首先,他们试图解决我已经解决的实际获得令牌的问题。其次,它们依赖于呈现 HTML 表单的登录 URL,而 login.microsoftonline.com 不是这种情况。

你有什么建议?

更新:尝试不同的解决方案,我收到一个有趣的错误。 loginMS 命令:

import * as MSAL from '@azure/msal-browser'

Cypress.Commands.add('loginMS', () => {
    cy.request({
        method: 'POST',
        url: `https://login.microsoftonline.com/${Cypress.env('TenantId')}/oauth2/token`,
        form: true,
        body: {
            scope: Cypress.env('LoginScope'),
            client_id: Cypress.env('ClientId'),
            client_secret: Cypress.env('ClientSecret'),
            redirect_uri: Cypress.env('LoginRedirect'),
            grant_type: Cypress.env('GrantType'),
            username: Cypress.env('Username'),
            password: Cypress.env('Password'),
            response_type: 'code'
        }
    }).then(response => {
        console.log(response)
        window.localStorage.setItem(`msal.idtoken`, response.body.access_token);
        window.localStorage.setItem(`msal.client.info`, MSAL.clientInfo);
    })
})

错误是:

Failed to find a valid digest in the 'integrity' attribute for resource
'https://aadcdn.msauth.net/shared/1.0/content/js/OldConvergedLogin_PCore_Up8WrFIk8-TG_eqBz8MSlw2.js'
with computed SHA-256 integrity 'NxfOkHjbTYDy/EOknsK0PMOfym7iLRGY+yBShyznzx4='.
The resource has been blocked.

【问题讨论】:

  • 如果my-url 将您重定向到login.microsoftonline.com,难道仅仅设置access_token cookie 还不够吗?如果我理解正确,您需要在访问您的应用程序之前设置 所有 cookie 和/或需要登录的 localStorage,这样您就不会被重定向
  • 另外,您的baseUrl 是否设置为与my-url 相同的主机?或更笼统地说:在执行cy.setCookie 时,赛普拉斯跑步者是否与my-url 在同一个超级域上?否则 cookie 可能会设置在错误的域中
  • 谢谢!是的,同一个域。但你可能是对的,我没有设置正确的 cookie。调查这个......

标签: javascript oauth azure-active-directory cypress ui-testing


【解决方案1】:

这实际上取决于被测应用程序如何处理请求。但我猜你使用的是 adal 库。

https://mechanicalrock.github.io/2020/05/05/azure-ad-authentication-cypress.html 的帮助下,它在使用 adal v1 的 vuejs 应用程序中为我工作。

重要的是

   localStorage.setItem("adal.token.keys", `${Cypress.config("clientId")}|`);
    localStorage.setItem(`adal.access.token.key${Cypress.config("clientId")}`, ADALToken);
    localStorage.setItem(`adal.expiration.key${Cypress.config("clientId")}`, expiresOn);
    localStorage.setItem("adal.idtoken", ADALToken);

我实际上并没有向 azure 请求令牌,而是在使用被测应用程序时复制了我看到的 F12 工具作为我的令牌。

【讨论】:

    【解决方案2】:

    我通过为我的 Angular 应用程序创建以下赛普拉斯自定义命令来解决 Azure AD 登录问题:

    Cypress.Commands.add('login', () => {
      return cy
        .request({
          method: 'POST',
          url: `https://login.microsoftonline.com/${tenantId}/oauth2/token`,
          form: true,
          body: {
            grant_type: 'password',
            tenant: 'tenantId',
            client_id: 'clientId',
            client_secret: 'clientSecret',
            username: 'username',
            password: 'password',
            resource: 'clientId',
          },
        })
        .then((response) => {
          sessionStorage.setItem('access_token', response.body.access_token);
        });
    });

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-10-31
      • 2021-04-29
      • 1970-01-01
      • 2021-08-28
      • 2020-10-16
      • 2017-10-15
      • 1970-01-01
      相关资源
      最近更新 更多