How to disable or bypass MSAL authentication when running Angular e2e tests?

回眸只為那壹抹淺笑 提交于 2020-12-06 07:03:05

问题


I want to set up some end to end tests for my Angular application, which requires the use of the MSAL library to authenticate with some downstream services. When I try to run my e2e tests locally, the MSAL library is forcing me to authenticate with a username/password.

This is a problem because our CI/CD e2e testing should not have any human-intervention; thus I am looking for a way to either bypass the MSAL authentication or set up a service-account to login. Unfortunately there is not a lot of documentation surrounding MSAL for Angular (especially when it comes to e2e testing), but this seems like a common issue that others may have run into.

I've tried to disable the MsalModule from our app.module.ts file but I am still prompted for login when I try to run the application. I've also seen some articles trying to programmatically log in, but this does not work for us as MSAL is technically not an Angular component we are able to touch.

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 { }

Expected result: removing the MSAL authentication module should allow our application to run without needing to log in.

Actual result: application is still prompting for log in, or does not render correctly.


回答1:


I solved that by adding a property enableMsal into my environment.test.ts (and same property with value true in prod environment):

export const environment = {
  production: false,
  enableMsal: false,
};

Then used it in routing module (by default called app-routing.module.ts, like this:

//... 
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},
];
//...

In case you don't know how to configure multiple environments, angular has a good guide here.




回答2:


To Bypass MSAL you can mock the implementation of MsalGuard, MsalService and MsalInterceptor inside main-skip-login.ts which is a replica of main.ts file.

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
    }
  };
};

Then create a configuration named e2e inside angular.json and replace main.ts with main-skip-login.ts.

"configurations": {
            "e2e": {
              "fileReplacements": [
                {
                  "replace": "src/main.ts",
                  "with": "src/main-skip.login.ts"
                }
              ]
}}

Now you can run project with this configuration and set localStorage with authentic token to bypass MSAL auth flow. You can also play with mocking logic to get the desired outcome.




回答3:


In order to resolve this issue, we set up another config file for running e2e tests.

We utilized a custom ngular.routing.module that does not contain the property canActivate: [MsalGuard]



来源:https://stackoverflow.com/questions/56600532/how-to-disable-or-bypass-msal-authentication-when-running-angular-e2e-tests

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!