升级后的 IdentityServer4 - 检查预期范围 openid 失败

Upgraded IdentityServer4 - Checking for expected scope openid failed

一切都从我将 .Net Core 2.1 升级到 Core 3.1 开始,为此我还将 IdentityServer4 v2.3 升级到 v4。 数据库在迁移和依赖性方面发生了很多变化。 一切正常,除了我现在尝试使用外部提供商登录时出现以下错误。 (目前我们只使用外部登录提供商,在本例中 Google)

fail: IdentityServer4.Validation.TokenValidator[0]
      Checking for expected scope openid failed
{
        "ValidateLifetime": true,
        "AccessTokenType": "Jwt",
        "ExpectedScope": "openid",
        "Claims": {
          "nbf": 1601023633,
          "exp": 1601023933,
          "iss": "xx-local",
          "client_id": "xx",
          "sub": "89e9001c-dda2-4938-8f3f-4285b160ac42",
          "auth_time": 1601023633,
          "idp": "google",
          "email": "xxxxx@xxxx.com",
          "roles": "tech",
          "iat": 1601023633,
          "scope": [
            "cc",
            "offline_access"
          ],
          "amr": "google"
        }
      }

嗯,错误说它缺少一个必需的范围,即 OpenID,所以我确保在创建客户端时将它添加到我的客户端,并在数据库中检查它

new Client
            {
                ClientId = "xx",
                ClientName = " xx Portal",
                AllowedGrantTypes =
                    {
                        GrantType.ResourceOwnerPassword, "external"
                    },
                AllowAccessTokensViaBrowser = true,
                RedirectUris = { },
                PostLogoutRedirectUris = { },
                AllowedScopes = {
                    IdentityServerConstants.StandardScopes.OpenId,
                    IdentityServerConstants.StandardScopes.Profile,
                    "cc"
                },
                RequireConsent = false,
                AllowOfflineAccess = true,
                ClientSecrets = {new Secret("secret".Sha256())},
                RequireClientSecret = false,
                UpdateAccessTokenClaimsOnRefresh = true,
                AccessTokenLifetime = 300,
                RefreshTokenUsage = TokenUsage.ReUse,
                RefreshTokenExpiration = TokenExpiration.Sliding
            },

我还创建了 ApiScopes 和 Resources 来表示范围,它们也在 startup.cs

中注册
    public static IEnumerable<ApiResource> GetApiResources()
    {
        return new List<ApiResource>
        {
            new ApiResource("cc", "CC", new[] { JwtClaimTypes.Subject, JwtClaimTypes.Email }),
        };
    }


    public static IEnumerable<ApiScope> GetApiScopes()
    {
        return new List<ApiScope>
        {
            new ApiScope(name: "cc",   displayName: "CC"),
        };
    }


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

编辑:

我刚刚注意到在发现文档中,在支持的范围列表中我没有任何 OpenId 或配置文件

  "scopes_supported": [
    "cc",
    "offline_access"
  ],

我正在使用 EF 来管理资源和配置。

我还检查了这里的其他帖子和类似的帖子,但不幸的是 none 的帮助!

您需要做的是创建 ApiScopes 来表示用户可以请求访问的范围。在早期版本中,您的范围与 ApiResources 相关联。

因此,在 v4 中,您有 IdentityResourcesApiScopes 来表示用户可以请求访问的范围。

看到这个link:

还有一点,看这个source code:

其中有两个配置选项可控制发现文档中是否包含内容:

    /// <summary>
    /// Show identity scopes
    /// </summary>
    public bool ShowIdentityScopes { get; set; } = true;

    /// <summary>
    /// Show API scopes
    /// </summary>
    public bool ShowApiScopes { get; set; } = true;

也许 ShowIdentityScopes 是错误的,这就是您看不到它们的原因?