microsoft-authentication-library-for-js: loginPopup doesn't properly close itself

Using version 0.1.3

Code:

let microsoftApp = new UserAgentApplication("my-app-id", null, null);
microsoftApp.loginPopup(["openid", "email"])
    .then(idtoken => /* do something with the id token */)
    .catch(error => /* do something with the error */);

Expected behavior: A login popup pops up and after the user logs in the pop up closes itself and the loginPopup promise resolves (or rejects).

Actual behavior: A login popup pops up and after the user logs in the pop up redirects back to my site in the pop up.

image

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Reactions: 4
  • Comments: 28 (4 by maintainers)

Most upvoted comments

@rohitnarula7176 that’s extremely inconventient. An SPA has to stand up a new endpoint simply to include the msal lib again so it can close itself?

The Google and Facebook JS libraries can do it, why can’t msal?

@dfederm This is by design. All the tokens we receive are in the form of a redirect response on the redirectURI page and you need an instance of userAgentApplication on that page for MSAL to process that response and close the popup. Closing this issue as this is by design.

I think I found a workaround. If I create a UserAgentApplication on that redirected page, it closes the popup and works as I expect it to.

It seems like a weird requirement to require the redirect. This is an SPA and I only need the id token (to auth with my application). Both the Google and Facebook JS libraries can handle this scenario without requiring a redirect in the pop up.

@chetanku my workaround was just to load the entire SPA in the redirect, and the SPA creates a UserAgentApplication at app startup if the hash include “id_token”. It’s pretty terrible and I only have to do this workaround for MSA log in support; Facebook and Google’s libraries work perfectly.

    // This is weird but Microsoft login redirects back to the site and expects it to create the object before it closes the popup.
    // See https://github.com/AzureAD/microsoft-authentication-library-for-js/issues/174
    if (location.hash.includes("id_token")) {
      new UserAgentApplication("4ecf3d26-e844-4855-9158-b8f6c0121b50", null, null);
    }

This behaviour is absolutely incomprehensible, by definition the authentication process is completed when the token is returned by the service, so why should we need to instantiate an other UserAgentApplication just to avoid cancel operation error closing the popup? It does not make sense at all…

I agree with @dfederm it’s extremely inconventient. What problem do you fix with this design? All oAuth providers sent token to promise resolve and close popup. It’s default behavior for all SPA’s

I encountered the problem to implement this library to my application because of inappropriate behaviour. It’s time consuming due to its inflexibility. I couldn’t initialize the library after AJAX request - wtf??? This behaviour is inconsistence with usual flow (like in Google and Facebook), so I have to add some hacks to my application

wow, it’s undocumented behavior. I need to have id_token in URL and after create UserAgentApplication I can get access token, save it and close modal. I think, this information need to be added to MSAL wiki pages.

I found the issue: so the workaround is actually to create the AuthProvider as a global, and not in React. If you do this it won’t work:

class Msal extends React.Component {
  componentWillMount() {
    const authProvider = new UserAgentApplication(msalConfig);
    this.setState({ authProvider })
  }
  render() {
    // ...
  }
}

But this setup works:

const authProvider = new UserAgentApplication(msalConfig);
class Msal extends React.Component {
  componentWillMount() {
    this.setState({ authProvider })
  }
  render() {
    // ...
  }
}

This still feels like a hack and should not be ‘per design’. The good design would be to track the popup’s location and resolve the promise when the token appears in the hash. But anyway, the lib does not support response_type=code so it’s not suitable for me.

// This is weird but Microsoft login redirects back to the site and expects it to create the object before it closes the popup. // See https://github.com/AzureAD/microsoft-authentication-library-for-js/issues/174 if (location.hash.includes(“id_token”)) { new UserAgentApplication(“4ecf3d26-e844-4855-9158-b8f6c0121b50”, null, null); }

Where exactly do i need to put this code in reactjs?

For the record, in Angular7 app using MSAL I have:

import {Component, OnInit} from ‘@angular/core’; import {UserAgentApplication} from ‘msal’;

@Component({
    selector: 'app-login',
    templateUrl: './login.component.html',
    styleUrls: ['./login.component.scss']
})
export class LoginComponent implements OnInit {
    ngOnInit() {
        console.log(`login component`);
        // necessary - https://github.com/AzureAD/microsoft-authentication-library-for-js/issues/174
        new UserAgentApplication(
            {
                auth: {
                    clientId: 'xxx',
                }
            });
    }
}

This component is hit as part of the redirectUri.

Hi @rohitnarula7176, I am trying to understand why the popup would not get closed after authentication on its own. Is there an application that uses this kind of workflow you could reference? I cannot imagine where this design would be more convenient than the traditional implementation. Thanks!

@Apollinaire we absolutely do. Currently, our plan is that our node.js lib will support it, although that does not help SPA. We have used the implict flow on the web because of previous recommendations by the Oauth spec , but from what I understand those winds have shifted and auth_code is now safe to use on the web. This requires some investigation on our end and I don’t have a solid answer yet, but do check our roadmap from time to time and we will put it there.

@Apollinaire thanks for sharing, I think that the setup code you provided that works is not necessarily a hack, but understand the frustration around no set pattern for react. https://github.com/AzureAD/microsoft-authentication-library-for-js/wiki#roadmap React is on our roadmap, and we hope to have a wrapper that abstracts all of this away.

We are also working on ideas for cleaner ways to resolve popups, but need to do some work to decouple the flows first. Right now the code handling redirect, popup and silent all share some code paths and for us to change one, we first need to separate those code paths.

I know its not a great answer today, but we definitely understand your pain and are working to make things easier moving forward. Any thoughts or contributions are appreciated.

Wish I’d found this a few days ago: now the incomprehensible and undocumented behaviour is explained. +1 to at least document this.

@dfederm Thank you so much, this is very weird. Hope Microsoft fixes this soon.