Search code examples
asp.net-coreasp.net-identity

User isn't authenticated with external login


I use dotnet core v2.0.0. I've migrated my authentication following this post: https://go.microsoft.com/fwlink/?linkid=845470

Currently it looks like this:

public void ConfigureServices(IServiceCollection services)
{
    services
        .AddDbContext<DatabaseContext>()
        .AddIdentity<AppUser, IdentityRole>()
        .AddEntityFrameworkStores<DatabaseContext>()
        .AddDefaultTokenProviders();

    services
        .AddAuthentication()
        .AddFacebook(o => {
            o.AppId = "my id";
            o.AppSecret = "my secret";
        });

    services
        .AddAuthorization()
        .AddRouting()
        .AddMvc();
}

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory, IServiceProvider serviceProvider)
{
    app.UseWebSockets();
    app.UseAuthentication();
    ServiceProvider = serviceProvider;
    Routing.AddRoutes(app);

    app.UseStaticFiles();
    app.UseMvc();
}

And the callback:

[Route("api/account/external")]

public async Task<IActionResult> GetExternalLogin(string provider, string error = null)
{
    if (error != null)
    {
        return BadRequest(Uri.EscapeDataString(error));
    }

    // info is null
    // but HttpContext.Request.Cookies does contain a cookie
    var info = await _signInManager.GetExternalLoginInfoAsync();

    ....
}

Form-based registration and authentication works. When I try to use Facebook login, I'm redirected to the login window, can enter my password, and am redirected back to my application.

A cookie named Identity.External is created and sent through the request. But my user isn't authenticated and I don't have any claim. Why isn't Identity using the cookie? If I can't access it through SignInManager, is there any way to read the provider key by parsing the cookie?


Solution

  • I've finally found a workaround! It seems I can get all the info I need through AuthenticateAsync:

    var auth = await HttpContext.AuthenticateAsync(IdentityConstants.ExternalScheme);
    var principal = auth.Principal;
    var providerKey = auth.Principal.Claims.FirstOrDefault();
    

    Provider is "Facebook", providerKey.Value is provider key, and I can get the username through auth.Principal.Identity.Name.