Аутентификация MVC OAuth с помощью Salesforce возвращается на страницу входа в систему

Я пытаюсь получить рабочий пример аутентификации приложения MVC в .NET против Salesforce, используя свой рабочий процесс проверки подлинности OAuth. Я ссылаюсь на это пошаговое руководство, которое довольно просто. Это очень похоже на то, чтобы работать с аутентификацией Google. Это сводится к настройке проекта .NET MVC с помощью индивидуального шаблона проверки подлинности учетной записи и развертыванию нового подключенного приложения в Salesforce. Затем добавьте библиотеку Owin.Security.Providers для Salesforce, скорректируйте Startup.Auth.cs и включите ClientId и ClientSecret из приложения Salesforce, а также конечные точки авторизации и токена. Предлагаемый URL-адрес обратного вызова http://localhost:[port]/signin-salesforce, который очень похож на URL-адрес обратного вызова, используемый для аутентификации Google.

Пока я перенаправлен в Salesforce и могу войти в систему, рукопожатие, возвращающее меня обратно в мое приложение MVC, похоже, сталкивается с проблемой, которую я не могу прибить. Я перенаправляюсь обратно на страницу входа в систему, и .NET, похоже, не знает о моей учетной записи, хотя у меня определенно есть активный сеанс с Salesforce (панель управления Salesforce автоматически войдет в систему). В коде все начинается здесь:

// GET: /Account/ExternalLoginCallback
[AllowAnonymous]
public async Task<ActionResult> ExternalLoginCallback(string returnUrl)
{
    var loginInfo = await AuthenticationManager.GetExternalLoginInfoAsync();
    if (loginInfo == null)
    {
        return RedirectToAction("Login");
    }
    //more code we never reach
}

loginInfo всегда равно нулю. Итак, чтобы выяснить, какой запрос отправляется на .NET, я обратился к Fiddler и встретил запрос от localhost:[port]/signin-salesforce с кучей параметров, который вызывает любопытный ответ:

HTTP/1.1 302 Найдено

Местоположение:/Account/ExternalLoginCallback? error = access_denied

Сервер: Microsoft-IIS/10.0

Set-Cookie:.AspNet.Correlation.Salesforce =; Путь =/; expires = Thu, 01-Jan-1970 00:00:00 GMT

X файлы исходного кода:??? = UTF-8 В YzpcdXNlcnNcc3RldmUuY2FtaXJlXGRvY3VtZW50c1x2aXN1YWwgc3R1ZGlvIDIwMTVcUHJvamVjdHNcU2FsZXNGb3JjZUludGVncmF0aW9uXFNhbGVzRm9yY2VJbnRlZ3JhdGlvblxzaWduaW4tc2FsZXNmb3JjZQ == =

X-Powered-By: ASP.NET

Дата: Пт, 20 мая 2016 21:46:09 GMT

Content-Length: 0

Обратите внимание на заголовок Location, который указывает .NET на перенаправление на /Account/ExternalLoginCallback с параметром ошибки "access_denied". Включение некоторой трассировки в Owin показывает, что что-то возвращает 400 либо в .NET, либо в .NET, но я не знаю, что.

Итак, вот где я. A null loginInfo в моем контроллере и свидетельствует о том, что в некоторых веб-запросах что-то не так. Я просмотрел несколько других связанных вопросов, но почти никто не фокусируется на SalesForce, и они предоставляют ответы, которые на самом деле не применимы (например, у меня нет API Google+ для включения). Любые идеи о том, как исправить это?

Ответ 1

Похоже, что URI переадресации должен соответствовать таковому на сервере Identity. Когда вы снова перенаправляетесь на страницу входа в систему, похоже, что URI переадресации может не совпадать с секретом клиента и идентификатором клиента.

В сервере SalesForce Identity появится URL-адрес перенаправления, который определит путь, по которому вы будете перенаправлены после завершения проверки подлинности. Иногда вам также необходимо предоставить URI идентификатор клиента и секрет, чтобы получить полное разрешение.

Ответ 2

Я бы проверить Startup.Auth.cs и убедиться, что ваша организация имеет правильный экземпляр, и вы не используете тот, который находится в пошаговом руководстве (если оно отличается). Например, моя организация начинается с na10.salesforce.com. В пошаговом руководстве используется ap1.salesforce.com.

    AuthorizationEndpoint = "https://**ap1**.salesforce.com/services/oauth2/authorize",
    TokenEndpoint = "https://**ap1**.salesforce.com/services/oauth2/token"

Я также гарантирую, что файлы cookie и кеш будут очищены. Например, я выпустил совершенно новый проект VS 2015 MVC без какой-либо информации OAuth, и я был зарегистрирован через поставщика SFDC. Нет идентификатора клиента, секрет, даже раздел SFDC!

Я сделал пошаговое руководство и смог пройти аутентификацию с SFDC OAuth. Как вы сказали, это было очень просто. Я бы не разорвал ваш код так, чтобы беспокоиться о чем-то простом.

Ответ 3

Я также продолжил загрузку кода Owin.Security.Providers.Salesforce и добавил его в мою ссылку на проект, чтобы иметь возможность отлаживать проблему. Я узнал, что когда выполнялся ответ на своп-код oauth, я получил исключение для "Код состояния ответа, который не указывает на успех: 400 (требуется TLS 1.1 или выше)". Я работал над песочницей, и Salesforce отключил TLS 1.0 начиная с июня 2016 года. Поэтому добавление этой строки кода в моем контроллере контролера учетных записей устранило мою проблему:

 System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;

Ответ 4

Для всех, у кого проблемы с loginInfo всегда возвращаются, когда это действительно не должно быть, это может не исправить вашу проблему, однако я провожу дни по аналогичной проблеме с facebook и google. Я закончил очистку сеанса HttpContext до вызова ExternalLoginCallback, и с тех пор он работает отлично. Не сказать, что это исправит, но, надеюсь, это поможет кому-то.

//
// POST: /Account/ExternalLogin
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public ActionResult ExternalLogin(string provider, string returnUrl)
{
    // Clear any other session first as this seems to cause unexpected null responses.
    if (ControllerContext.HttpContext.Session != null)
    {
        ControllerContext.HttpContext.Session.RemoveAll();
    }

    // Request a redirect to the external login provider
    return new ChallengeResult(provider, Url.Action("ExternalLoginCallback", "Account", new { ReturnUrl = returnUrl }));
}

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