MSAL Angular - 动态重定向 Url 配置通过 document.location.origin 不使用 AOT

MSAL Angular - Dynamic Redirect Url Config via document.location.origin not working with AOT

我正在编写一个 Angular 应用程序,同时尽最大努力避免根据环境变量重建我的项目。对于基本的后端 API 调用,分别使用 document.location.origin and/or window.location.origin 非常容易。引用托德霍华德最臭名昭着的台词:“它就是有效”。我必须承认,到目前为止,我的应用程序有相当直接和相当简单的问题需要解决,所以我缺乏一些更中间概念的知识。但是,最终客户希望使用 MSAL 库将其用作备用 Active Directory,并为了方便“单点登录策略”。我忽略了在生产构建中尝试它,意识到我不能像这样使用它...

 MsalModule.forRoot({
      auth: {
        clientId: '<my_client_id>',
        authority: '',
        redirectUri: window.location.origin,
        postLogoutRedirectUri: window.location.origin + "/login"
      },
      cache: {
        cacheLocation: 'localStorage',
        storeAuthStateInCookie: isIE, // set to true for IE 11
      },
    },

在类似案例的应用解决方案方面,我还没有看到太多。我什至发现这个特定问题的唯一原因是通过这个 git-issue post

https://github.com/angular/angular-cli/issues/10957

我的问题是,有没有办法为 AOT 构建提供 window 对象?

您应该将 redirectUri 和 postLogoutRedirectUri 作为变量传递,例如 clientId 和 authority,'redirect uri' 也是 Azure Ad 应用程序注册的一部分 - 这应该是处理该问题的正确方法。您将无法使用动态值在不同环境中测试此应用程序。

除此之外,如果您的流程完全不可更改,可以使用位置服务 https://angular.io/api/common/Location#path ?

因此,在四处挖掘并考虑到人们的沉默之后...我通过挖掘 MSAL 库的 Git 找到了解决方案。

const isIE = window.navigator.userAgent.indexOf('MSIE ') > -1 || window.navigator.userAgent.indexOf('Trident/') > -1;


export const protectedResourceMap: [string, string[]][] = [
  ['https://graph.microsoft.com/v1.0/me', ['user.read']]
];

// This setup won't change in our environment, so we were fine with having it statically included
export const clientId = window.location.origin.includes('qa') || window.location.origin.includes('localhost') ? '<qa_id>' : '<prod_id>';

export function MSALConfigFactory(): Configuration {
  return {
    auth: {
      clientId,
      authority: "https://login.microsoftonline.com/common/",
      validateAuthority: true,
      redirectUri: window.location.origin,
      postLogoutRedirectUri: window.location.origin,
      navigateToLoginRequestUrl: true,
    },
    cache: {
      cacheLocation: "localStorage",
      storeAuthStateInCookie: isIE, // set to true for IE 11
    },
  };
}

export function MSALAngularConfigFactory(): MsalAngularConfiguration {
  return {
    popUp: !isIE,
    consentScopes: [
      "user.read",
      "openid",
      "profile"
    ],
    unprotectedResources: [],
    protectedResourceMap,
    extraQueryParameters: {}
  };
}

我们只是在 [=16= 的导入对象中添加 MsalModule 而不是使用不适用于通过 window 进行动态设置的 MsalModule.forRoot({},{}) 配置].所以而不是...

imports: [
.. // shortened for terseness
MsalModule.forRoot({},{}),
..
]

我们确实将其更改为...

imports: [
.. // shortened for terseness
MsalModule,
..
]

对于提供商,我们需要提供 MSAL_CONFIG class,但我们还需要提供我们想要使用的配置,这是我们之前所做的。不要忘记包含 MsalService,否则应用程序不会 运行。

  providers: [
    {
      provide: MSAL_CONFIG,
      useFactory: MSALConfigFactory
    },
    {
      provide: MSAL_CONFIG_ANGULAR,
      useFactory: MSALAngularConfigFactory
    },
    MsalService,
  ],

此应用程序已在 Angular 7 项目上进行测试,即使使用高效构建 + AOT

也能按预期工作