Search code examples
identityserver4windows-authentication

IdentityServer4: "code challenge required" under hybrid flow


I have a MVC client accessing a web API protected by IDS4 server. It works perfectly when I use ResponseType = "code". But when I change it to ResponseType = "code id_token" (hybrid flow), I start to get this "Sorry, there was an error : invalid_request code challenge required" error.

Here is my client configuration on the IDS4 side:

        new Client
        {
            ClientId = "mvc",
            ClientSecrets = { new Secret("secret".Sha256()) },
            AllowedGrantTypes = GrantTypes.HybridAndClientCredentials, 
            RequirePkce = false,
            //AllowedGrantTypes = GrantTypes.Code,

            RedirectUris = { "https://localhost:6009/signin-oidc" },
            PostLogoutRedirectUris = { "https://localhost:6009/signout-callback-oidc" },
            AllowOfflineAccess = true,

            AllowedScopes = new List<string>
            {
                IdentityServerConstants.StandardScopes.OpenId,
                IdentityServerConstants.StandardScopes.Profile,
                IdentityServerConstants.StandardScopes.Email,
                "roles",
                "MyAPI"
            }

And here is the configuration on the MVC Client side. Note that it is the 'options.ResponseType = "code id_token"' that made the error occur. It will not error if I use "code" instead.

    .AddOpenIdConnect("oidc", options =>
    {
        options.Authority = "https://localhost:6005";
        options.ClientId = "mvc";
        options.ClientSecret = "secret";
        //options.ResponseType = "code";
        options.ResponseType = "code id_token";
        options.SaveTokens = true;

        options.Scope.Add("profile");
        options.Scope.Add("email");
        options.GetClaimsFromUserInfoEndpoint = true;
        options.Scope.Add("roles");
        options.ClaimActions.MapJsonKey("role", "role", "role");
        options.TokenValidationParameters.RoleClaimType = "role";
        options.Scope.Add("MyAPI");
        options.Scope.Add("offline_access");
        options.TokenValidationParameters = new TokenValidationParameters
        {
            NameClaimType = "name"
        };
    });

And here is what's in the log:

[2021-03-12T15:25:51.014Z] [4] [Error] Request validation failed 
[2021-03-12T15:25:51.013Z] [4] [Error] code_challenge is missing
{
  "ClientId": "mvc",
  "RedirectUri": "https://localhost:6009/signin-oidc",
  "AllowedRedirectUris": [
    "https://localhost:6009/signin-oidc"
  ],
  "SubjectId": "anonymous",
  "ResponseType": "code id_token",
  "ResponseMode": "fragment",
  "GrantType": "hybrid",
  "RequestedScopes": "",
  "State": "CfDJ....8oxh4",
  "PromptMode": "",
  "Raw": {
    "client_id": "mvc",
    "redirect_uri": "https://localhost:6009/signin-oidc",
    "response_type": "code id_token",
    "scope": "openid profile email roles MyAPIoffline_access",
    "response_mode": "form_post",
    "nonce": "637511...lOGNh",
    "state": "CfDJ8...8oxh4",
    "x-client-SKU": "ID_NETSTANDARD2_0",
    "x-client-ver": "5.5.0.0"
  }
} 

By the way, I am testing hybrid flow because I am trying to make the Windows authentication working under IDS4. My local login works but not Windows. Some resource says that hybrid flow is needed for that. Can somebody tell me what I am doing wrong here?


Solution

  • It could be that IdentityServer always requires PKCE and that's why it complains when you don't provide the necessary challenge.

    Dominic writes here:

    Code flow without PKCE is vulnerable to code injection attacks. That's why we do not expose it.
    

    Adding the code challenge/verifier in a client is not that complicated.

    Here's how I present OAuth 2.1 in my training classes:

    enter image description here