Самоанализ IdentityServerV4 эталонного токена - PullRequest
2 голосов
/ 08 октября 2019

Я настроил IdentityServerV4 с клиентом, используя код авторизации + PKCE, и установил тип маркера доступа для ссылки.

new Client
{
    ClientId = "app",
    ClientName = "My Application",
    AllowedGrantTypes = GrantTypes.Code,
    RequireClientSecret = false,
    RedirectUris = { "http://site.example.com:3000/callback" },
    AllowedCorsOrigins = { "http://site.example.com:3000" },
    AllowedScopes = { "openid", "profile", "email" },
    AccessTokenType = AccessTokenType.Reference,
    RequireConsent = false,
    RequirePkce = true
}

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

Я добавил API, который я назвал "шлюзом", к серверу идентификации как описано здесь , дал ему секрет и успешно вызвал эту конечную точку, используя IntrospectionClient с ID и секретом API, но я получаю ответ active: false, и журналы сервера идентификации показывают ошибку, что токенотсутствует ожидаемый объем "шлюз". Информация о токене, отображаемая в журнале, показывает только область действия openid.

new ApiResource("gateway"){
    ApiSecrets = { new Secret("test".Sha256()) }
}

Это приводит к двум сообщениям журнала от IdentityServer:

fail: IdentityServer4.ResponseHandling.IntrospectionResponseGenerator[0]
      Expected scope gateway is missing in token
info: IdentityServer4.Endpoints.IntrospectionEndpoint[0]
      Success token introspection. Token active: True, for API name: gateway

Поэтому я не могу сказать, чтоотсутствует какая-то связь между API и выданным токеном, но я пробовал каждую перестановку областей и разрешал области между определениями Client и ApiResource, о которых я мог думать, но я не могу получить ожидаемый результат. Я прочитал и перечитал документацию несколько раз, и я не могу понять отношения между API и клиентами в этом контексте. Какая конфигурация требуется для поддержки этого типа установки?

Ответы [ 2 ]

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

Похоже, ваш прокси-сервер использует область действия gateway для конечной точки самоанализа, и проблема в том, что у вашего токена нет этой области действия gateway, поэтому вы всегда получите active: false в ответ.

У вас есть два варианта:

  1. Предоставьте клиенту gateway область и заставьте его отправить область шлюза вместе с другими областями в запросе на авторизацию .
new Client
{
    ClientId = "app",
    ClientName = "My Application",
    AllowedGrantTypes = GrantTypes.Code,
    RequireClientSecret = false,
    RedirectUris = { "http://site.example.com:3000/callback" },
    AllowedCorsOrigins = { "http://site.example.com:3000" },
    AllowedScopes = { "openid", "profile", "email", "gateway" }, // add gateway here
    AccessTokenType = AccessTokenType.Reference,
    RequireConsent = false,
    RequirePkce = true
}
Напишите пользовательский IClaimService и добавьте область действия шлюза ко всем токенам доступа.
public class CustomClaimService : IdentityServer4.Services.DefaultClaimsService
{
    public CustomClaimService(IProfileService profile, ILogger<DefaultClaimsService> logger)
        : base(profile, logger)
    {

    }

    public override Task<IEnumerable<Claim>> GetAccessTokenClaimsAsync(ClaimsPrincipal subject, Resources resources, ValidatedRequest request)
    {
        resources.ApiResources.Add(new ApiResource("gateway"));
        return base.GetAccessTokenClaimsAsync(subject, resources, request);
    }
}

Вам также необходимо зарегистрировать CustomClaimService в IServiceCollection до AddIdentityServer

public void ConfigureServices(IServiceCollection services)
{
    ...
    services.AddTransient<IClaimsService, CustomClaimService>();
    services.AddIdentityServer();
    ...
}
0 голосов
/ 15 октября 2019

Ваш токен не был выдан для области действия gateway. Вашему клиенту не разрешено запрашивать эту область:

AllowedScopes = { "openid", "profile", "email" },

Итак, если apigateway вызовет конечную точку самоанализа с этим токеном, ответ будет всегда active=false

Я думаю, ваши потребности в APIинформация о пользователе. Если нет, вы можете использовать Client Credentials Grant в apigateway для вызова вашего API.

Если нет, у вас есть 2 решения:

  1. Используйте ту же область в вашем apigateway ив вашем API и передайте токен непосредственно в API, где вы будете вызывать конечную точку самоанализа. Обратите внимание, что ваш apigateway и ваши api делятся аудиторией и областями действия, поэтому это не лучший вариант.

  2. Пользовательское делегирование. У apigateway и api есть своя аудитория и возможности. Apigateways действует как клиент делегирования, который вызывает конечную точку токена вашего idp для пересылки ваших пользовательских заявок на новый токен, выпущенный для вашего API. В документации IdentityServer4 показан способ реализации делегирования с использованием ExtensionGrants . Вы должны иметь в виду, что ваш apigateway является apiresource и в то же время клиентом для делегирования.

У вас есть отличная статья Скотта Брейди о Шаблонах делегирования для OAuth 2.0.

...