带有 Azure AD (MSAL) 的赛普拉斯

Mic*_*lin 6 azure-active-directory angular angular-router-guards cypress

我是 Cypress 和 Azure AD 的新手,但我一直按照此处描述的步骤使用 Azure AD 的现有 Angular 应用程序上创建 Cypress 测试。它提到他们使用 ADAL,但我们的应用程序使用 MSAL,它说应该是相似的。但是,我正在努力让它发挥作用。到目前为止,这是我的登录功能:

const tenant = 'https://login.microsoftonline.com/{my_tenant_id}/';
const tenantUrl = `${tenant}oauth2/token`;
const clientId = '{my_app_id}';
const clientSecret = '{my_secret}';
const azureResource = 'api://{my_app_id}';
const knownClientApplicationId = '{client_application_id_from_manifest}';
const userId = '{user_identifier}';
    
export function login() {
    cy.request({
        method: 'POST',
        url: tenantUrl,
        form: true,
        body: {
            grant_type: 'client_credentials',
            client_id: clientId,
            client_secret: clientSecret,
            resource: azureResource
        }
    }).then(response => {
        const Token = response.body.access_token;
        const ExpiresOn = response.body.expires_on;
        const key = `{"authority":"${tenant}","clientId":"${knownClientApplicationId}","scopes":${knownClientApplicationId},"userIdentifier":${userId}}`;
        const authInfo = `{"accessToken":"${Token}","idToken":"${Token}","expiresIn":${ExpiresOn}}`;
    
        window.localStorage.setItem(`msal.idtoken`, Token);
        window.localStorage.setItem(key, authInfo);
}
Cypress.Commands.add('login', login);
Run Code Online (Sandbox Code Playgroud)

当我运行它时,会返回一个访问令牌。当我在正常的浏览器请求后检查本地存储时,它有更多的字段,例如msal.client.infoauthInfo上面代码中的值也应该包含这个值),但我不知道从哪里获取这些信息。

最终结果是 POST 请求似乎成功返回,但 Cypress 测试仍然认为用户未经身份验证。

现有应用程序实现了一项CanActivate服务,如果MsalService.getUser()返回有效用户,则该服务将通过。我怎样才能让这个服务相信我的 Cypress 用户是有效的?

更新:

在对本地存储值进行一些实验后,看起来只需要两个值就可以通过登录:

msal.idtoken
msal.client.info
Run Code Online (Sandbox Code Playgroud)

第一个我已经有了;第二个我不确定,但它似乎每次都返回相同的值。现在,我正在将该值硬编码到我的测试中,它似乎有点工作:

msal.idtoken
msal.client.info
Run Code Online (Sandbox Code Playgroud)

现在唯一的小问题是该MsalService.getUser()方法返回的值与应用程序预期的值略有不同(例如displayableIdname缺少;idToken.azp并且idToken.azpacr是新的)。我会进一步调查...

小智 2

我要感谢您为确定使用 MSAL 时要设置哪些变量所做的所有基础工作!我想我可以帮助弄清楚 clientInfo 来自哪里。它看起来像是从 clientId 生成的,这解释了为什么它总是相同的值:

static createClientInfoFromIdToken(idToken:IdToken, authority: string): ClientInfo {
        const clientInfo = {
            uid: idToken.subject, 
            utid: ""
        };

        return new ClientInfo(CryptoUtils.base64Encode(JSON.stringify(clientInfo)), authority);
    }
Run Code Online (Sandbox Code Playgroud)

请参阅此处的源代码:https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/70b87bcd27bfe67789c92b9bc046b45733f490ed/lib/msal-core/src/ClientInfo.ts

我能够使用你的代码,只需添加import * as MSAL from "@azure/msal-browser"window.localStorage.setItem(`msal.client.info`, MSAL.clientInfo);

对我来说就像一个魅力!

  • 这看起来确实很有希望,但如果您使用的是 MSAL v2,那么您就不走运了。这些本地存储密钥在那里都无效。现在,他们拥有“{homeAccountId}-login.windows.net-{tokentype}-{clientid}-{tenentid}-{scope}”格式的多个密钥。 (2认同)