2

I'm implementing REST API using ASP.NET WEB API 2.I have default AccountController implementation with method for // GET api/Account/ExternalLogin.

[OverrideAuthentication]
[HostAuthentication(DefaultAuthenticationTypes.ExternalCookie)]
[AllowAnonymous]
[Route("ExternalLogin", Name = "ExternalLogin")]
public async Task<IHttpActionResult> GetExternalLogin(string provider, string error = null)
{
    if (error != null)
    {
        return Redirect(Url.Content("~/") + "#error=" + Uri.EscapeDataString(error));
    }

    if (!User.Identity.IsAuthenticated)
    {
        return new ChallengeResult(provider, this);
    }

    ExternalLoginData externalLogin = ExternalLoginData.FromIdentity(User.Identity as ClaimsIdentity);

    if (externalLogin == null)
    {
        return InternalServerError();
    }

    if (externalLogin.LoginProvider != provider)
    {
        Authentication.SignOut(DefaultAuthenticationTypes.ExternalCookie);
        return new ChallengeResult(provider, this);
    }

    ApplicationUser user = await UserManager.FindAsync(new UserLoginInfo(externalLogin.LoginProvider,
        externalLogin.ProviderKey));

    bool hasRegistered = user != null;

    if (hasRegistered)
    {
        Authentication.SignOut(DefaultAuthenticationTypes.ExternalCookie);

         ClaimsIdentity oAuthIdentity = await user.GenerateUserIdentityAsync(UserManager,
            OAuthDefaults.AuthenticationType);
        ClaimsIdentity cookieIdentity = await user.GenerateUserIdentityAsync(UserManager,
            CookieAuthenticationDefaults.AuthenticationType);

        AuthenticationProperties properties = ApplicationOAuthProvider.CreateProperties(user.UserName);
        Authentication.SignIn(properties, oAuthIdentity, cookieIdentity);
    }
    else
    {
        IEnumerable<Claim> claims = externalLogin.GetClaims();
        ClaimsIdentity identity = new ClaimsIdentity(claims, OAuthDefaults.AuthenticationType);
        Authentication.SignIn(identity);
    }

    return Ok();
}

I've looked through the Internet and did not find anything applicable to this situation.

URL I use

https_://_www.dummydomain.com:43363/api/Account/ExternalLogin?provider=Google&response_type=token&client_id=self&redirect_uri=https%3A%2F%2Fwww.dummydomain.com%3A43363%2F&state=jI4zGXuaVvHI8qf9E0Nww3qBwke0YsYwD9AORwKBj3o1

Every external service (Google/FB) works correclty. I see AspNet.ExternalCookie is set, but redirecting back I'm not authorized and get

{
  email:null,
  hasRegistred: true,
  loginProvaider: null
}

Update 1

Properties dictionary of Request property at AppController does not contain MS_UserPrincipal.

See screenshot attached. Properties keys

Request.Properties["MS_HttpContext"] returns: (see screenshot) MS_HttpContextobject

Helga Lukava
  • 21
  • 1
  • 4

1 Answers1

0

It's unable to use HttpContext property directly in APIController. To get this , you have to make use of Request property of type System.Net.Http.HttpRequestMessage. HttpRequestMessage has a Properties dictionary; you will find the value of the key MS_UserPrincipal holds your IPrincipal object.

alaa_sayegh
  • 2,141
  • 4
  • 21
  • 37
  • This does not work for me. MS_UserPrincipal seems to be missed. Please take a look at the screenshot https://www.screencast.com/t/FpMDjU1O. – Helga Lukava Aug 10 '17 at 15:55