Автоматическое обновление аутентифицируется при предварительном просмотре OPTIONS, но не в GET для конечной точки UserInfo - PullRequest
0 голосов
/ 20 февраля 2019

Среда:

Базовая выдача и проверка токенов работают нормально в нашей среде.Сейчас я пытаюсь включить технику тихого обновления (как описано здесь ).После включения automaticSilentRenew и короткого AccessTokenLifetime я вижу, как тихие запросы запускаются в консоли браузера, как и следовало ожидать.

Я вижу два последовательных вызова конечной точки UserInfo IS4 (см. Скриншот).ниже).Первый запрос CORS preflight OPTIONS.В точке останова в моей пользовательской реализации IProfileService.IsActiveAsync() я вижу, что этот запрос успешно аутентифицируется (проверяя httpContext).

enter image description here

public class ProfileService : IProfileService
{
    private readonly HttpContext _httpContext;

    public ProfileService(IHttpContextAccessor httpContextAccessor)
    {
        _httpContext = httpContextAccessor.HttpContext;
    }

    ...

    public async Task IsActiveAsync(IsActiveContext context)
    {
        var temp = _httpContext.User; // breakpoint here
        // call external API with _httpContext.User info to get isActive
    }
}

Однако второй запрос (GET) к конечной точке UserInfo не проходит проверку подлинности.Моя точка останова в IProfileService.IsActiveAsync() не показывает аутентификацию пользователя, поэтому моя процедура проверки, активен ли пользователь (вызывает другой API), возвращает false, что транслируется в 401. Я вижу этот заголовок в неудавшемся запросе GET1037 *.

Я попытался указать IdentityTokenLifetime, который меньше AccessTokenLifetime на это , но безуспешно.

Вот журналы двухзапросы:

Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request starting HTTP/1.1 OPTIONS http://localhost:5000/connect/userinfo  
Microsoft.AspNetCore.Cors.Infrastructure.CorsService:Information: CORS policy execution successful.
Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request finished in 8.5635ms 204 
Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request starting HTTP/1.1 GET http://localhost:5000/connect/userinfo  
Microsoft.AspNetCore.Cors.Infrastructure.CorsService:Information: CORS policy execution successful.
Microsoft.AspNetCore.Cors.Infrastructure.CorsService:Information: CORS policy execution successful.
IdentityServer4.Hosting.IdentityServerMiddleware:Information: Invoking IdentityServer endpoint: IdentityServer4.Endpoints.UserInfoEndpoint for /connect/userinfo
IdentityServer4.Validation.TokenValidator:Error: User marked as not active: f84db3aa-57b8-48e4-9b59-6deee3d288ad
Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request finished in 94.7189ms 401

Вопрос:

Как получить запрос GET к конечной точке UserInfo во время обновления без вывода сообщений для аутентификации в HttpContext?

Обновление:

Добавление скриншотов всех заголовков двух запросов и полученных файлов cookie браузера для исследования ответа @ Anders.

imageOPTIONS request to UserInfo endpoint"> imageGET request to UserInfo endpoint"> resulting cookies in browser

Ответы [ 2 ]

0 голосов
/ 27 февраля 2019

Хорошо, так что я думаю, что у меня есть представление о том, что происходит.Вы делаете запрос на автоматическое обновление токена (что успешно видно из перенаправления на oidc-silent-refresh.html), и вызывается первый IsActiveAsync в ProfileService (поскольку он должен пройти через службу профиля, чтобы сгенерировать токены длятихое обновление).Вы смогли увидеть «HttpContext.User», потому что был открыт iframe, который позволял отправлять все необходимые файлы cookie.

Запрос предварительной проверки информации о пользователе даже не поступил в ProfileService, как вы можете видеть изтолько в журналах один раз отображается 'Invoking IdentityServer endpoint: IdentityServer4.Endpoints.UserInfoEndpoint for / connect / userinfo'.Кроме того, UserInfoEndpoint предотвращает прохождение любого запроса опций (что можно проверить на истинность в начале метода ProcessAsync здесь ).

Теперь, когда вы делаете фактический запрос информации о пользователе, вы пытаетесь получить информацию из HttpContext (который обычно заполняется с использованием информации из файла cookie), но он недоступен, поскольку в запросе не отправляются файлы cookie.Запрос делается здесь в методе 'getJson' (из библиотеки oidc-client-js), и вы можете видеть, что в запросе не отправляются файлы cookie (свойство 'withCredentials' будет установлено наtrue по запросу, если они были).

Так как же получить необходимую информацию о пользователе?Чтобы получить эту информацию, мы можем обратиться к « context », переданному в «IsActiveAsync» ProfileService, который содержит принципала, заполненного утверждениями токена доступа (этот процесс можно увидеть в методе «ValidateAccessTokenAsync» здесь ).

0 голосов
/ 20 февраля 2019

Запрос к /connect/userinfo аутентифицируется с помощью куки-файла аутентификации сеанса в домене / пути IdentityServer.

Я предполагаю, что куки-файл правильно включен в запрос OPTIONS, но не в последующем GET-запросе.Это то, что вы можете проверить в инструментах разработчика браузера, посмотрев на запрос.

Если мое предположение верно, причина, вероятно, в том же атрибуте сайта.Все файлы cookie аутентификации в ASP.NET Core (которые использует IdentityServer4) по умолчанию имеют атрибут samesite для предотвращения атак подделки межсайтовых запросов.

Согласно информации , я могу найти cookie с таким же сайтом= lax не допускается из запроса Get AJAX.Однако я не могу найти ничего, если это разрешено в запросе OPTIONS.Вы можете проверить (используя инструменты разработчика browswer), есть ли настройка одинакового сайта в заголовке cookie в ответе от первого запроса на /connect/authorize.

Сам параметр находится в разделе CookieВарианты cookie в звонке на AddCookie().Документы MS говорят, что по умолчанию это lax.

С другой стороны, в репозитории Idsrv4 есть поток GitHub , который говорит, что они изменили значение по умолчанию на "none"для файла cookie сеанса Idsrv4.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...