angular 5 adal.js 自动 token 更新负载 Angular 两次或更多

标签 angular azure-active-directory angular5 adal.js

我已经尝试了一些 angular-adal 库,但 token 的更新不是自动完成的。

这是我使用的配置。

在 package.json 中

"@types/adal": "^1.0.29",
"@types/adal-angular": "^1.0.0",
"adal-angular": "^1.0.17",

adal-angular 带有两个脚本 adal.jsadal-angular.js。我认为 adal.angular.js 仅适用于旧的 angularjs 解决方案。所以我使用了 adal.js 和包装器@types/adal。

并在 .angular-cli.json 中包含 adal.js

  "scripts": [
    "../node_modules/adal-angular/lib/adal.js"
  ],

在我的 angular 5 应用程序中,我使用 adal 登录并向另一个 url 上的网站发出请求 api 请求。

使用的配置

  JwtConfig: {
    tenant: "a1d50521-9687-4e4d-a76d-xxxxxxxxx",
    clientId: "8d708afe-2966-40b7-918c-xxxxxxxx",
    isAngular: true
  },

我的 authService 看起来像

  import { } from "adal";
  @Injectable()
  export class AuthService {
  private _config: adal.Config;
  private _context: adal.AuthenticationContext;
  constructor() {
    Logging = {
      level: 3,
      log: function (message) {
        console.log(message);
      }
    };
    this._config = environment.JwtConfig;
    this._context = new AuthenticationContext(this._config);
  }

不需要日志记录但启用 adal.js 日志记录

很多示例将 token 存储在本地存储中,但此 token 仅在 1 小时内有效。为了解决这个问题,我每次都调用 acquireToken。它会给我缓存的 token ,如果它过期了,它会给我更新。

  acquireToken(): Observable<string> {
    return new Observable<string>((subscriber: Subscriber<string>) => {
      if (window.frameElement && window.frameElement.id === "adalIdTokenFrame")
        subscriber.next(null);
      else {
        const user = this._context.getCachedUser();
        return this._context.acquireToken(environment.JwtConfig.clientId, (message: string, token: string) => {
          subscriber.next(token);
        });
      }
    });
  }

要让它正常工作,有许多棘手的事情。

更新是在向 Microsoft AD 发出请求的隐藏 I 框架中完成的

https://login.microsoftonline.com/xxxtenantIDxxx/oauth2/authorize?response_type=id_token&client_id=xxx-xx-x-xx

响应将重定向到 http://localhost:4200/...,这将启动此隐藏 IFrame 中的另一个 Angular 应用程序

此检查 if (window.frameElement && window.frameElement.id === "adalIdTokenFrame") 将防止隐藏 IFrame 的无限循环。

const user = this._context.getCachedUser(); 行是必需的,以便 adal 知道有一个用户并将更新该用户,而不是一条用户必须登录的消息。

这似乎工作正常。如果 token 已过期 New Date(profile.exp*1000) 几个小时。用户仍然可以续订此 token 。

有没有办法防止我的 Angular 应用程序加载到隐藏的 Iframe 中?使用有效的包装器或其他一些技巧?

最佳答案

添加脚本以防止在隐藏框架中加载 Angular 。这使得 token 的登录/更新更快。当第一次在浏览器中加载时,它可以防止 angular 启动树次。

此脚本可以添加到 index.html 中。它检查它是否加载到隐藏框架中,解码 token 并防止加载 Angular 。

<script>
    if (window.parent && window.parent.AuthenticationContext) {
      var self = window.parent._adalInstance;
      var hash = window.location.hash;

      if (self.isCallback(hash)) {
        self.info("Returned from redirect url");

        var requestInfo = self.getRequestInfo(hash);
        var tokenReceivedCallback = self._callBackMappedToRenewStates[requestInfo.stateResponse];

        self.saveTokenFromHash(requestInfo);

        var token = requestInfo.parameters[self.CONSTANTS.ACCESS_TOKEN] || requestInfo.parameters[self.CONSTANTS.ID_TOKEN];
        var tokenType = self.CONSTANTS.ACCESS_TOKEN;
        var errorDesc = requestInfo.parameters[self.CONSTANTS.ERROR_DESCRIPTION];
        var error = requestInfo.parameters[self.CONSTANTS.ERROR];
        try {
          if (tokenReceivedCallback)
            tokenReceivedCallback(errorDesc, token, error, tokenType);
        } catch (err) {
          self.error("Error occurred in user defined callback function: " + err);
        }
        document.write('<style type="text/undefined">');
      }
    }
  </script>

更新: 使用 Adal en MSAL,您可以使用弹出窗口,但某些 IE 版本对此有问题。 MSAL 没有 adal 复杂

import * as Msal from 'msal';
export const config: Msal.Configuration  {
  auth: { clientId: '.....-1796-...'},
  cache: { cacheLocation: 'localStorage' },
};
constructor() {
    this.adAuthenticationContext = new Msal.UserAgentApplication(config);
  }

关于angular 5 adal.js 自动 token 更新负载 Angular 两次或更多,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49099740/

相关文章:

node.js - 我怎样才能在 Angular 问题中获得一条记录?

owin - Microsoft.Owin.Security.OpenIdConnect 与 Azure Active Directory 身份验证票证生命周期

angular - 如何在 Angular5 的 ng2-select 中列出客户端?

angular5 - Angular 5 bypassSecurityTrustUrl 不工作

html - Angular 2/4/6 组件方法如何用于另一个组件?

Angular Material Progress 微调器和进度条不显示

java - 使用 Angular 和 Spring 进行 Jwt 身份验证

powershell - 如何使用具有集成安全性的 Powershell 连接 Azure Paas 数据库

azure - 无法从 Dynamics 365 Customer Insights 平台接收正确的预测数据

angular - UAngular 5 : mat-table [dataSource] within *ngFor loop, 如何从数组传递数据源