Заявки IdentityServer4 не являются частью токена гибридного потока - PullRequest
0 голосов
/ 27 февраля 2019

Я пытаюсь создать гибридный поток, и у меня есть претензии к возвращенному токену доступа с IdentityServer4.Я использую QuickStart UI контроллеры.

В моем AccountController после успешной аутентификации пользователя у меня есть следующий код, который его подписывает:

await HttpContext.SignInAsync("anon@nymous.com", "anon@nymous.com", null, new Claim("MyName", "Ophir"));

На веб-сайте MVC, который вызывает этот поток, на странице, которую я хочу «защитить», у меня есть следующий код:

[Authorize]
public IActionResult RestrictedMvcResource()
{
       var token = _httpContext.HttpContext.GetTokenAsync("access_token").Result;
       var identity = User.Identity;
       return View();
}

После успешного входа в систему отладчик в порядке выполняет этот код, и я 'я получаю токен доступа.

Проблема в том, что если я декодирую свой токен доступа (я использую https://jwt.io/), я вижу имя и тему, но не вижу претензию MyNameчто я определил.

(в моей системе есть другой поток для client_credentials, который возвращает утверждения на токене, но использует другой поток кода).

Как мневернуть заявки на токен для гибридного потока?

РЕДАКТИРОВАТЬ:

Решение этой проблемы было комбинацией 2 вещей:

  1. Реализация IProfileService как предложено в (выбранном) ответе. Вот моя реализация:
public class ProfileService : IProfileService
{
    public Task GetProfileDataAsync(ProfileDataRequestContext context)
    {
        context.AddRequestedClaims(context.Subject.Claims);

        foreach (Claim claim in context.Subject.Claims)
        {
            if (context.IssuedClaims.Contains(claim))
                continue;

            context.IssuedClaims.Add(claim);
        }

        return Task.FromResult(0);
    }

    public Task IsActiveAsync(IsActiveContext context)
    {
        context.IsActive = true;
        return Task.FromResult(0);
    }
}

Это добавит любую претензию, которой еще нет в токене.

При звонке HttpContext.SignInAsync вы должны передать список претензий, иначе никаких дополнительных претензий в коллекции context.Subject.Claims не будет.

Ответы [ 3 ]

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

Вы можете реализовать пользовательские IProfileService, если хотите добавить пользовательские утверждения в токен.

Дополнительную информацию можно найти в Документах Identity Server 4 .

Примером простой службы пользовательских профилей может быть:

public class CustomProfileService : IProfileService
{
    public Task GetProfileDataAsync(ProfileDataRequestContext context)
    {
        context.AddRequestedClaims(context.Subject.Claims);
        context.IssuedClaims.Add(new Claim("MyName", "Ophir"));
        return Task.FromResult(0);
    }

    public Task IsActiveAsync(IsActiveContext context)
    {
        context.IsActive = true;    
        return Task.FromResult(0);
    }
}

Когда у вас есть это, просто зарегистрируйте его в DI:

services.AddTransient<IProfileService, CustomProfileService>();

Он будет вызываться всякий раз, когда access_token илиid_token запрашивается.Вам нужно будет проверить context.Caller в соответствии с комментарием Руарда, если вы хотите получить дополнительные утверждения только для определенного типа токена.

РЕДАКТИРОВАТЬ: Кроме того, вы также можете добавить утверждения непосредственно впользовательская конфигурация в соответствии с одним из примеров быстрого запуска Identity Server 4 :

            new TestUser
            {
                SubjectId = "1",
                Username = "alice",
                Password = "password",

                Claims = new []
                {
                    new Claim("MyName", "Ophir")
                }
            },

Если в итоге вы не внедрили пользовательский IProfileService и продолжаете использовать DefaultProfileService, то вы такженеобходимо добавить пользовательский IdentityResource в вашу конфигурацию:

return new List<IdentityResource>
{
    //..Your other configured identity resources

    new IdentityResource(
    name: "custom.name",
    displayName: "Custom Name",
    claimTypes: new[] { "MyName" });
};

Любым клиентам, желающим добавить это утверждение в токен, потребуется запрос для custom.name scope.

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

Есть два шага, на которых я добавляю заявки на токены для нашего сервера идентификации.

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

Эти утверждения затем могут быть запрошены через конечную точку userinfo.

Или вы создаете Api (ресурс), называемый, например, IncludeNameInAccessToken, который добавляет утверждение имени по умолчанию к токену доступа, если вы запрашиваете этот Api какОбъем.

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

AspNet.Security.OpenIdConnect.Server не сериализует утверждения, для которых не заданы пункты назначения.Я столкнулся с этим при использовании OpenIdDict.

попробуйте это:

var claim = new Claim("MyName", "Ophir");
claim.SetDestinations(OpenIdConnectConstants.Destinations.AccessToken);

await HttpContext.SignInAsync("anon@nymous.com", "anon@nymous.com", null, claim);

Возможно, вам потребуется добавить следующие пространства имен:

using AspNet.Security.OpenIdConnect.Extensions;
using AspNet.Security.OpenIdConnect.Primitives;
...