microsoft-authentication-library-for-js icon indicating copy to clipboard operation
microsoft-authentication-library-for-js copied to clipboard

Defer configuration loading in dedicated method instead of controller

Open vlafranca opened this issue 4 years ago • 22 comments

#1090 Library

Description

Hi everyone, In my situation, I need to load oidc configuration from a remote server, so I need to make an http call to retrieve it. I have read all the docs and tryed all the ways to load configurations but nothing suits my need and I think I won't be the only one looking for this. I am working on a security library which will be embedded in many other project, the goal is to obfuscate any auth security process within this lib which will expose only basic methods to hosts projects. The libs needs then to handle all Msal init (service instanciation, interceptors, etc) and retrieve the config url via an injection token injected by host app.

The only way to load asynchronously a config file from doc is to use platformDynamic, but I don't want to duplicate that Msal specific configuration scheme in all the applications that will use the library. Also the APP_INITIALIZER provider is not delaying the app bootstrap so the configuration is not loaded on time because MsalService load configuration in constructor.

What I needed to do is to build a custom wrapper service to handle remote configuration loading and manual MsalService instanciation (loading config from constructor). Then set a flag init to true, and use my inner MsalService instance.

It would be nice to have a configure(config) method to be able to manage the lib initilization flow entirely. Instead of init in constructor.

Here is the code I made to have an idea, I would be able to make a PR if you think it is interesting.

@Injectable({
  providedIn: 'root'
})
export class ConfigService {
  public msalService: MsalService;
  private http: HttpClient;
  public configInit = new Subject();
  constructor(httpClient: HttpClient, private router: Router, private broadcasService: BroadcastService) {
    this.http = httpClient;
  }

  configure(uri) {
    this.http.get(uri).pipe(map(res => res))
    .subscribe((value: any) => {
      msalConfig.auth.clientId = value.client_id;
      msalConfig.auth.postLogoutRedirectUri = value.post_logout_redirect_uri;
      msalConfig.auth.redirectUri = value.redirect_url;
      msalConfig.auth.authority = value.stsServer;
      msalAngularConfig.consentScopes = value.scope.split(" ");
      this.msalService = new MsalService(msalConfig, msalAngularConfig, this.router, this.broadcasService);
      this.configInit.next(true);
    },
      (error) => {
      });
  }
}

vlafranca avatar May 15 '20 14:05 vlafranca

@vlafranca Thanks for the feedback! This is an interesting use case. Feel free to open a PR that shows what you think this might look like, thanks!

jasonnutter avatar May 19 '20 16:05 jasonnutter

@jasonnutter great ! I am working on it and will be soon able to make a PR

vlafranca avatar May 22 '20 19:05 vlafranca

Hi @jasonnutter I juste submitted a PR #1715

Labeler / label (pull_request) checks fails, can you explain me why ?

vlafranca avatar May 27 '20 20:05 vlafranca

@vlafranca The labeler wasn't setup to work with forks, that will be fixed.

jasonnutter avatar May 29 '20 02:05 jasonnutter

Ok thanks for your reply, is there any log output in azure to know why is the build failing ? It succeed on my machine ..

Le jeu. 28 mai 2020 à 22:01, Jason Nutter [email protected] a écrit :

@vlafranca https://github.com/vlafranca The labeler wasn't setup to work with forks, that will be fixed.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/AzureAD/microsoft-authentication-library-for-js/issues/1665#issuecomment-635713021, or unsubscribe https://github.com/notifications/unsubscribe-auth/AB2NUS357IATOZGZY43EGATRT4JQDANCNFSM4NBT5HWA .

vlafranca avatar May 29 '20 02:05 vlafranca

Any news or estimation about this ?

vlafranca avatar Jun 15 '20 16:06 vlafranca

@vlafranca Not yet, sorry, been busy. We'll update the ticket when we get a chance, apologies for the delay.

jasonnutter avatar Jun 17 '20 01:06 jasonnutter

Ok no problem

vlafranca avatar Jun 19 '20 14:06 vlafranca

Hello, any news into this? It's a really good functionality and we really need it for our project, thanks!

ursedaniel avatar Oct 13 '20 09:10 ursedaniel

We will look to support updating the MSAL configuration dynamically in MSAL Angular v2 (alpha available now).

jasonnutter avatar Nov 12 '20 02:11 jasonnutter

Ok so this PR is abandoned or need to adapt for v2 ?

On Wed, Nov 11, 2020 at 9:35 PM Jason Nutter [email protected] wrote:

We will look to support updating the MSAL configuration dynamically in MSAL Angular v2 (alpha available now https://github.com/AzureAD/microsoft-authentication-library-for-js/releases/tag/msal-angular-v2.0.0-alpha.0 ).

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/AzureAD/microsoft-authentication-library-for-js/issues/1665#issuecomment-725790093, or unsubscribe https://github.com/notifications/unsubscribe-auth/AB2NUS6T3MDLCDNEXVAQVRDSPNCYPANCNFSM4NBT5HWA .

vlafranca avatar Nov 12 '20 14:11 vlafranca

This can be achieved easily using the Factory providers with APP_INITIALIZER, check following sample https://github.com/vinusorout/msal-angular-dynamic-configuration-sample

vinusorout avatar Mar 10 '21 18:03 vinusorout

Yes they brought this feature with MSAL 2.

On Wed, Mar 10, 2021 at 1:55 PM Vinay Sorout [email protected] wrote:

This can be achieved easily using the Factory providers with APP_INITIALIZER, check following repo https://github.com/vinusorout/msal-angular-dynamic-configuration-sample

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/AzureAD/microsoft-authentication-library-for-js/issues/1665#issuecomment-795910016, or unsubscribe https://github.com/notifications/unsubscribe-auth/AB2NUS2HJHUW2FQZMSDYE3LTC66DDANCNFSM4NBT5HWA .

vlafranca avatar Mar 10 '21 19:03 vlafranca

No, It was also working with MSAL 1.x , check following https://github.com/AzureAD/microsoft-authentication-library-for-js/issues/1403

vinusorout avatar Mar 10 '21 19:03 vinusorout

@jo-arroyo any news on this? I'm using msal-angular 2.0.0 and msal-browser 2.14.2 and sometimes I get an error because the MSAL initialization starts before APP_INITIALIZER finishes reading the JSON configuration file:

image

My project uses PathLocationStrategy(like the angular10-sample-app) but with all routes guarded by MsalGuard, so the users are logged in as soon as they hit the app as explained in the documentation.

You can reproduce the problem in the sample provided by @vinusorout by adding the MsalGuard as I explained in this issue.

Any tip regarding how to make sure MSALInstanceFactory is executed after reading a file asynchronously would be much appreciated.

ozkoidi avatar May 06 '21 08:05 ozkoidi

hey @ozkoidi did you find a solution for this? I have the same issue.

Depechie avatar Dec 10 '21 10:12 Depechie

Hello @Depechie,

They may have fixed the issue in the meantime but in case it helps you, the workaround that worked for me is the following:

Disable the initial navigation in the routing module

@NgModule({
  imports: [
    RouterModule.forRoot(ROUTES, {
      initialNavigation: 'disabled'
    })
  ],

In app.module.ts pass the Router to the initializer method

...
providers: [
  ...,
  {
    provide: APP_INITIALIZER,
    useFactory: initializeApp,
    deps: [Router],
    multi: true
  },
  ...

to call router.initialNavigation(); after reading the configuration file

  export const initializeApp = (router: Router) => async () => {
    await config.load(); <- This is where you load the config file
    router.initialNavigation(); <- This enables the navigation we disabled in the routing module
  };

ozkoidi avatar Dec 10 '21 12:12 ozkoidi

@ozkoidi thx for the details... but no matter what I try, as soon as I hit the http.get in my config.Load to read out the /assets/config.json, I see in the logging that other elements will still get called before the file is read.

Cfr screenshot: the config parsed is placed above the router.initialNavigation().

Screenshot (113) .

Is there any running example I can look at? Otherwise I can always try to put a test example on my github ofcourse.

Depechie avatar Dec 10 '21 13:12 Depechie

Got it working, by refactoring the original example by @vinusorout

Depechie avatar Dec 12 '21 21:12 Depechie

@jo-arroyo Are we still planning official support for this feature?

sameerag avatar Apr 02 '22 04:04 sameerag

We haven't decided on it, no. It looks like there are workarounds, though.

jasonnutter avatar Apr 05 '22 17:04 jasonnutter

This is exactly what i need

Gillardo avatar Oct 17 '22 09:10 Gillardo