angular 5 adal.js自动令牌更新,加载角度两次或更多次 [英] angular 5 adal.js automatic token renew in load angular twice or more

查看:136
本文介绍了angular 5 adal.js自动令牌更新,加载角度两次或更多次的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经尝试了许多角形标签库,但是令牌的更新不是自动完成的。

I have tried a number of angular-adal libraries but the renew of the token is not automatic done.

这是我使用的配置。

在package.json中

In package.json

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

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

adal-angular come with two scripts adal.js and adal-angular.js. I think adal.angular.js is only for old angularjs solutions. So I used adal.js and an wrapper @types/adal.

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

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

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

In my angular 5 application I use adal to log on and make request api request to website on another url.

使用的配置

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

我的authService

My authService looks like

  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日志记录

The logging is not needed but enables adal.js logging

很多示例将令牌存储在本地存储中,但是此令牌仅可使用1个小时。为了解决这个问题,我每次都调用acquireToken。

A lot of examples store there token in localstorage but this token is only valid for 1 hour. To solve this problem I call acquireToken everytime. It will give me the cached token or a renewed if it is expired.

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

要使此功能正常运行,有很多棘手的事情。

To get this working right there are a number of tricky things.

续订是在隐藏的I框架中完成的,这是向Microsoft AD发出请求的原因

The renewal is done in a hidden I frame what makes a request to microsoft AD

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

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

the response will redirect to http://localhost:4200/... that will start another angular application in this hidden IFrame

此项检查,如果(window.frameElement&&& window.frameElement.id === adalIdTokenFrame)

const user = this._context.getCachedUser(); 行是必需的,因此该adal知道有一个用户,并将续订该用户,而是一条消息,提示用户必须登录。

The line const user = this._context.getCachedUser(); is needed so that adal knows there is a user and will renew the user instead a message that the user must login.

这似乎正常。如果令牌已过期 New Date(profile.exp * 1000)数小时。用户仍然可以续签此令牌。

This seems to work ok. If the token is expired New Date(profile.exp*1000) for several hours. The user can still renew this token.

有没有办法防止将我的Angular叠放加载到隐藏的iframe中?

Is there a way to prevent that my Angular apllication is loaded in the hidden Iframe? With a working wrapper or some other trick?

推荐答案

添加脚本以防止在隐藏的框架中加载角形。这样可以更快地登录/更新令牌。这样可以防止首次在浏览器中加载angular时就启动了tree时间。

Add a script to prevent loading angular in the hidden frame. This makes the logon/renew of token faster. It prevent that angular is started tree times when loaded for the first time in the browser.

此脚本可以添加到index.html中。它检查是否将其加载到隐藏帧中,对令牌进行解码并防止加载角度。

This script can be added to the index.html. It check if it is loaded in a hidden frame, decode the token and prevent loading 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一起使用MSAL可以使用弹出窗口,但是某些IE版本存在问题这个。
MSAL不如adal

Update: with Adal en MSAL you can use popup but some IE versions have problems with this. MSAL is not as complex as 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自动令牌更新,加载角度两次或更多次的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆