Как аутентифицировать соединение HttpClient с внешним провайдером (Google) - PullRequest
1 голос
/ 23 октября 2019

Редактировать:

Вот мой вопрос с новой формулировкой:

У меня есть веб-сервер с защищенными конечными точками API - перед использованием их необходимо пройти проверку подлинности в Google. Для этого я реализовал Challenge и Callback конечные точки.

Это хорошо работает из браузера с моим веб-интерфейсом SPA. Пользователь перенаправляется на сайт Google для входа, а затем перенаправляется обратно в мое веб-приложение;затем в браузере есть аутентифицированные куки, и веб-приложение может использовать конечные точки для обновления своего состояния.

У меня также есть приложение WPF, которое будет взаимодействовать с веб-сервером. Я хочу, чтобы приложение WPF выполняло те же функции, что и веб-интерфейс: используйте конечные точки веб-API после аутентификации в Google. Соединение между приложением WPF и моим веб-сервером осуществляется через HttpClient.

Моя проблема в том, что я не знаю, как аутентифицировать это соединение HttpClient между приложением WPF и веб-сервером.

Я пытался использовать ту же самую Challenge конечную точку, но ответ, который я получаю, - это, конечно, HTML-код со страницы входа в Google, так что, думаю, я не могу использовать это с HttpClient ...

Iтакже пытался выполнить проверку подлинности с помощью GoogleApis из приложения WPF и использовать маркер проверки подлинности для установки файлов cookie в HttpClient, но, по-видимому, это несовместимо.

Как выполнить проверку подлинности подключения HttpClient к веб-API с помощьювнешний поставщик, такой как Google?


Оригинальный вопрос:

Из приложения WPF пользователь аутентифицируется в Google с помощью этого кода:

using Google.Apis.Auth.OAuth2;
...
public void Authenticate()
{
    UserCredential credential = GoogleWebAuthorizationBroker.AuthorizeAsync(
        new ClientSecrets
        {
            ClientId = "myClientId",
            ClientSecret = "myClientSecret"
        },
        new[] { "email", "openid" },
        "user",
        CancellationToken.None).Result;
}

Это работает, и объект UserCredential содержит аутентифицированный токен:

enter image description here

Как встроить эту информацию токена в веб-запрос маde с HttpClient для того, чтобы позвонить моей конечной точке webapi?

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

Конечная точка на стороне сервера проверяет, что пользователь аутентифицирован с помощью IdentityServer:

var result = await HttpContext.AuthenticateAsync(IdentityServer4.IdentityServerConstants.ExternalCookieAuthenticationScheme);
if (result?.Succeeded != true)
{
    throw new Exception("External authentication error");
}

Ответы [ 4 ]

2 голосов
/ 31 октября 2019

Если я правильно понял ваш вопрос, вам просто нужно установить заголовок Authorization

var credentials = await GoogleWebAuthorizationBroker.AuthorizeAsync(
        clientSecrets,
        new[] { "email", "openid" },
        "user",
        CancellationToken.None);

_httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(
        credentials.Token.TokenType, 
        credentials.Token.IdToken);
0 голосов
/ 31 октября 2019

Если я правильно понял ваш вопрос, то столкнулся с той же проблемой не так давно.

Я реализовал это так, что в бэкэнде, независимо от того, кто пытается получить доступ к конечной точке, они должны былиотправьте Bearer X токен авторизации. Маркер содержал идентификатор клиента, который хотел получить доступ к ресурсу, и я проверил, разрешен ли он.

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

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

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

Это приводит к такой конструкции, что независимо от способа аутентификации клиента конечный результат должен быть своего рода токеном, которыйбэкэнд может получать и читать.

Надеюсь, это поможет.

0 голосов
/ 30 октября 2019

Вы отвечаете на свой вопрос в вопросе:

в браузере есть аутентифицированные куки, и веб-приложение может использовать конечные точки для обновления своего состояния

Потребности HttpClientчтобы отправить те же куки. Как мне установить cookie на HttpRequestMessage HttpClient

0 голосов
/ 27 октября 2019

Возможно, вы найдете ниже полезную подсказку для лучшего понимания OpenID:)

Путаница возникает из-за смешивания каркасов GoogleApis и IdentityServer. Аутентификация / авторизация может быть достигнута с использованием любого из них. Объекты из пространств имен Google.Apis.Auth.OAuth2 и IdentityServer4 не предназначены для взаимодействия. Конечно, ручная обработка файлов cookie не требуется.

Спросите себя, кому Google оказывает доверие пользователю. Если он перезванивает в WPF, то доверять webapi WPF - это отдельная проблема.

...