Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
381 views
in Technique[技术] by (71.8m points)

c# - OWIN's GetExternalLoginInfoAsync Always Returns null

I've created a new MVC5 Web Application, and when I try to login with Google or Facebook, the ExternalLoginCallback Action in the AccountController is called, but GetExternalLoginInfoAsync() always returns null:

var loginInfo = await AuthenticationManager.GetExternalLoginInfoAsync();
if (loginInfo == null)
{
    return RedirectToAction("Login");
}

Because it's always null, it just redirects back to the login page and the process starts over. How can I fix this?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

To get OWIN Google login to work properly on a standard Visual Studio 2013, ASP.Net MVC5 site, I had to:

  1. Setup a Google OpenId account at https://console.developers.google.com/project

  2. Set the callback URL there to blah/signin-google.
    Important notes on things you don't need to do:

    • You don't need to use HTTPS for Google to redirect back; you can even redirect back to plain http://localhost, no problem.

    • You don't need to setup anything for the redirect URL - no routes, Controller Actions or special permissions in Web.Config. The redirect URL is always /signin-google and OWIN handles this behind the scenes for you.

As an example, if your site was me.com, you might have these 3 callback URLs in the Google Developer Console:

http://localhost:53859/signin-google
http://test.me.com/signin-google
https://me.com/signin-google

The first one including whatever port number VS gave you for your project.

  1. Enable the Google+ API. This is one hidden b**** of a gotcha and is the root cause of the problem in the question here - if you don't do this, it's easy to miss that the Request to /account/ExternalLoginCallback includes &error=access_denied, and that's because Google said no to a permissions request OWIN made for the user's Google+ basic profile. I can't tell whose fault this is, Google's or Microsoft's.

To enable the Google+ API in the Developers Console, click APIs on the left, hunt for Google+, click that and hit Enable. Yes you really do need to do that. You're hosed if you don't do that.

  1. Add the ClientId and ClientSecret Google gave you in the Developers Console to Startup.Auth, but improve the code in the process to explicitly use OAuth2, and explicitly ask for the user's email address:

    var google = new GoogleOAuth2AuthenticationOptions()
    {
        ClientId = "123abc.apps.googleusercontent.com",
        ClientSecret = "456xyz",
        Provider = new GoogleOAuth2AuthenticationProvider()
    };
    google.Scope.Add("email");
    app.UseGoogleAuthentication(google);
    

That's it. That finally got it working.

Just want to reiterate one more time, there are a LOT of answers about this and issues like it where OWIN/Google isn't working, and nearly all of them are wrong for the current VS2013/MVC5/OWIN template.
You don't need to modify Web.Config at all.
You don't need to create any special Routes whatsoever.
You should not attempt to point /signin-google to a different place, or use a different callback URL, and you definitely shouldn't attempt to tie it directly to /account/externallogincallback or externalloginconfirmation, because those are both separate from /signin-google and necessary steps in the OWIN/Google process.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...