问题描述
我对Cypress和Azure AD还是陌生的,但是我一直遵循here中描述的步骤在使用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);
运行此命令时,将返回访问令牌。当我在正常浏览器请求之后检查本地存储时,它具有更多字段,例如msal.client.info
(上面代码中的authInfo
值也应包含此值),但我不知道从何处获取此信息。
最终结果是POST请求似乎成功返回,但是赛普拉斯测试仍然认为该用户未经身份验证。
如果CanActivate
返回有效用户,则现有应用程序将实现MsalService.getUser()
服务。如何使该服务确信我的赛普拉斯用户有效?
更新:
在对本地存储值进行了一些试验之后,看起来只需两个值即可通过登录:
msal.idtoken
msal.client.info
我已经拥有的第一个;第二个我不确定,但是出现每次都会返回相同的值。现在,我正在将该值硬编码到我的测试中,并且似乎有些起作用:
then(response => {
const Token = response.body.access_token;
window.localStorage.setItem(`msal.idtoken`,Token);
window.localStorage.setItem(`msal.client.info`,`{my_hard_coded_value}`);
});
现在唯一的小问题是MsalService.getUser()
方法返回的值与应用程序期望的值略有不同(例如,缺少displayableId
和name
; idToken.azp
和{{ 1}}是新的)。我将进一步调查...
解决方法
我要感谢您为弄清楚在使用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);
}
我能够使用您的代码,并仅添加了import * as MSAL from "@azure/msal-browser"
和window.localStorage.setItem(`msal.client.info`,MSAL.clientInfo);
对我来说就像一个魅力!
,这个解决方案让我成功请求,但我仍然无法通过我的应用程序的登录屏幕,经过一些搜索,我找到了这个很棒的教程视频,让我通过了登录屏幕!我正在使用 msal-react
和 msal-browser
npm 包。
https://www.youtube.com/watch?v=OZh5RmCztrU
代码的回购在这里:
https://github.com/juunas11/AzureAdUiTestAutomation/tree/main/UiTestAutomation.Cypress/cypress