Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Logout doesn't redirect back to my app #127

Closed
khalibloo opened this issue Sep 14, 2017 · 45 comments
Closed

Logout doesn't redirect back to my app #127

khalibloo opened this issue Sep 14, 2017 · 45 comments

Comments

@khalibloo
Copy link

On calling logout(), I expect the browser to be redirected to my app once the logout process is completed. However, I just get a screen "You signed out of your account ..." and it stays there.

I think it's intrusive that the user is redirected away from my app in the first place. Why not have a pop up at the very most instead? It's tempting to just clear my local storage variables and skip the logout process entirely.

I should also mention that I'm testing with a localhost address and yes that address is included in my app's registration on the portal.

@navyasric
Copy link
Contributor

I'm unable to reproduce this. Can you provide a Fiddler trace of the network when you are having this issue?

@khalibloo
Copy link
Author

I've never used fiddler and I tried to export the data in several formats, none seemed to have enough info. Just "saving" the trace warns that it might contain unencrypted passwords. But I made sure to include only the logout trace, so I think that's fine.

ms_auth_bug.zip

here's a screenshot of the final screen after logging out
ms auth bug

@rohitnarula7176
Copy link
Contributor

@khalibloo We do not see any logout requests in your fiddler. To do this, just open fiddler, click login, enter your credentials and then clear the traces. This will make sure you do not have any credentials in your trace when you send it to us. Now click logout and then you should see the following get request sent out from msal. GET /rohit1.onmicrosoft.com/oauth2/logout?post_logout_redirect_uri=https%3A%2F%2Flocalhost%3A44326%2F HTTP/1.1. Please resend the fiddler when you get a chance.

@khalibloo
Copy link
Author

Hi, I apologize fiddler is all very strange to me. Basically, here's what I'm doing. When I start up fiddler, I press F12 to disable the capturing process. Then I open my app and sign in with my ms account. This all works smoothly. Then I enable the fiddler capturing process with F12. I then sign out of my ms account from my app.
At this point, I believe fiddler should have only the logout data, right? But when I open fiddler, here's what I see.
fiddler2
None of the urls look like what you described. In fact, they look to me like login urls, not logout. Now I feel like I'm missing something that should be obvious. My logout code is simply
userAgentApplication.logout();

@peterblazejewicz
Copy link

Hi,
I'm getting the same problem - the auth server does not redirect back to app, here is the output from the console session when the problem occurs:

localhost/:49 Sun, 10 Dec 2017 22:34:49 GMT:12345-0.1.3-Info Processing the callback from redirect response
localhost/:49 Sun, 10 Dec 2017 22:34:49 GMT:12345-0.1.3-Info State status:true; Request type:LOGIN
localhost/:49 Sun, 10 Dec 2017 22:34:49 GMT:12345-0.1.3-Info State is right
localhost/:49 Sun, 10 Dec 2017 22:34:49 GMT:12345-0.1.3-Info Fragment has id token
localhost/:49 Sun, 10 Dec 2017 22:34:50 GMT:12345-0.1.3-Verbose renewing accesstoken
localhost/:49 Sun, 10 Dec 2017 22:34:50 GMT:12345-0.1.3-Verbose renewToken is called for scope:user.read mail.send
localhost/:49 Sun, 10 Dec 2017 22:34:50 GMT:12345-0.1.3-Info Add msal frame to document:msalRenewFrameuser.read mail.send
localhost/:49 Sun, 10 Dec 2017 22:34:50 GMT:12345-0.1.3-Verbose Renew token Expected state: 2b475968-dd78-417e-bd38-92b7bcb0dd68
localhost/:49 Sun, 10 Dec 2017 22:34:50 GMT:12345-0.1.3-Verbose Set loading state to pending for: user.read mail.send
localhost/:49 Sun, 10 Dec 2017 22:34:50 GMT:12345-0.1.3-Info LoadFrame: msalRenewFrameuser.read mail.send
localhost/:49 Sun, 10 Dec 2017 22:34:50 GMT:12345-0.1.3-Info Add msal frame to document:msalRenewFrameuser.read mail.send
localhost/:49 Sun, 10 Dec 2017 22:34:52 GMT:12345-0.1.3-Info Returned from redirect url
localhost/:49 Sun, 10 Dec 2017 22:34:52 GMT:12345-0.1.3-Info State status:true; Request type:renewToken
localhost/:49 Sun, 10 Dec 2017 22:34:52 GMT:12345-0.1.3-Info State is right
localhost/:49 Sun, 10 Dec 2017 22:34:52 GMT:12345-0.1.3-Info Fragment has access token
localhost/:49 Sun, 10 Dec 2017 22:34:52 GMT:12345-0.1.3-Info The user object received in the response is the same as the one passed in the acquireToken request
localhost/:49 Sun, 10 Dec 2017 22:34:52 GMT:12345-0.1.3-Verbose Window is in iframe, acquiring token silently
(index):1 Sun, 10 Dec 2017 22:35:10 GMT:12345-0.1.3-Info Navigate to:https://login.microsoftonline.com/common//oauth2/v2.0/logout?post_logout_redirect_uri=http%3A%2F%2Flocalhost%3A1530%2F
Navigated to https://login.microsoftonline.com/common//oauth2/v2.0/logout?post_logout_redirect_uri=http%3A%2F%2Flocalhost%3A1530%2F
Navigated to https://login.microsoftonline.com/common/oauth2/v2.0/logoutsession
abc123.dc1files.1drv.com/storageservice/passport/expirecookie.aspx?ct=1512945315:1 GET https://abc123.dc1files.1drv.com/storageservice/passport/expirecookie.aspx?ct=1512945315 net::ERR_NAME_NOT_RESOLVED
Image (async)
_j4 @ Logout_Core.js:1
evt_LogoutNoUI_onload @ Logout_Core.js:1
onload @ logout.srf?iframed_by=https%3a%2f%2flogin.microsoftonline.com:1
accountservices.microsoft.com/passport/ppexpire.ashx?ct=1512945315:1 GET https://accountservices.microsoft.com/passport/ppexpire.ashx?ct=1512945315 net::ERR_CERT_DATE_INVALID
Image (async)
_j4 @ Logout_Core.js:1
evt_LogoutNoUI_onload @ Logout_Core.js:1
onload @ logout.srf?iframed_by=https%3a%2f%2flogin.microsoftonline.com:1
logout.srf?iframed_by=https%3a%2f%2flogin.microsoftonline.com:1 Mixed Content: The page at 'https://login.microsoftonline.com/common/oauth2/v2.0/logoutsession' was loaded over HTTPS, but requested an insecure image 'http://www.microsoft.com/'. This content should also be served over HTTPS.

The console spills errors.
thanks!

@zippy1981
Copy link

zippy1981 commented Jan 31, 2018

@khalibloo did you try setting reply uri in portal? (See below)

I have the same issue. I end up with the following sequence of URLs:

The last url looks like this:
image

Google lead me to this MSDN page which stated **This value [post_logout_redirect_uri] must match one of the redirect URIs registered for the application. **

I then added that to the portal, triple checking application id, etc.
image

It still did not work.

@khalibloo
Copy link
Author

khalibloo commented Jan 31, 2018

I've been away from this project for a while, but yeah I did set the redirect uris.
msauth portal
Don't remember what logout url does or why i left it blank. It's probably explained somewhere in one of the scattered documentations they have.

@saregbesola
Copy link

If you have post_logout_redirect_uri parameter defined, then it should redirect you back your app. It works fine for me

@khalibloo
Copy link
Author

I initialize my UserAgentApplication like so

    // Initialize application
    MSAuth.userAgentApplication = new Msal.UserAgentApplication(
      config.clientID,
      null,
      loginCallback,
      {
        redirectUri: "https://localhost:3000"
      }
    );

redirectUri is post_logout_redirect_uri, right?

I just tested again. The log out screen is different from last time, but issue still remains.

@saregbesola
Copy link

saregbesola commented Apr 2, 2018

This is my logout method:
logout() {
sessionStorage.clear();
location.href = "https://login.microsoftonline.com/common/oauth2/v2.0/logout?post_logout_redirect_uri=http://localhost:4200";
}
I just wired that to the click event of my logout button and it works. Note, you must make a GET request to this endpoint "https://login.microsoftonline.com/{tenant_Id}/oauth2/v2.0/logout?post_logout_redirect_uri=http://localhost:4200" . The endpoint must contain post_logout_redirect_uri parameter as shown

@saregbesola
Copy link

And redirectUri is not "post_logout_redirect_uri"

@khalibloo
Copy link
Author

Oh you manually rewired the logout call. I just used UserAgentApplication.logout(). I'll try your method as a workaround, thanks.
But this would mean UserAgentApplication.logout() is failing to pass along the redirectUri in the request as post_logout_redirect_uri, right?

@khalibloo
Copy link
Author

Ok, just gave it a go.
127 logout 01
You can see the post_logout_redirect_uri in the address bar.

It still doesn't redirect. It stays on this page
127 logout 02

@khalibloo
Copy link
Author

Using UserAgentApplication.logout(), I get the post_logout_redirect_uri parameter in the address bar. Though in a slightly different style.
127 logout 03

So I think it's safe to say there's something else going on beside the redirect parameter. If only there was some server side error log.

@saregbesola
Copy link

That's strange. You are supposed to be redirected back after getting "You signed out of your account". Can you inspect that page? I mean the page where is says " You signed out of your account". Also I don't know why you have two Redirect Urls in your app portal. Your post_logout_redirect_uri must be the same as the redirect url you set in the Application Registration Portal. May be there is a conflict because you have two urls in there. But you can inspect the sign out page in chrome or use fiddler to monitor the traffic. Inspect using chrome first and let's see if there is an error.

@khalibloo
Copy link
Author

When inspecting the "You signed out of your account" page, the console is empty, indicating no errors. The network tab shows that all requests were completed with a 200 status code. I will look into the multiple redirect Urls in my portal, but I doubt that will change anything. It is after all reasonable for an app to have multiple redirect Urls.

@saregbesola
Copy link

Yea multiple redirect urls will not be an issue. I just tested that and it still worked. I think It is safe to say there is something else causing that...fiddler might give you a better visibility tho. From the image you have above, you will need to configure it to decrypt https...then try sign out

@khalibloo
Copy link
Author

Ok, I'll look that up and let you know how it goes. Thanks a lot for taking the time.

@khalibloo
Copy link
Author

After several tries, I discovered setting Fiddler to decrypt HTTPS breaks msal's connection to the microsoft servers. The sign in and sign out processes stop working all together. The sign in popup disappears after a second or less. The sign out redirect ends in a browser error page "Unable to create secure connection". I'm guessing it sees fiddler as a malicious sniffer of sorts.

@saregbesola
Copy link

Fiddler is not supposed to interfere with the app. And if you close Fiddler, does it work? If only I can see your code. As for me, I'm using angular, here is what I have done with it: http://www.sharepointcorridor.com/2018/03/calling-microsoft-graph-api.html

Though I didn't implement logout in the post but I later did it as explained above, and it works fine.

@khalibloo
Copy link
Author

khalibloo commented Apr 5, 2018

Yes, when I close Fiddler, it works. Or when I press F12 to stop capturing on Fiddler, that works too.
Here's the class I use for the authentication. It's in Typescript. The value of config.redirectUri is http://localhost:3000.

import config from './msalconfig';
import ls from 'local-storage';
import jwtDecode from 'jwt-decode';
import logger from './logger';

const Msal = (window as any).Msal;

export default class MSAuth{
  static scopes: string[];
  static userAgentApplication: any;
  static initialize(){
    MSAuth.scopes = [
      "files.readwrite.all",
      "files.readwrite.appfolder",
      // "profile", //profile and openid scopes are automatically included by msal
    ];
    // Initialize application
    MSAuth.userAgentApplication = new Msal.UserAgentApplication(
      config.clientID,
      null,
      function (errorDes, token, error, tokenType) {
        // this callback is called after loginRedirect OR 
        // acquireTokenRedirect (not used for loginPopup/aquireTokenPopup)
        logger.log("ms auth login redirect callback");
      },
      {
        redirectUri: config.redirectUri
      }
    );
  }

  static signIn(onSuccess: ()=>void, onError: (error)=>void){
    this.userAgentApplication.loginPopup(this.scopes).then(token => {
      const user = this.userAgentApplication.getUser();
      // signin successful
      logger.log("signin successful");
      this.getIdToken(idToken => {
        this.getAccessToken(aToken => {
          onSuccess();
        });
      });
    },
    error => {
      // handle error
      logger.log("signin error");
      onError(error);
    });
  }

  static getAccessToken(callback?: (success: boolean)=>void){
    // get an access token
    this.userAgentApplication.acquireTokenSilent(this.scopes).then(aToken => {
      logger.log("ATS promise resolved");
      logger.log("we got your access token");
      this.onReceiveAccessToken(aToken);
      if(callback){
        callback(true);
      }
    },
    error => {
      // interaction required 
      logger.log("slight hiccup, we need your help");
      if(error.indexOf("interaction_required") != -1){
          this.userAgentApplication.acquireTokenPopup(this.scopes).then(aToken => {
          // success
          logger.log("we got your access token at last");
          this.onReceiveAccessToken(aToken);
          if(callback){
            callback(true);
          }
        },
        error => {
          // error
          logger.log("we failed to get your access token :(");
          if(callback){
            callback(false);
          }
        });
      }
    });
  }

  static getIdToken(callback?: (success: boolean)=>void){
    // get an access token
    this.userAgentApplication.acquireTokenSilent([config.clientID]).then(idToken => {
      logger.log("ATS promise resolved");
      logger.log("we got your id token");
      this.onReceiveIdToken(idToken);
      if(callback){
        callback(true);
      }
    },
    error => {
      // interaction required 
      logger.log("slight hiccup, we need your help");
      if(error.indexOf("interaction_required") != -1){
          this.userAgentApplication.acquireTokenPopup([config.clientID]).then(idToken => {
          // success
          logger.log("we got your id token at last");
          this.onReceiveIdToken(idToken);
          if(callback){
            callback(true);
          }
        },
        error => {
          // error
          logger.log("we failed to get your id token :(");
          if(callback){
            callback(false);
          }
        });
      }
    });
  }

  static onReceiveAccessToken(aToken){
    //...set some other cookies
    ls.set("signedin", true);
  }

  static onReceiveIdToken(idToken){
    const decodedToken = jwtDecode(idToken);
    ls.set("name", decodedToken.name);
	//...set some other cookies
    ls.set("signedin", true);
  }

  static signOut(callback?: ()=>void){
    MSAuth.userAgentApplication.logout();
	// alt method
    // location.href = `https://login.microsoftonline.com/common/oauth2/v2.0/logout?post_logout_redirect_uri=${config.redirectUri}`;
    ls.clear();
    ls.set("signedin", false);
    if(callback){
      callback();
    }
  }
}

if(Msal){
  MSAuth.initialize();
}
else{
  logger.log("Could not load msal.js. Please connect to the internet");
}

There really isn't anything that seems out of place in the sign out function. It's just a simple call to logout().

@rohitnarula7176
Copy link
Contributor

@khalibloo This does not seem to be an issue with the library. The library correctly creates the logout request to send to the authorization endpoint. Closing this issue as this is out of scope.

@chinmayembedded
Copy link

When i do msal.logout(). my web application redirects me to home screen but in between i get this frameloader error screen.
2aa1a680-a514-4977-a1dc-82e6c0ad91a2

@mrlubos
Copy link

mrlubos commented Sep 7, 2018

Hey! Is there a way to do a silent logout?

@blindfish3
Copy link

I also experienced this issue: the post logout redirect isn't respected after calling logout in a React-based app. From what I've read elsewhere this could be some kind of timing issue...
It's not an ideal solution; but it appears you can achieve a 'clean' logout by opening a new window and calling logout from there. The user is left with an extra open window; but at least they've retained a view of the app and it hasn't lost state.

@yesoreyeram
Copy link

Guys . anyone got this working? BTW, Why this issue is in closed state?

@jasonnutter
Copy link
Contributor

@yesoreyeram The logout page not redirecting back to your app for MSA accounts is a known issue with the logout page (and the team that owns the logout page is aware). There isn't anything the library can do to fix this, which is why this issue is closed.

@yesoreyeram
Copy link

@jasonnutter thanks for confirming. Is there any authentic url to track this issue?

@jasonnutter
Copy link
Contributor

@yesoreyeram Nothing external from MSFT, unfortunately.

@chinmayembedded
Copy link

chinmayembedded commented Dec 18, 2019 via email

@jonenst
Copy link

jonenst commented Apr 3, 2020

The logout page not redirecting back to your app for MSA accounts is a known issue with the logout page (and the team that owns the logout page is aware). There isn't anything the library can do to fix this, which is why this issue is closed.

Hi @jasonnutter , is there news regarding this issue ? Could you please describe more specifically in what circumstances the redirect is working or not working as of april 2020 ?

we are hitting the same problem after redirecting to https://login.microsoftonline.com/<TENANT-ID>/oauth2/v2.0/logout?post_logout_redirect_uri=https%3A%2F%2Fmyhost%2Fmyapp%2F
We do have the exact same (but urldecoded) value of post_logout_redirect_uri configured as a reply url (in addition to the login call back url) in the azure portal.

Thanks in advance for your time

@jasonnutter
Copy link
Contributor

jasonnutter commented Apr 6, 2020

@jonenst For MSA accounts, the logout page should redirect back to your app if:

  • User has used/consented to the client app
  • Logout uri is https
  • Logout uri is registered as a reply uri in the portal
  • Logout uri is registered as the post logout url
  • Logout uri is set as auth.postLogoutRedirectUri in msal (and you call logout).

I just tested this with my personal MSA account and our React sample app and it worked.

@jonenst
Copy link

jonenst commented Apr 7, 2020

hi @jasonnutter , thanks for taking the time to answer. I still can't the redirect to work :(
could you please send the link to the exact code of the sample react app ? I would like to try it there.

Below is my setup, did I misunderstand one of your instructions ? Thanks in advance

Here's what I have:

  • edit /etc/hosts to have foobar.com resolve as 127.0.0.1 (not sure if localhost was allowed as a replyurl)
  • used the following portal conf
    ad
  • used the following msal conf
    msalconf

@jonenst
Copy link

jonenst commented Apr 7, 2020

Ok, just got it to work, using a personal account and the /common tenantid and v2.0 . Do you know the exact restrictions ...? Thanks in advance.
Jon

@jasonnutter
Copy link
Contributor

Ok, just got it to work, using a personal account and the /common tenantid and v2.0 . Do you know the exact restrictions ...? Thanks in advance.
Jon

Great, so sounds like you need to use /common in addition to the list of requirements above.

@suencien
Copy link

Hi guys! I still can't get it to redirect back to my site.

At OpenIdConnectAuthenticationOptions, I have the below option:
Authority = "https://login.microsoftonline.com/common/v2.0",
RedirectUri = "https://iluvrun.com/signin-oidc",
PostLogoutRedirectUri = "https://iluvrun.com"

And I have these two at Redirect URIs:
https://iluvrun.com/signin-oidc
https://iluvrun.com

After log out it's still stuck at https://login.microsoftonline.com/common/oauth2/v2.0/logoutsession

What do I have wrong Jon? :)

@jonenst
Copy link

jonenst commented Apr 12, 2020 via email

@suencien
Copy link

Hmm.. does you logout page performs logout function?
The user has actually been logged out before going to the Microsoft page. I tried forwarding it to another page but it doesn't work either.
If possible I like the user to be just directed to the home page instead.

@jonenst
Copy link

jonenst commented Apr 12, 2020 via email

@suencien
Copy link

suencien commented Apr 12, 2020 via email

@Riff451
Copy link

Riff451 commented Apr 28, 2020

It works only with a personal account

Any idea or reason on why this is working only with personal accounts? I understand this is probably not an issue with the library, but I couldn't find a better place to ask and this one seems to be the more up-to-date discussion about the topic. Thank you very much.

@jasonnutter
Copy link
Contributor

@Riff451 Redirecting back to the logout URL works with both personal and organizational accounts (see my guidance above, which also applies for organizational accounts).

@Riff451
Copy link

Riff451 commented Apr 29, 2020

@jasonnutter Hi, thanks for the reply. I probably should've mentioned that I'm using a B2C tenant even if I'm trying the standard Azure AD identity feature.
I've tried a couple of different combinations.
This is my common manifest for the urls:

"logoutUrl": "https://localhost:30444/logout"

"replyUrlsWithType": [
		{
			"url": "https://localhost:30444",
			"type": "Spa"
		},
		{
			"url": "https://localhost:30444/logout",
			"type": "Web"
		}
]

It works with all these values for the authority (with both personal and organizational accounts)

authority: "https://login.microsoftonline.com/consumers"
authority: "https://login.microsoftonline.com/organizations"
authority: "https://login.microsoftonline.com/common"

But if I try to use my tenantId or name (authority: "https://login.microsoftonline.com/<tenant_name>") the page gets stuck here:

image

I'm using my external aad organizational account in this scenario. The one automatically added as global admin during the B2C tenant creation.

Hope this is clear enough :) Thanks again!

@jasonnutter
Copy link
Contributor

@Riff451 Can you please open a new issue, thanks!

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Sep 2, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

15 participants