AuthorizeRequestValidator: Error: Invalid grant type for client: implicit

Saurin Vala picture Saurin Vala · May 23, 2018 · Viewed 13.3k times · Source

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();

    }

Answer

DaImTo picture DaImTo · May 23, 2018

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)