sureshchahal / angular2-adal

Angular 2 wrapper for adal.js
MIT License
41 stars 50 forks source link

Redirect from AAD leaves hash in url #46

Open ukphillips opened 7 years ago

ukphillips commented 7 years ago

When I am redirected from AAD back to my app I have the id_token fragment in the URL as expected, but I am missing how this gets cleared out:

https://localhost:44387/#id_token=eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6InowMzl6ZHNGdWl6cEJmQlZ ...

In the original adal.js it cleared out the hash after the redirect. Is there a setting I need to set to allow this? I know with angular you can using routes after the #, but I'm not using that so I want to make sure after the redirect I remove the hash once I process the token.

ukphillips commented 7 years ago

Would there be an issue with adding this to the handleWindowCallback method:

 public handleWindowCallback(): void {
        let hash = window.location.hash;

        window.location.hash = ''; //Clear out the URL hash once we have captured it

        if (this.adalContext.isCallback(hash)) {
            let requestInfo = this.adalContext.getRequestInfo(hash);
            this.adalContext.saveTokenFromHash(requestInfo);
            if (requestInfo.requestType === this.adalContext.REQUEST_TYPE.LOGIN) {
                this.updateDataFromCache(this.adalContext.config.loginResource);

            } else if (requestInfo.requestType === this.adalContext.REQUEST_TYPE.RENEW_TOKEN) {
                this.adalContext.callback = window.parent.callBackMappedToRenewStates[requestInfo.stateResponse];
            }

            if (requestInfo.stateMatch) {
                if (typeof this.adalContext.callback === 'function') {
                    if (requestInfo.requestType === this.adalContext.REQUEST_TYPE.RENEW_TOKEN) {
                        // Idtoken or Accestoken can be renewed
                        if (requestInfo.parameters['access_token']) {
                            this.adalContext.callback(this.adalContext._getItem(this.adalContext.CONSTANTS.STORAGE.ERROR_DESCRIPTION)
                                , requestInfo.parameters['access_token']);
                        } else if (requestInfo.parameters['id_token']) {
                            this.adalContext.callback(this.adalContext._getItem(this.adalContext.CONSTANTS.STORAGE.ERROR_DESCRIPTION)
                                , requestInfo.parameters['id_token']);
                        }
                        else if (requestInfo.parameters['error']) {
                            this.adalContext.callback(this.adalContext._getItem(this.adalContext.CONSTANTS.STORAGE.ERROR_DESCRIPTION), null);
                            this.adalContext._renewFailed = true;
                        }
                    }
                }
            }
        }
    }
ukphillips commented 7 years ago

The less than optimal solution I ended up going with so as not to modify the library was handling it in my app.component:

import { Component, ViewEncapsulation } from '@angular/core';
import { Router, NavigationEnd } from '@angular/router';
import { OnInit } from '@angular/core';

import { AdalConfigService } from "../adal/adal.config.service";
import { AdalService } from "ng2-adal/core";
import { Location } from '@angular/common';

@Component({
    selector: 'app',
    templateUrl: './app.component.html',
    styleUrls: ['../../assets/styles/bundled.scss'],
    encapsulation: ViewEncapsulation.None 
})
export class AppComponent implements OnInit {
    constructor(
        private adalService: AdalService,
        private secretService: AdalConfigService,
        private router: Router,
        private location: Location
    ) {
        this.adalService.init(this.secretService.adalConfig);
    }
    ngOnInit(): void {
        this.adalService.handleWindowCallback();

        var urlFragments = window.location.href.split("#id_token")
        if (urlFragments.length > 1)
        {
            this.location.go(this.location.path());
        }

        this.adalService.getUser();
    }

}

Since this is in my app.component it will always fire when reloading my app from an AAD redirect. I simply see if I had the id_token fragment and if so set my location to the path (this avoids reloading my app again, which was a problem I had with my initial approach of setting the window.location.href)

mystardustcaptain commented 5 years ago

Thanks, you last workaround works well!