从身份服务器 returns 获取 access_token 空

Getting access_token from identityserver returns null

我有 3 个项目,一个 MVC .net 核心网站,一个 API 服务和一个 IdentityServer (IdentityServer4)。登录该网站就像一个魅力。当我想从 API 获取数据时,问题就开始了。从 httpcontext 获取 access_token 失败并且 returns 为空。奇怪的是,当我调试它时,我似乎从 httpcontext 返回了一个 access_token。只有当我 运行 来自实时网络服务器的网站时才会出现问题。

我按如下方式配置了我的 OpenIdConnect:

services.AddAuthentication(options =>
        {

            options.DefaultScheme = "Cookies";
            options.DefaultAuthenticateScheme = "Cookies";
            options.DefaultChallengeScheme = "oidc";
        })
            .AddCookie("Cookies")
            .AddOpenIdConnect("oidc", options =>
            {
                options.SignInScheme = "Cookies";
                options.Authority = "https://idserverurl";
                options.RequireHttpsMetadata = true;
                options.ClientId = "clientid";
                options.ClientSecret = "xxxxxxxx";
                options.ResponseType = "code id_token";

                options.SaveTokens = true;
                options.GetClaimsFromUserInfoEndpoint = true;
                options.Scope.Add("openid");
                options.Scope.Add("profile");
                options.Scope.Add("offline_access");
                };
            });

要为 API 调用设置 bearertoken,我使用以下代码:

   var client = new HttpClient();
   var accessToken = await HttpContext.GetTokenAsync("access_token");
   client.SetBearerToken(accessToken);

当我在调试中 运行 这段代码时,我从 HttpContext 得到了 access_token。当我 运行 来自实时服务器时,我得到空值。

有人知道我做错了什么吗?可能是服务器级别的配置错误吗?

上面的代码看起来不错 - 最终令牌应该在用户登录后从授权服务器返回,然后在身份验证 cookie 中的请求之间持久保存。

您是否能够 运行 在您的实时 Web 服务器上使用 Fiddler 并捕获流量跟踪,包括您的 Web 应用程序和授权服务器之间的流量?这是解决问题的理想方法 - 并查看 HTTPS 请求中是否存在预期的令牌/cookie。

如果您不知道,在 .Net Core 2.0 中,您可以使用 HttpClientHandler 构建 Web 应用程序的 HttpClient,该 HttpClientHandler 设置代理详细信息,如下所示:

public class ProxyHttpHandler : HttpClientHandler
{
    public ProxyHttpHandler()
    {
        this.Proxy = new WebProxy("http://127.0.0.1:8888");
    }
}

在旧版本的 MS OpenIdConnect 库中,我发现了与负载平衡相关的问题,其中并非所有服务器都可以解密身份验证 cookie。因此,如果您的实时服务器是负载平衡的,this older link 中的详细信息可能是相关的。

我想我自己解决了。 它与行

有关
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();

通过删除这一行并更改我获得声明的代码行(它们现在有不同的密钥),我得到了 access_token。

仅供参考,我将该项目发布到我自己的 IIS。这样我就可以将 Visual Studio 附加到 dotnet 进程并对其进行调试。

为什么它在本地工作而不是在线我​​仍然不知道。