简体   繁体   中英

Why does OAuth fail when using ASP.NET Identity Core?

I have an ASP.NET Core 2.x project with the following configuration:

services
  .AddAuthentication(options => options.DefaultScheme = CookieAuthenticaitonDefaults.AuthenticationScheme)
  .AddCookie(CookieAuthenticationDefaults.AuthenticationScheme)
  .AddFacebook(ConfigureFacebook);

Predictably, when I call from one of my actions:

return Challenge(new AuthenticationProperties { RedirectUri = "/test" }, "Facebook");

... Then, I get navigated through the Facebook OAuth sequence. When I find my way back to my app, HttpContext.User.Identity is populated with the relevant details:

  • User.Identity.Name - The Facebook user name.
  • User.Identity.AuthenticationType - The string "Facebook" .
  • User.Identity.IsAuthenticated - true .

This is all well and as is expected. However, if I add to my application configuration the following

services.AddIdentity<MyUserType, MyRoleType>()
  .AddEntityFrameworkStores<MyDbContext>();

Suddenly, the OAuth flow ends in User.Identity being anonymous without anything else changing. If we drill into IdentityServiceCollectionExtensions.cs, we find:

options.DefaultAuthenticateScheme = IdentityConstants.ApplicationScheme; options.DefaultChallengeScheme = IdentityConstants.ApplicationScheme; options.DefaultSignInScheme = IdentityConstants.ExternalScheme;

among other things...

What is going on here? Why is Identity interfering with the Cookie process, and what is the correct way to get the User returned from an OAuth provider?

For combining OAuth and Asp.Net Core Identity, you need to configure the facebookOptions.SignInScheme with CookieAuthenticationDefaults.AuthenticationScheme .

Try code below:

services
    .AddAuthentication(options => options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme)
    .AddCookie(CookieAuthenticationDefaults.AuthenticationScheme)
    .AddFacebook(facebookOptions =>
    {
        facebookOptions.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
        facebookOptions.AppId = "xx";
        facebookOptions.AppSecret = "xxx";
    });

When combining ASP.NET Identity and OAuth, certain considerations need to be made:

Configuring the services:

Adding AddCookie(CookieAuthenticationDefaults.AuthenticationScheme) is no longer necessary because Identity adds its own cookie handlers.

Getting the external user as a ClaimsPrincipal:

If you want the external user to be populated under HttpContext.User , do the following:

.AddFacebook(options => {
    options.SignInScheme = IdentityConstants.ApplicationScheme;
})

After being redirected to the RedirectUri in your challenge's AuthenticationProperties , your HttpContext.User will be populated.

Getting the external user as ExternalLoginInfo :

This is preferred if you need to know things about the user such as:

  1. From what provider did they come?
  2. What is their unique key on the provider?

Your services should be configured like so:

services.AddAuthentication()
    .AddFacebook(options =>
    {
        options.AppId = "";
        options.AppSecret = "";
    });

services.AddIdentity<IdentityUser, IdentityRole>()
    .AddEntityFrameworkStores<MyDbContext>();

In your login controller, inject SignInManager<TUser> in:

public DefaultController(SIgnInManager<IdentityUser> signInManager)

And in your challenge action, use ConfigureExternalAuthenticationProperties to get the challenge properties:

public IActionResult LoginExternal() {
    var props = SignInManager.ConfigureExternalAuthenticationProperties("Facebook", "/");
    return Challenge(props, "Facebook");
}

In your return action, use GetExternalLoginInfoAsync to get the external details about the user:

public async Task<IActionResult> LoginCallback() {
    var loginInfo = await SignInManager.GetExternalLoginInfoAsync();
    // This object will tell you everything you need to know about the incoming user.
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM