Search code examples
c#oauthoauth-2.0asp.net-core-2.0identityserver4

AuthorizeRequestValidator: Error: Invalid grant type for client: implicit


I am trying to setting up Identity Server 4 HybridAndClientCredentials on .NET Core 2.0 MVC.

I'm struggling with the error:

Invalid grant type for client: implicit

Even though I have in my code:

AllowedGrantTypes = GrantTypes.HybridAndClientCredentials,

I have downloaded sample quickstart, and that is working properly, but I am unable to find with my code, what the chunk of line is missing.

Debug output:

IdentityServer4.Validation.AuthorizeRequestValidator:
Error: Invalid grant type for client: implicit
{
  "ClientId": "consultee",
  "ClientName": "consultee Client test",
  "RedirectUri": "http://consultee.mi.local:44352/signin-oidc",
  "AllowedRedirectUris": [
    "http://consultee.mi.local:44352/signin-oidc"
  ],
  "SubjectId": "anonymous",
  "ResponseType": "id_token",
  "ResponseMode": "form_post",
  "GrantType": "implicit",
  "RequestedScopes": "",
  "State": "CfDJ8KERs5ihv_5Ll9ddYi6Nj5lkLNGQptrJwHqbSD11g27zqVxPcKxLKvbMtd5ab5LPbV15yaCNlHlzpPgRQL4R2XSue8ka_fqLBWFfXad-sRNCyY03JxgL7HZDKDrph-G4hdvRRMvBtXUc0tq2tHd7ZGX7-djehs8aHD6-P_80UfFplHCYkvARV7I64Kb5ki4cFVmLE6G8EbWIUwir6HJpkgK1CbN_IuPtBTjaLZoBOEzpxWTRVaudsD4vZFxdTv4N51ufkn8jy7GPC0pf3xCGInQpA-FziHp681qmiWbCxlp9HuAIZBem-at9dNvC29yRBw4JbcoTSrjuHkq6G6gZtXVh1YuuQYIW9R4wklmlSEX4i8kxM8zJTog98Ce3OFsYnw",
  "Raw": {
    "client_id": "consultee",
    "redirect_uri": "http://consultee.mi.local:44352/signin-oidc",
    "response_type": "id_token",
    "scope": "openid profile api1 offline_access",
    "response_mode": "form_post",
    "nonce": "636626718480261618.MDYwZjE0MjMtNzczMi00ZjQ4LTk0NWUtZjQ1ZDNjM2VjZTRhOWI0NWM0MjMtNGM3Ni00ZDA3LWIyZDctMDcwNTc3ZDU0NGYy",
    "state": "CfDJ8KERs5ihv_5Ll9ddYi6Nj5lkLNGQptrJwHqbSD11g27zqVxPcKxLKvbMtd5ab5LPbV15yaCNlHlzpPgRQL4R2XSue8ka_fqLBWFfXad-sRNCyY03JxgL7HZDKDrph-G4hdvRRMvBtXUc0tq2tHd7ZGX7-djehs8aHD6-P_80UfFplHCYkvARV7I64Kb5ki4cFVmLE6G8EbWIUwir6HJpkgK1CbN_IuPtBTjaLZoBOEzpxWTRVaudsD4vZFxdTv4N51ufkn8jy7GPC0pf3xCGInQpA-FziHp681qmiWbCxlp9HuAIZBem-at9dNvC29yRBw4JbcoTSrjuHkq6G6gZtXVh1YuuQYIW9R4wklmlSEX4i8kxM8zJTog98Ce3OFsYnw",
    "x-client-SKU": "ID_NET",
    "x-client-ver": "2.1.4.0"
  }
}

Client:

new Client
{
    ClientId = "consultee",
    ClientName = "consultee Client test",
    AllowedGrantTypes = GrantTypes.HybridAndClientCredentials,

    ClientSecrets =
    {
        new Secret("secret".Sha256())
    },

    RedirectUris = { "http://consultee.mi.local:44352/signin-oidc" },
    PostLogoutRedirectUris = { "http://consultee.mi.local:44352/signout-callback-oidc" },

    AllowedScopes =
    {
        IdentityServerConstants.StandardScopes.OpenId,
        IdentityServerConstants.StandardScopes.Profile,
        "api1"
    },
    AllowOfflineAccess = true,
    AllowAccessTokensViaBrowser = true,
}

ConfigurationService at Client:

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc();

    JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();

    services.AddAuthentication(options =>
        {
            options.DefaultScheme = "Cookies";
            options.DefaultChallengeScheme = "oidc";
        })
        .AddCookie("Cookies")
        .AddOpenIdConnect("oidc", options =>
        {
            options.SignInScheme = "Cookies";

            options.Authority = Configuration["identityServerUri"];
            options.RequireHttpsMetadata = false;

            options.ClientId = "consultee";
            options.ClientSecret = "secret";

            options.SaveTokens = true;
            options.GetClaimsFromUserInfoEndpoint = true;

            options.Scope.Add("api1");
            options.Scope.Add("offline_access");
        });
}

ConfigurationService at IdServer:

public void ConfigureServices(IServiceCollection services)
    {
        services.AddMvc();

        // configure identity server with in-memory stores, keys, clients and scopes
        services.AddIdentityServer()
            .AddDeveloperSigningCredential()
            .AddInMemoryIdentityResources(Config.GetIdentityResources())
            .AddInMemoryApiResources(Config.GetApiResources())
            .AddInMemoryClients(Config.GetClients())
            .AddTestUsers(Config.GetUsers());

        services.AddAuthentication();

    }

Solution

  • The log tells you what that problem is

    Error: Invalid grant type for client: implicit

    You are logging in as an implicit client.

    .AddOpenIdConnect("oidc", options =>
            {
                options.SignInScheme = "Cookies";
    
                options.Authority = Configuration["identityServerUri"];
                options.RequireHttpsMetadata = false;
    
                options.ClientId = "consultee";
                options.ClientSecret = "secret";
    
                options.SaveTokens = true;
                options.GetClaimsFromUserInfoEndpoint = true;
    
                options.Scope.Add("api1");
                options.Scope.Add("offline_access");
            });
    

    You have configured a hybrid client in the identity server

    new Client
                {
                    ClientId = "consultee",
                    ClientName = "consultee Client test",
                    AllowedGrantTypes = GrantTypes.HybridAndClientCredentials,
    
                    ClientSecrets =
                    {
                        new Secret("secret".Sha256())
                    },
    
                    RedirectUris = { "http://consultee.migrology.local:44352/signin-oidc" },
                    PostLogoutRedirectUris = { "http://consultee.migrology.local:44352/signout-callback-oidc" },
    
                    AllowedScopes =
                    {
                        IdentityServerConstants.StandardScopes.OpenId,
                        IdentityServerConstants.StandardScopes.Profile,
                        "api1"
                    },
                    AllowOfflineAccess = true,
                    AllowAccessTokensViaBrowser = true,
                }
    

    So the server isnt going to allow you to do this. You need to change your code to login as hybrid or alter your client to be an implicit client.

    Change to hybrid

    In order to change an implicit login to a hybrid login you need to change a few things.

    • configure the ClientSecret to match the secret at IdentityServer.
    • Add the offline_access
    • add a scope (api1)
    • set the ResponseType to code id_token (which basically means “use hybrid flow”) (you are missing this)