Почему происходит сбой OAuth при использовании ASP.NET Identity Core? - PullRequest
1 голос
/ 19 марта 2019

У меня есть проект ASP.NET Core 2.x со следующей конфигурацией:

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

Как и ожидалось, когда я звоню с одного из моих действий:

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

... Затем я перехожу через последовательность OAuth на Facebook. Когда я возвращаюсь к своему приложению, HttpContext.User.Identity заполняется соответствующей информацией:

  • User.Identity.Name - имя пользователя Facebook.
  • User.Identity.AuthenticationType - Строка "Facebook".
  • User.Identity.IsAuthenticated - true.

Это все хорошо и, как ожидается. Однако, если я добавлю в свою конфигурацию приложения следующее

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

Внезапно поток OAuth заканчивается User.Identity анонимностью без каких-либо изменений. Если мы углубимся в IdentityServiceCollectionExtensions.cs, мы найдем:

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

между прочим ...

Что здесь происходит? Почему идентификация мешает процессу Cookie и как правильно вернуть пользователя от поставщика OAuth?

Ответы [ 2 ]

2 голосов
/ 19 марта 2019

Для объединения OAuth и Asp.Net Core Identity необходимо настроить facebookOptions.SignInScheme с CookieAuthenticationDefaults.AuthenticationScheme.

Попробуйте код ниже:

services
    .AddAuthentication(options => options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme)
    .AddCookie(CookieAuthenticationDefaults.AuthenticationScheme)
    .AddFacebook(facebookOptions =>
    {
        facebookOptions.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
        facebookOptions.AppId = "xx";
        facebookOptions.AppSecret = "xxx";
    });
1 голос
/ 19 марта 2019

При объединении удостоверений ASP.NET и OAuth необходимо учитывать следующие факторы:

Настройка услуг:

Добавление AddCookie(CookieAuthenticationDefaults.AuthenticationScheme) больше не требуется, поскольку Identity добавляет свои собственные обработчики файлов cookie.

Получение внешнего пользователя в качестве ClaimsPrincipal:

Если вы хотите, чтобы внешний пользователь был заполнен под HttpContext.User, сделайте следующее:

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

После перенаправления на RedirectUri в вашем вызове AuthenticationProperties ваш HttpContext.User будет заполнен.

Получение внешнего пользователя как ExternalLoginInfo:

Это предпочтительно, если вам нужно знать что-то о пользователе, например:

  1. От какого провайдера они пришли?
  2. Какой у них уникальный ключ у провайдера?

Ваши сервисы должны быть настроены так:

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

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

В вашем контроллере входа введите SignInManager<TUser> in:

public DefaultController(SIgnInManager<IdentityUser> signInManager)

А в вашем задании на вызов используйте ConfigureExternalAuthenticationProperties, чтобы получить свойства задания:

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

В ответном действии используйте GetExternalLoginInfoAsync, чтобы получить внешние данные о пользователе:

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