14

I'm using the following code for ExternalLoginCallback
In google everything is OK. but in Facebook and Microsoft loginInfo.Email is always null. What's wrong with the following code?

    [AllowAnonymous]
public async Task<ActionResult> ExternalLoginCallback(string returnUrl)
{
    ExternalLoginInfo loginInfo = await AuthenticationManager.GetExternalLoginInfoAsync();
    if (loginInfo == null)
    {
        return RedirectToAction("Login");
    }

    // loginInfo.Email is always null, so FindByEmailAsync throws an exception
    UserIdentityModel user = await UserManager.FindByEmailAsync(loginInfo.Email); 

    if (user != null)
    {
        await SignInAsync(user, false);
        return RedirectToLocal(returnUrl);
    }

    // If the user does not have an account, then prompt the user to create an account
    ViewBag.ReturnUrl = returnUrl;
    ViewBag.LoginProvider = loginInfo.Login.LoginProvider;
    return View("ExternalLoginConfirmation", new ExternalLoginConfirmationViewModel
    {
        UserName = loginInfo.DefaultUserName,
        Email = loginInfo.Email
    });
}

I'm using the following packages:

<package id="Microsoft.Owin" version="3.0.1" targetFramework="net45" />
  <package id="Microsoft.Owin.Host.SystemWeb" version="3.0.1" targetFramework="net45" />
  <package id="Microsoft.Owin.Security" version="3.0.1" targetFramework="net45" />
  <package id="Microsoft.Owin.Security.Cookies" version="3.0.1" targetFramework="net45" />
  <package id="Microsoft.Owin.Security.Facebook" version="3.0.1" targetFramework="net45" />
  <package id="Microsoft.Owin.Security.Google" version="3.0.1" targetFramework="net45" />
  <package id="Microsoft.Owin.Security.MicrosoftAccount" version="3.0.1" targetFramework="net45" />
  <package id="Microsoft.Owin.Security.OAuth" version="3.0.1" targetFramework="net45" />
  <package id="Microsoft.Owin.Security.Twitter" version="3.0.1" targetFramework="net45" />
2
  • Haven't yet used Microsoft oAuth, but with Facebook you need to specifically ask for email permissions in the configuration of your facebook app, otherwise you will not get the email address.
    – Stephen
    Commented Apr 26, 2015 at 15:18
  • I've done it, and I checked email. Commented Apr 27, 2015 at 2:09

4 Answers 4

22

I found the solution, We have to use Facebook and Microsoft as the following in Startup.Auth.cs file:

// Facebook
app.UseFacebookAuthentication(new FacebookAuthenticationOptions
{
    AppId = "---",
    AppSecret = "---",
    Scope = { "email" }
});

// Microsoft
app.UseMicrosoftAccountAuthentication(new MicrosoftAccountAuthenticationOptions()
{
    ClientId = "---",
    ClientSecret = "---",
    Scope = { "wl.basic", "wl.emails" }
});
6
  • I am facing the same problem for Yahoo OAuth2 authentication. The email is null after successful authentication. Do you have solution for Yahoo authentication please? Commented May 23, 2015 at 17:15
  • I have the same problem: stackoverflow.com/questions/29998559/… Commented May 24, 2015 at 8:13
  • 8
    After doing this, still info.Email is null for me. Commented Nov 23, 2015 at 17:01
  • After doing this, still info.Email is null for me Commented Mar 19, 2016 at 20:56
  • info.Email is null still.
    – Bimal Das
    Commented Jul 3, 2016 at 15:47
8
app.UseFacebookAuthentication(new FacebookAuthenticationOptions
            {
                AppId = "",
                AppSecret = "",
                BackchannelHttpHandler = new FacebookBackChannelHandler(),
                UserInformationEndpoint = "https://graph.facebook.com/v2.4/me?fields=id,name,email,first_name,last_name,location",
                Scope = { "email" }
            });

Create a class :

 public class FacebookBackChannelHandler : HttpClientHandler
    {
        protected override async System.Threading.Tasks.Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, System.Threading.CancellationToken cancellationToken)
        {
            // Replace the RequestUri so it's not malformed
            if (!request.RequestUri.AbsolutePath.Contains("/oauth"))
            {
                request.RequestUri = new Uri(request.RequestUri.AbsoluteUri.Replace("?access_token", "&access_token"));
            }

            return await base.SendAsync(request, cancellationToken);
        }
    }

works for me.

0
2

I had the same issue with Microsoft accounts, but only those which were associated with personal accounts (i.e. hotmail) and not business/school accounts. After trying several of the answers above, I was still not receiving the email address despite the user giving permission to my app.

In the end, what solved this for me was updating the OWIN packages in my project to version 4.0. After that, everything works as expected.

0

I tried Mohammed's answer. No dice. I tried Bimal's answer. No dice.

Finally, I upgraded all my OWIN references using Nuget. Now it works.

If the other answers don't work, try upgrading all your Nuget packages w/ respect to all the OWIN items.

Not the answer you're looking for? Browse other questions tagged or ask your own question.