Asp.net core IdentityServer4-如何从另一个ApiResource调用一个ApiResource

Asp.net core IdentityServer4-如何从另一个ApiResource调用一个ApiResource,asp.net-core,oauth-2.0,access-token,identityserver4,openid-connect,Asp.net Core,Oauth 2.0,Access Token,Identityserver4,Openid Connect,我有一个spa应用程序设置,它受IdentityServer4保护,使用OpenId Connect的混合授权流 此spa应用程序能够通过请求访问令牌调用多个ApiResources,作为登录用户 HttpContextAccessor.HttpContext.GetTokenAsync("access_token") 这对于多个APIs资源来说非常有效。例如,我的Spa应用程序可以毫无问题地调用ApiResource1、ApiResource2和ApiResource3 但是,我添加了一个新

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

此spa应用程序能够通过请求访问令牌调用多个ApiResources,作为登录用户

HttpContextAccessor.HttpContext.GetTokenAsync("access_token")
这对于多个APIs资源来说非常有效。例如,我的Spa应用程序可以毫无问题地调用ApiResource1、ApiResource2和ApiResource3

但是,我添加了一个新的ApiResource(即ApiResource4),我需要能够从ApiResource1调用它。然而,当我试着打电话时

HttpContextAccessor.HttpContext.GetTokenAsync("access_token")
在ApiResource1中,access_令牌为空,因此调用失败

如何使用登录用户的令牌从ApiResource1呼叫ApiResource2

也许更好的提问方式是,如何从ApiResource1获取登录用户访问\u令牌

我的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";
                });
services.AddAuthentication("Bearer")
                .AddIdentityServerAuthentication(options =>
                {
                    options.Authority = Configuration.GetSection("IdentityServer").GetValue<string>("BaseUrl");
                    options.RequireHttpsMetadata = true;
                    options.ApiName = _AppName;
                });
services.AddAuthentication(选项=>
{
options.DefaultScheme=“Cookies”;
options.DefaultChallengeScheme=“oidc”;
})
.AddCookie(“Cookies”,选项=>
{
options.ExpireTimeSpan=TimeSpan.FromMinutes(30);
})
.AddOpenIdConnect(“oidc”,选项=>
{
options.signnscheme=“Cookies”;
options.Authority=Configuration.GetSection(“IdentityServerOptions”).GetValue(“BaseUrl”);
options.RequireHttpsMetadata=true;
options.ClientId=Configuration.GetSection(“IdentityServerOptions”).GetValue(“ClientId”);
options.ClientSecret=Configuration.GetSection(“IdentityServerOptions”).GetValue(“ClientSecret”);
options.SaveTokens=true;
options.GetClaimsFromUserInfoEndpoint=true;
选项。范围。添加(“ApiResource1”);
选项。范围。添加(“ApiResource2”);
选项。范围。添加(“ApiResource3”);
选项。范围。添加(“ApiResource4”);
options.ResponseType=“代码id\U令牌”;
});
我的资源设置如下:

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";
                });
services.AddAuthentication("Bearer")
                .AddIdentityServerAuthentication(options =>
                {
                    options.Authority = Configuration.GetSection("IdentityServer").GetValue<string>("BaseUrl");
                    options.RequireHttpsMetadata = true;
                    options.ApiName = _AppName;
                });
services.AddAuthentication(“承载人”)
.AddIdentityServerAuthentication(选项=>
{
options.Authority=Configuration.GetSection(“IdentityServer”).GetValue(“BaseUrl”);
options.RequireHttpsMetadata=true;
options.ApiName=\u AppName;
});

HttpContext.GetTokenAsync(“访问令牌”)扩展方法仅适用于Cookie身份验证。它将尝试提取存储在cookie中的令牌。当您有使用JWT身份验证的API时,这不可用

你有两个选择

  • 使用扩展授权委托,如Identity Server文档中所述。此选项的实现更加复杂,但它提供了更高的安全性

  • 授权
    标题
    中提取并转发JWT。此选项非常简单,只需从请求中获取头并在发出API请求之前在
    HttpClient
    的头上设置它


  • 了解延期补助金授权。听起来像是你在追求什么。另一个选项是通过从请求授权头中提取当前用户
    访问\u令牌
    来转发它。这听起来正是我想要的。明天我将努力实施它,并确保它有效。谢谢@Brad我如何获得您链接的文档中提到的“userToken”?我尝试了以下操作,所有操作都返回null:string userToken=\u contextAccessor.HttpContext!=无效的wait_contextAccessor.HttpContext?.GetTokenAsync(“id_令牌”)??wait_contextAccessor.HttpContext?.GetTokenAsync(“令牌”)??wait(u contextAccessor.HttpContext?.GetTokenAsync(“访问令牌”)
    GetTokenAsync()
    仅适用于cookie身份验证,而不适用于使用JWT的API。令牌位于
    授权
    标题中。它应该在
    \u context.HttpContext.Request.Headers中。谢谢。我不知道GetTokenAsync只与cookie身份验证一起工作。我确实从Auth头手动检索了令牌,这与您的第一条注释相结合解决了问题。非常感谢。如果你提交答案,我会接受的。