Подтвердить что ты не робот

OWIN GetExternalLoginInfoAsync всегда возвращает null

Я создал новое веб-приложение MVC5, и когда я пытаюсь войти в систему с помощью Google или Facebook, вызывается ExternalLoginCallback Действие в AccountController, но GetExternalLoginInfoAsync() всегда возвращает null:

var loginInfo = await AuthenticationManager.GetExternalLoginInfoAsync();
if (loginInfo == null)
{
    return RedirectToAction("Login");
}

Поскольку он всегда равен нулю, он просто перенаправляет обратно на страницу входа в систему, и процесс начинается. Как я могу это исправить?

4b9b3361

Ответ 1

Чтобы OWIN Google мог нормально работать на стандартном сайте Visual Studio 2013, ASP.Net MVC5, мне пришлось:

  1. Настройте учетную запись Google OpenId по адресу https://console.developers.google.com/project.

  2. Установите URL-адрес обратного вызова на blah/signin-google.
    Важные замечания о том, что вам не нужно делать:

    • Вам не нужно использовать HTTPS для Google, чтобы перенаправить обратно; Вы даже можете перенаправить обратно на обычный http://localhost, без проблем.

    • Вам не нужно ничего настраивать для URL перенаправления - никаких маршрутов, действий контроллера или специальных разрешений в Web.Config. URL перенаправления всегда /signin-google, и OWIN справляется с этим за кулисами.

Например, если ваш сайт был me.com, у вас могут быть эти 3 URL-адреса обратного вызова в консоли разработчика Google:

http://localhost:53859/signin-google
http://test.me.com/signin-google
https://me.com/signin-google

Первый, включая номер порта, который VS дал вам для вашего проекта.

  1. Включить API Google+. Это одна скрытая &error=access_denied и является основной причиной проблемы в этом вопросе - если вы не сделаете этого, легко пропустить, что Запрос к /account/ExternalLoginCallback включает &error=access_denied, и это потому, что Google сказал "нет" запросу OWIN для основного профиля пользователя Google+. Я не могу сказать, чья это вина, Google или Microsoft.

Чтобы включить API Google+ в консоли разработчика, нажмите API слева, найдите Google+, щелкните его и нажмите "Включить". Да, вам действительно нужно это сделать. Тебя ждут, если ты этого не делаешь.

  1. Добавьте ClientId и ClientSecret, которые Google дал вам в консоли разработчика, в Startup.Auth, но улучшите код в процессе, чтобы явно использовать OAuth2, и явно запросите адрес электронной почты пользователя:

    var google = new GoogleOAuth2AuthenticationOptions()
    {
        ClientId = "123abc.apps.googleusercontent.com",
        ClientSecret = "456xyz",
        Provider = new GoogleOAuth2AuthenticationProvider()
    };
    google.Scope.Add("email");
    app.UseGoogleAuthentication(google);
    

Это. Это наконец заставило это работать.

Просто хочу повторить еще раз, есть много ответов на этот счет и такие вопросы, как, когда OWIN/Google не работает, и почти все они не соответствуют текущему шаблону VS2013/MVC5/OWIN.
Вам вообще не нужно изменять Web.Config.
Вам не нужно создавать какие-либо специальные маршруты вообще.
Вы не должны пытаться указать /signin-google в другое место или использовать другой URL-адрес обратного вызова, и вам определенно не следует пытаться привязать его напрямую к /account/externallogincallback или externalloginconfirmation, потому что оба они отделены от /signin-google и необходимые шаги в процессе OWIN/Google.

Ответ 2

Хорошо, я узнал, почему это null. Вы должны включить Google + API в консоли Google. Также убедитесь, что секретный ключ не конкатенируется с пробелом в конце после того, как вы вставляете его в свой код. Почему они не могут вернуть нормальную ошибку? Я не знаю.

Ответ 3

Кажется, что пакет Nuget Microsoft.Owin.Security.Facebook версии 3.0.1 больше не работает с входом в Facebook.

Обновите этот пакет до версии 3.1.0 перед выпуском, вы можете использовать следующее:

Установочный пакет Microsoft.Owin.Security.Facebook -Pre

Ответ 4

Как правильно говорили другие, большую часть времени, потому что у вас нет прав на Google+ API, вот как получить разрешение на проект в Google API Manager на Google+ API

Шаг 1. Выберите "Проект" из верхнего списка со списком и перейдите в "Панель управления" > "Включить API". введите описание изображения здесь

Шаг 2: Найдите Google плюс и выберите его. введите описание изображения здесь

Шаг 3: Включите его! введите описание изображения здесь

если вы вернетесь на панель управления для этого проекта, вы можете увидеть список разрешенных API для этого проекта внизу введите описание изображения здесь

Ответ 5

Я знаю это глупо, но после долгой борьбы перезапуск IIS решил проблему для меня.

Ответ 6

Это решило мою проблему:

Включить API Google+. Это вопрос и является основной причиной проблемы в этом вопросе. Если вы этого не сделаете, легко пропустить, что запрос на /account/ExternalLoginCallback включает &error=access_denied, и это потому, что Google не ответил на разрешения запросите OWIN для основного профиля Google+. Я не могу сказать, чья это вина, Google или Microsoft.

Чтобы включить Google+ API в Консоли разработчиков, щелкните API слева, найдите Google+ и нажмите "Включить".

Ответ 7

Я получил его для работы, просто обновив весь пакет самородок в приложении, и он сработал.

Ответ 8

Я сделал следующее, чтобы заставить его работать.

Войдите в портал разработчика, найдите свое приложение и выполните следующие действия.

Сведения о приложении > Приложения, ориентированные в список Платные платформы > Выберите Да для веб-сайта

Ответ 9

Сегодня я столкнулся с этой проблемой, и выяснилось, что я определил удаленный файл cookie после того, как я назначил поставщиков.

Убедитесь, что вы разместили...

app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);

раньше...

app.UseFacebookAuthentication(
                   appId: "",
                   appSecret: "");

Ответ 10

Для тех, кто испытывает эту проблему для Web Api. Другие решения не помогают AuthenticationManager.GetExternalLoginInfoAsync(); возвращает всегда ноль, даже если Google Plus API включен.

используйте эту пользовательскую функцию для получения логина. очевидно, у Microsoft есть ошибка для GetExternalLoginInfoAsync при запросе через веб-API.

private async Task<ExternalLoginInfo> AuthenticationManager_GetExternalLoginInfoAsync_WithExternalBearer()
        {
            ExternalLoginInfo loginInfo = null;

            var result = await Authentication.AuthenticateAsync(DefaultAuthenticationTypes.ExternalBearer);

            if (result != null && result.Identity != null)
            {
                var idClaim = result.Identity.FindFirst(ClaimTypes.NameIdentifier);
                if (idClaim != null)
                {
                    loginInfo = new ExternalLoginInfo()
                    {
                        DefaultUserName = result.Identity.Name == null ? "" : result.Identity.Name.Replace(" ", ""),
                        Login = new UserLoginInfo(idClaim.Issuer, idClaim.Value)
                    };
                }
            }
            return loginInfo;
        }

Ответ 11

Хотя ответы выше все хорошо, в моем случае ни один из них не работал - я проверил и дважды проверил настройки Google и согласился с Крисом Москини, что там много вводящей в заблуждение информации.

Для меня это был момент, когда я понял, что моя служба "Не работающая" не была запущена! Никаких ошибок (поскольку логин был первым, что я пытался после перезагрузки, когда государственная служба настроена на ручной запуск на машине), просто Null от GetExternalLoginInfoAsync

Надеюсь, это поможет кому-то другому.

Ответ 12

После долгих поисков и царапин на голове, а также после многочисленных ответов красной селедки здесь, в Stackoverflow, я в конце концов просмотрел все свои варианты на своей консоли Google dev и обнаружил немного синюю кнопку [Enable] на странице обзора API Google+. Я нажал на эту кнопку, и это было хорошо. Забудьте обо всех балонях, которые вы читаете о настройках URL-адреса обратного вызова и маршрута, OWIN в любом случае переопределяет URL-адрес google default/signin-google redirect uri и отправляет вас обратно в ExternalLoginCallback. Просто придерживайтесь реализации по умолчанию, все будет хорошо, пока вы включите свой Google + API.

Ответ 13

Я тоже хотел внести свой вклад в это. Я недавно получил эту работу. У меня возникла проблема с возвратом GetExternalLoginInfoAsync, но только в процессе производства.

После большого поиска я наконец нашел свой ответ, это была просто проблема с моей базой данных. В производстве я установил неправильную строку соединения, чтобы она не подключалась должным образом, но в основном молчала об этом. Единственное, что произошло, это GetExternallLoginInfoAsync, которое возвращает null. Поэтому проверьте строку подключения к базе данных, если это произойдет!

Кроме того, на стороне, единственное, что было необходимо для получения этой работы, было:

  • Настроить проект в консоли Google
  • Включить API Google+
  • Скопируйте идентификатор клиента и секрет клиента в файл Startup.Auth.cs.

Вам не нужно включать HTTPS, вам не нужно создавать собственные маршруты. Но убедитесь, что ваша база данных работает правильно!

Ответ 14

Это правда, что вам понадобится Google плюс включен. Большой вещью для меня был URL проекта. Откройте окно свойств (Вид → Окно свойств) в VS, а затем щелкните правой кнопкой мыши проект и выберите свойства. В небольшом окне свойств скопируйте свой URL-адрес SSL, а затем в более крупном окне свойств выберите вкладку Web и вставьте этот URL-адрес в URL-адрес проекта.

Исправлена проблема для меня.

См. Более подробно: https://docs.microsoft.com/en-us/aspnet/mvc/overview/security/create-an-aspnet-mvc-5-app-with-facebook-and-google-oauth2-and -openid-вход

Ответ 15

Для меня я был старым, но работающим веб-сайтом .NET 4.6.1 MVC до ядра 1.1. Работа остановилась, прежде чем я смог заставить ее работать, когда я поднял ее обратно, я затем перешел на 2.x.

Моя проблема заключалась в том, что ответный звонок от Google был встречен с 404 с моего сайта. Я думал, что это должно было поразить AccountController.ExternalLoginCallback поэтому я добавил [Route(...)] к нему и, конечно же, обратный вызов Google попал в действие.

Это тогда поражает null возвращенный в этой строке (какой маньяк возвращает null?)

var externalLoginInfo = await this.SignInManager.GetExternalLoginInfoAsync();

Я реверс-инжиниринг этого, чтобы найти под капотом его в конечном итоге получить обработчик для ExternalScheme который для меня был обработчиком куки!

Все казалось неправильным, и я как-то почувствовал, что промежуточное ПО должно было просто перехватить URI обратного вызова, поэтому я удалил свой [Route(...)] и проблема 404 вернулась.

Затем я обнаружил, что мне нужно добавить это во время запуска.

applicationBuilder.UseAuthentication();

Это решает 404 но дает другую проблему.

Схема authenticationScheme не указана, а DefaultSignInScheme не найден.

Добавив схему по умолчанию здесь, я устраняю ошибку выше.

serviceCollection.AddAuthentication(IdentityConstants.ExternalScheme)
    .AddGoogle(googleOptions => Configuration.Bind("OAuth2:Providers:Google", googleOptions))
    .AddExternalCookie();

Теперь AccountController.ExternalLoginCallback снова вызывается каким-то волшебством, но я вернулся к null возвращаемому значению.

Я добавил этот код над оскорбительной строкой, что, по сути, и происходит под капотом (глядя на код Microsoft на GitHub). Интересно, что h имеет тип CookieAuthenticationHandler и имеет все мои требования и информацию от Google внутри! a

var authHandler = this.HttpContext.RequestServices.GetRequiredService<IAuthenticationHandlerProvider>();
var h = await authHandler.GetHandlerAsync(this.HttpContext, IdentityConstants.ExternalScheme);
var a = await h.AuthenticateAsync();

var externalLoginInfo = await this.SignInManager.GetExternalLoginInfoAsync();

Копаясь в GitHub и копируя вставленный внутренний код, который он запускает, в мой контроллер, я вижу, что ему не удалось найти ClaimTypes.NameIdentifier в моих утверждениях, это ProviderKey используемый позже.

Хм....

Обеспокоенный тем, что я использовал старый код 1.x AccountController с новыми битами идентификации 2.x, я нашел несколько примеров, которые все еще используют этот материал, и некоторые примеры, которые также используют Razor Pages для всего этого. Я продолжу с тем, что у меня есть.

Далее я собираюсь исследовать сопоставление дополнительных элементов полезной нагрузки JSON пользователя Google с утверждениями. Я думаю, что если бы идентификатор моей учетной записи Google (я думаю, числовой) был сопоставлен, тогда все работало бы.

https://docs.microsoft.com/en-us/aspnet/core/security/authentication/social/additional-claims?view=aspnetcore-2.2

Окончательное исправление

Я наконец-то решил проблему, добавив "действие по иску", чтобы вытащить мой идентификатор Google из JSON, возвращаемого из Google!

serviceCollection.AddAuthentication(IdentityConstants.ExternalScheme)
    .AddGoogle(googleOptions =>
    {
        Configuration.Bind("OAuth2:Providers:Google", googleOptions);

        googleOptions.ClaimActions.MapJsonKey(ClaimTypes.NameIdentifier, "sub", "string");
    })
    .AddExternalCookie();

К sub поле содержит то, что в конечном итоге заканчивается в nameidentifier претензии, а затем в ProviderKey, что AccountController хочет.

Ответ 16

Все остальные ответы не разрешили это для меня, поэтому, если вы в той же лодке, убедитесь, что действие вашего контроллера регистрации имеет атрибут RequireHttps:

    // GET: /Account/LoginRegister
    [AllowAnonymous]
    [RequireHttps]
    public ActionResult LoginRegister()
    {
        return View(new RegisterLoginViewModel());
    }