运行 Angular e2e 测试时如何禁用或绕过 MSAL 身份验证?
How to disable or bypass MSAL authentication when running Angular e2e tests?
我想为我的 Angular 应用程序设置一些端到端测试,这需要使用 MSAL 库对某些下游服务进行身份验证。当我尝试在本地 运行 我的 e2e 测试时,MSAL 库强制我使用 username/password 进行身份验证。
这是一个问题,因为我们的 CI/CD 端到端测试不应该有任何人为干预;因此我正在寻找一种方法来绕过 MSAL 身份验证或设置服务帐户进行登录。不幸的是,Angular(尤其是在端到端测试方面)的 MSAL 相关文档并不多,但这似乎是其他人可能 运行 遇到的一个常见问题。
我已尝试从我们的 app.module.ts 文件中禁用 MsalModule,但当我尝试 运行 应用程序时仍然提示我登录。我还看到一些文章试图以编程方式登录,但这对我们不起作用,因为 MSAL 在技术上不是我们能够接触的 Angular 组件。
app.module.ts:
@NgModule({
...
imports: [
...
MsalModule.forRoot({
clientID: '<client_id>',
authority: <microsoft_authority_url>,
validateAuthority: true,
redirectUri: "http://localhost:4200/",
cacheLocation : "localStorage",
postLogoutRedirectUri: "http://localhost:4200/",
navigateToLoginRequestUrl: true,
popUp: true,
consentScopes: [ "user.read"],
unprotectedResources: ["https://www.microsoft.com/en-us/"],
protectedResourceMap: protectedResourceMap,
logger: loggerCallback,
correlationId: '1234',
level: LogLevel.Info,
piiLoggingEnabled: true
})
],
entryComponents: [SaveDialogComponent,
GenericDialog, MassChangeDialogComponent],
providers: [TitleCasePipe,
{provide: HTTP_INTERCEPTORS, useClass: MsalInterceptor, multi: true}],
bootstrap: [AppComponent]
})
export class AppModule { }
预期结果:删除 MSAL 身份验证模块应该允许我们的应用程序 运行 无需登录。
实际结果:应用程序仍在提示登录,或未正确呈现。
为了解决这个问题,我们为 运行 e2e 测试设置了另一个配置文件。
我们使用了不包含 属性 canActivate 的自定义 ngular.routing.module:[MsalGuard]
我通过将 属性 enableMsal
添加到我的 environment.test.ts 中解决了这个问题(和相同的 属性 值 true
在产品环境中):
export const environment = {
production: false,
enableMsal: false,
};
然后在路由模块中使用(默认叫app-routing.module.ts,像这样:
//...
const guards: any[] = environment.enableMsal ? [MsalGuard] : [];
const routes: Routes = [
{path: '', redirectTo: '/main', pathMatch: 'full'},
{path: 'main', component: MainComponent, canActivate: guards},
{path: 'other', component: OtherComponent, canActivate: guards},
];
//...
如果您不知道如何配置多个环境,angular 有一个很好的指南 here。
要绕过 MSAL,您可以在 main-skip-login.ts
中模拟 MsalGuard
、MsalService
和 MsalInterceptor
的实现,这是 main.ts
文件的副本。
import { MsalGuard, MsalInterceptor, MsalService } from '@azure/msal-angular';
MsalGuard.prototype.canActivate = () => true;
MsalInterceptor.prototype.intercept = (req, next) => {
const access = localStorage.getItem('access_token');
req = req.clone({
setHeaders: {
Authorization: `Bearer ${access}`
}
});
return next.handle(req);
};
MsalService.prototype.getAccount = (): any => {
if (!localStorage.getItem('access_token')) return undefined;
return {
idToken: {
scope: [],
// other claims if required
}
};
};
然后在angular.json
中创建一个名为e2e的配置,并将main.ts
替换为main-skip-login.ts
。
"configurations": {
"e2e": {
"fileReplacements": [
{
"replace": "src/main.ts",
"with": "src/main-skip.login.ts"
}
]
}}
现在您可以 运行 使用此配置进行项目并使用真实令牌设置 localStorage 以绕过 MSAL 身份验证流程。您还可以使用模拟逻辑来获得所需的结果。
我想为我的 Angular 应用程序设置一些端到端测试,这需要使用 MSAL 库对某些下游服务进行身份验证。当我尝试在本地 运行 我的 e2e 测试时,MSAL 库强制我使用 username/password 进行身份验证。
这是一个问题,因为我们的 CI/CD 端到端测试不应该有任何人为干预;因此我正在寻找一种方法来绕过 MSAL 身份验证或设置服务帐户进行登录。不幸的是,Angular(尤其是在端到端测试方面)的 MSAL 相关文档并不多,但这似乎是其他人可能 运行 遇到的一个常见问题。
我已尝试从我们的 app.module.ts 文件中禁用 MsalModule,但当我尝试 运行 应用程序时仍然提示我登录。我还看到一些文章试图以编程方式登录,但这对我们不起作用,因为 MSAL 在技术上不是我们能够接触的 Angular 组件。
app.module.ts:
@NgModule({
...
imports: [
...
MsalModule.forRoot({
clientID: '<client_id>',
authority: <microsoft_authority_url>,
validateAuthority: true,
redirectUri: "http://localhost:4200/",
cacheLocation : "localStorage",
postLogoutRedirectUri: "http://localhost:4200/",
navigateToLoginRequestUrl: true,
popUp: true,
consentScopes: [ "user.read"],
unprotectedResources: ["https://www.microsoft.com/en-us/"],
protectedResourceMap: protectedResourceMap,
logger: loggerCallback,
correlationId: '1234',
level: LogLevel.Info,
piiLoggingEnabled: true
})
],
entryComponents: [SaveDialogComponent,
GenericDialog, MassChangeDialogComponent],
providers: [TitleCasePipe,
{provide: HTTP_INTERCEPTORS, useClass: MsalInterceptor, multi: true}],
bootstrap: [AppComponent]
})
export class AppModule { }
预期结果:删除 MSAL 身份验证模块应该允许我们的应用程序 运行 无需登录。
实际结果:应用程序仍在提示登录,或未正确呈现。
为了解决这个问题,我们为 运行 e2e 测试设置了另一个配置文件。
我们使用了不包含 属性 canActivate 的自定义 ngular.routing.module:[MsalGuard]
我通过将 属性 enableMsal
添加到我的 environment.test.ts 中解决了这个问题(和相同的 属性 值 true
在产品环境中):
export const environment = {
production: false,
enableMsal: false,
};
然后在路由模块中使用(默认叫app-routing.module.ts,像这样:
//...
const guards: any[] = environment.enableMsal ? [MsalGuard] : [];
const routes: Routes = [
{path: '', redirectTo: '/main', pathMatch: 'full'},
{path: 'main', component: MainComponent, canActivate: guards},
{path: 'other', component: OtherComponent, canActivate: guards},
];
//...
如果您不知道如何配置多个环境,angular 有一个很好的指南 here。
要绕过 MSAL,您可以在 main-skip-login.ts
中模拟 MsalGuard
、MsalService
和 MsalInterceptor
的实现,这是 main.ts
文件的副本。
import { MsalGuard, MsalInterceptor, MsalService } from '@azure/msal-angular';
MsalGuard.prototype.canActivate = () => true;
MsalInterceptor.prototype.intercept = (req, next) => {
const access = localStorage.getItem('access_token');
req = req.clone({
setHeaders: {
Authorization: `Bearer ${access}`
}
});
return next.handle(req);
};
MsalService.prototype.getAccount = (): any => {
if (!localStorage.getItem('access_token')) return undefined;
return {
idToken: {
scope: [],
// other claims if required
}
};
};
然后在angular.json
中创建一个名为e2e的配置,并将main.ts
替换为main-skip-login.ts
。
"configurations": {
"e2e": {
"fileReplacements": [
{
"replace": "src/main.ts",
"with": "src/main-skip.login.ts"
}
]
}}
现在您可以 运行 使用此配置进行项目并使用真实令牌设置 localStorage 以绕过 MSAL 身份验证流程。您还可以使用模拟逻辑来获得所需的结果。