IdentityServer4 - 如何从另一个 ApiResource 调用一个 ApiResource

IdentityServer4 - How to Call One ApiResource from Another ApiResource

我有一个 spa 应用程序设置,它使用 OpenId Connect 的混合授权流程受到 IdentityServer4 的保护。

此 spa 应用程序能够以登录用户身份通过​​

请求 access_token 来调用多个 ApiResources
HttpContextAccessor.HttpContext.GetTokenAsync("access_token")

这对多个 ApiResources 非常有效。例如,我的 Spa 应用程序可以毫无问题地调用 ApiResource1、ApiResource2 和 ApiResource3。

但是,我添加了一个新的 ApiResource(即 ApiResource4)并且我需要能够从 ApiResource1 调用它。但是,当我尝试调用

HttpContextAccessor.HttpContext.GetTokenAsync("access_token")

来自 ApiResource1,access_token 为 null,因此调用失败。

如何使用登录的用户令牌从 ApiResource1 调用 ApiResource2?

也许更好的提问方式是,如何从 ApiResource1 获取登录用户 access_token?

我的 SPA 应用程序是这样设置的:

services.AddAuthentication(options =>
                {
                    options.DefaultScheme = "Cookies";
                    options.DefaultChallengeScheme = "oidc";
                })
                .AddCookie("Cookies", options =>
                {
                    options.ExpireTimeSpan = TimeSpan.FromMinutes(30);
                })
                .AddOpenIdConnect("oidc", options =>
                {
                    options.SignInScheme = "Cookies";

                    options.Authority = Configuration.GetSection("IdentityServerOptions").GetValue<string>("BaseUrl");
                    options.RequireHttpsMetadata = true;

                    options.ClientId = Configuration.GetSection("IdentityServerOptions").GetValue<string>("ClientId");
                    options.ClientSecret = Configuration.GetSection("IdentityServerOptions").GetValue<string>("ClientSecret");

                    options.SaveTokens = true;
                    options.GetClaimsFromUserInfoEndpoint = true;

                    options.Scope.Add("ApiResource1");
                    options.Scope.Add("ApiResource2");
                    options.Scope.Add("ApiResource3");
                    options.Scope.Add("ApiResource4");
                    options.ResponseType = "code id_token";
                });

我的 ApiResources 是这样设置的:

services.AddAuthentication("Bearer")
                .AddIdentityServerAuthentication(options =>
                {
                    options.Authority = Configuration.GetSection("IdentityServer").GetValue<string>("BaseUrl");
                    options.RequireHttpsMetadata = true;
                    options.ApiName = _AppName;
                });

HttpContext.GetTokenAsync("access_token") 扩展方法仅适用于 Cookie 身份验证。它将尝试提取存储在 cookie 中的令牌。当您 API 使用 JWT 身份验证时,此功能不可用。

你有两个选择。

  1. 使用扩展授权委托,如 Identity Server 文档 http://docs.identityserver.io/en/release/topics/extension_grants.html#example-simple-delegation-using-an-extension-grant 中所述。此选项实施起来更复杂,但它提供了更高的安全性。

  2. Authorizationheader中提取并转发JWT。这个选项就像从请求中获取 header 并在发出 API 请求之前将其设置在 HttpClient 的 header 上一样简单。