user65248
user65248

Reputation: 551

Upgraded IdentityServer4 - Checking for expected scope openid failed

All started with me upgrading .Net Core 2.1 to Core 3.1, for that I also upgraded IdentityServer4 v2.3 to v4. There were a lot of changes in the database in terms of migrations as well as dependencies. All working, except that I now get the following error when tried to login using an external provider. (for now we only use external login provider, in this case 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": "[email protected]",
          "roles": "tech",
          "iat": 1601023633,
          "scope": [
            "cc",
            "offline_access"
          ],
          "amr": "google"
        }
      }

Well the error says it's missing a required scope which is OpenID so I made sure it is added to my client when created the client and checked it on the database as well

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
            },

I have also created the ApiScopes and Resources to represent the scopes, tehy are also registered in the 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(),
        };
    }

Edit:

I just noticed that in discovery document, in the list of supported scopes I don't have any of the OpenId or Profile

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

I am using EF to manage the resources and configuration.

I also checked the other posts here, and similar ones but unfortunately none of the helped!

Upvotes: 0

Views: 1179

Answers (1)

Tore Nestenius
Tore Nestenius

Reputation: 19901

What you need to do is to create ApiScopes to represent the scopes that the use can request access to. In earlier version your scopes was tied to ApiResources.

So, in v4 you have IdentityResources and ApiScopes to represent the scopes the user can request access to.

See this link:

One other thing, see this source code:

In it there's two configuration options that controls if what is included in the discovery document:

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

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

Perhaps the ShowIdentityScopes is false and that's why you don't see them?

Upvotes: 1

Related Questions