Передавать заявки пользователей в подчиненные (вторичные) api?

Я попытался выполнить поиск, но, к удивлению, не нашел ответа на свой вопрос.

Я разрабатываю веб-приложение, которое будет иметь интерфейсный интерфейс через Angular с несколькими API-интерфейсами нисходящего потока. Как показано ниже:

 [API - A Client] -> [API - A] -> [API - B]

Я использую IdentityServer4 для аутентификации / авторизации. У некоторых пользователей будет конкретное утверждение, давайте назовем его «Foo», и это утверждение будет правильно передано с сервера аутентификации в API A (с использованием неявного потока) при взаимодействии с API A через клиент SPA.

Однако я не могу передать это утверждение от API A к API B, который использует учетные данные клиента. Из того, что я прочитал / исследовал, это кажется правильным поведением, поскольку его поток учетных данных клиента.

Итак, мой вопрос: как я могу передать заявку пользователя («Foo») ниже по течению к API второго уровня (API-B)? мне нужно использовать другой поток? Следует ли API-A вручную передавать его вместе с запросом в API-B?

Я впервые использую IdentityServer / OpenID connect / OAuth, я открыт для изменений.

Конфигурация IdentityServer4

public class Config
{
    public static IEnumerable<ApiResource> GetApiResources()
    {
        return new List<ApiResource>
        {
            new ApiResource("API-B", "API B")
            {
                UserClaims = { "Foo" }
            },
            new ApiResource("API-A", "API A")
            {
                ApiSecrets = {new Secret("Secret") },
                UserClaims = { "Foo",  },
            }
        };
    }

    public static IEnumerable<Client> GetClients()
    {
        return new List<Client>
        {
            new Client
            {
                ClientName = "API-A Client",
                ClientId = "API-A_client",
                AllowedGrantTypes = GrantTypes.Implicit,

                RedirectUris = { "http://localhost:7900/swagger/oauth2-redirect.html" },
                PostLogoutRedirectUris = { "http://localhost:7900/" },

                RequireConsent = false,
                AllowAccessTokensViaBrowser = true,

                AllowedScopes = new List<string>(){
                    "API-A",
                    IdentityServerConstants.StandardScopes.OpenId,
                    IdentityServerConstants.StandardScopes.Profile
                }
            },

            new Client
            {
                ClientName = "API-A Backend",
                ClientId = "API-A_backend",
                AllowedGrantTypes = GrantTypes.ClientCredentials,

                ClientSecrets = {new Secret("Secret".Sha256()) },

                AllowedScopes = new List<string>()
                {
                    "API-B",
                    "custom_resource",
                    IdentityServerConstants.StandardScopes.OpenId,
                    IdentityServerConstants.StandardScopes.Profile
                },
                AlwaysIncludeUserClaimsInIdToken = true,
                AlwaysSendClientClaims = true,
            }
        };
    }

    public static IEnumerable<IdentityResource> GetIdentityResources()
    {
        return new List<IdentityResource>
        {
            new IdentityResources.OpenId(),
            new IdentityResources.Profile(),
            new IdentityResource("custom_resource", new [] { "Foo" }),
        };
    }
}

Конфигурация аутентификации API A

services.AddAuthentication(IdentityServerAuthenticationDefaults.AuthenticationScheme)
            .AddIdentityServerAuthentication(options =>
            {
                options.Authority = "http://localhost:6900";
                options.ApiName = "API-A";
                options.RequireHttpsMetadata = false; // dev only!
            });
services.AddTransient<AccessTokenDelegatingHandler>((service) => new AccessTokenDelegatingHandler(tokenEndpoint: $"http://localhost:6900/connect/token", clientId: "API-A", clientSecret: "Secret", scope: "API-B"));

        services.AddHttpClient<ApiBHttpClient>(client =>
        {
            client.BaseAddress = new Uri(Configuration["ApiBUri"]);
            client.DefaultRequestHeaders.Add("Accept", "application/json");
        })
        .AddHttpMessageHandler<AccessTokenDelegatingHandler>();

Конфигурация аутентификации API B

    services.AddAuthentication(IdentityServerAuthenticationDefaults.AuthenticationScheme)
            .AddIdentityServerAuthentication(options =>
            {
                options.Authority = "http://localhost:6900";
                options.ApiName = "API-B"; // required audience of access tokens
                options.RequireHttpsMetadata = false; // dev only!
                options.ApiSecret = "Secret";
            });

Результатом выше является то, что API-A правильно получает доступ к «Foo» через IdentityClaims, а API-B - нет (хотя вызов успешен).

Любая помощь приветствуется!

0
0
439
1

Ответы 1

Наконец нашел эту страницу GitHub, задав тот же вопрос: https://github.com/IdentityServer/IdentityServer4/issues/1679

Что приводит здесь к предоставлению расширений, http://docs.identityserver.io/en/release/topics/extension_grants.html, что является моим точным сценарием.

Ссылка больше не существует.

jGroot 20.05.2019 21:32

Другие вопросы по теме