How to use RenewToken method of MSADAL in Angular 6+?

后端 未结 2 570
暗喜
暗喜 2021-01-07 07:42

I am using MS Adal NPM package (https://www.npmjs.com/package/microsoft-adal-angular6) for Angular 6 to get the user Authenticated with Azure AD. I am using Implicit Flow t

相关标签:
2条回答
  • 2021-01-07 07:52

    Use an http wrapper service/interceptor to intercept all http requests and set the token subscribed by the this._adalService.acquireToken method and set in the Authorization header of each http request as follows,

          import {Component, Injectable } from '@angular/core';
          import { Headers, Http, Response, RequestOptions, XHRBackend, Request, 
          RequestOptionsArgs } from '@angular/http';
          import { Router, ActivatedRoute } from '@angular/router';
          import { Observable } from 'rxjs/Rx';
          import { AdalService } from 'ng4-adal/core';
    
          export class HttpService extends Http {
             constructor(backend: XHRBackend, options: RequestOptions,private 
             _adalService:AdalService) {
             super(backend, options);
         }
    
       request(url: string | Request, options: RequestOptionsArgs): Observable<Response> {
    
        return this._adalService
            .acquireToken(this._appDataService.adalConfig.clientId)
            .flatMap<string, Response>((token) => {
                var access_token = token || 
              this._adalService.getCachedToken(this._appDataService.adalConfig.clientId);
    
                if (typeof (url) == "string") {
                    if (!options) {
                        options = {};
                        options.headers = new Headers();
                    }
                    options.headers.append('Authorization', 'Bearer ' + access_token);
                    return super.request(url, options);
                }
                else {
                    url.headers.append('Authorization', 'Bearer ' + access_token);
                    return super.request(url, options);
                }
            });
          }
       }
    

    The token returned by the this._adalService.acquireToken method will be always the current active token. Also set the below configurations for ADAL,

            import {Injectable} from '@angular/core';
    
            @Injectable()
          export class AdalConfig {
         constructor() {
         }    
    
        public get getAdalConfig(): any {
        return {           
            tenant: "tenantName",
            clientId: "clientId",           
            redirectUri: window.location.origin + '/',            
            postLogoutRedirectUri: window.location.origin + '/' + "#/logout",
            extraQueryParameter: "domain_hint=someDomain.com",
            cacheLocation: "localStorage",
            expireOffsetSeconds: "1200"  //Worked for me to avoid token returned as null
          };
       }
     }
    

    Hope this helps...

    0 讨论(0)
  • 2021-01-07 08:08

    I found a nice explanation in the website https://docs.microsoft.com/en-us/microsoftteams/platform/concepts/authentication/auth-silent-aad about how ADAL creates a hidden IFrame.

    The ADAL.js library creates a hidden iframe for OAuth 2.0 implicit grant flow, but it specifies prompt=none so that Azure AD never shows the login page. If user interaction is required because the user needs to log in or grant access to the application, Azure AD will immediately return an error that ADAL.js then reports to your app. At this point your app can show a login button if needed.

    The solution was very simple. I had to just write one line of code

    this.adalsvc.RenewToken('https://graph.microsoft.com');
    

    The only point to note here is that, since "adalsvc" variable is created in the constructor through injection, you need to create a copy of the adalsvc and store it a global variable of the type MsAdalAngular6Service and then execute RenewToken method on this object. Here is a sample code that I have written. I am executign RenewToken in a button click, but in the real scenario, it could be executed in a non-interactical way.

            import { Component } from '@angular/core';
            import { MsAdalAngular6Service } from 'microsoft-adal-angular6';
    
            @Component({
              selector: 'app-root',
              templateUrl: './app.component.html',
              styleUrls: ['./app.component.css']
            })
            export class AppComponent {
              title = 'app';
              newadalsvc: MsAdalAngular6Service;
    
              onClickMe() {
               this.getNewToken();
              }
    
              constructor(private adalSvc: MsAdalAngular6Service) {
    
                 if (!this.adalSvc.userInfo) {
                   this.adalSvc.login();
                 } else {
    
                  const token = this.adalSvc.acquireToken('https://graph.microsoft.com').subscribe((token: string) => {
                   this.newadalsvc = adalSvc;
                  alert(token);
                  console.log(token);
                     localStorage.setItem('authtoken', token);
                    }); 
                 }
               }
    
    
            getNewToken()
            {
              this.newadalsvc.RenewToken('https://graph.microsoft.com');
    
    //Without calling acquireToken the new token will not be set in the "Local Storage"
    this.newadalsvc.acquireToken('https://graph.microsoft.com').subscribe((token) => {
            console.log('Token >>>>>>>>>>>>>>', token);
          });
             }
            }
    
    0 讨论(0)
提交回复
热议问题