AuthenticationManager.GetExternalLoginInfo returns

2019-07-20 19:56发布

问题:

I am using the standard MVC template in VS2013 and have enabled external logins. It works fine, and I am now adding some features.

I find that AuthenticationManager.GetExternalLoginInfo works fine in the ExternalLoginCallback action. However, if I have it anywhere else, it always returns null, even if the user is logged in. I did a test by adding the following in the Account controller:

    [Authorize]
    public async Task<ActionResult> Test()
    {
        Debug.Assert(User.Identity.IsAuthenticated);
        var loginInfo = await AuthenticationManager.GetExternalLoginInfoAsync();
        ViewBag.Provider = loginInfo.Login.LoginProvider;
        return View();
    }

The Account controller requires authorization but I added the Authorize attribute just to be doubly sure. I tried with both Twitter and Google accounts (user has to be successfully logged in to execute this code), GetExernalLoginInfo will always return null in the above method. I have only external accounts, and there are no accounts with local passwords so there is no chance that a local user was logged in by accident.

Why does it not work? Doesn't GetExternalLoginInfo derive the result from the cookies?

Edits: Applying the UseKentorOwinCookieSaver patch from ASP.NET_SessionId + OWIN Cookies do not send to browser didn't help either.

回答1:

It happens because the MVC template uses the SignInManager class. Because of that, by default all users are signed in locally, also after logging in with an external account.

In the ExternalLoginCallback method there is the following line:

var result = await SignInManager.ExternalSignInAsync(loginInfo, isPersistent: false);

This signs out the external userinfo, and signs in the local user with an ApplicationCookie. If you take a look at the AuthenticationManager after this line is executed, you will see an AuthenticationResponseGrant.AuthentityType=ApplicationCookie and AuthenticationResponseRevoke.AuthenticationType=ExternalCookie.

Eventually the ExternalCookie is removed when the Owin middleware inspects the context. That way AuthenticationManager.GetExternalLoginInfo() returns null after logging in, the cookie holding the info has been removed and replaced by a ApplicationCookie.