Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Identity Server 4 - unauthorized client

I am struggling with basic setup of the Identity Server 4 with Net Core 3.0 and React (but this is almost irrelevant).

I have generated new app by dotnet new react -au Individual, updated dependencies etc, Created config basically copied from the demo server with the following:

public static IEnumerable<Client> GetClients()
        {
            return new List<Client>
            {
                // JavaScript Client
                new Client
                {
                    Enabled = true,
                    ClientId = "spa",
                    ClientName = "SPA (Code + PKCE)",

                    RequireClientSecret = false,
                    RequireConsent = false,

                    RedirectUris = { "https://notused" },
                    PostLogoutRedirectUris = { "https://notused" },

                    AllowedGrantTypes = GrantTypes.Code,
                    AllowedScopes = { "openid", "profile", "email", "api" },

                    AllowOfflineAccess = true,
                    RefreshTokenUsage = TokenUsage.ReUse
                },
            };
        }

In my startup:

services.AddDefaultIdentity<ApplicationUser>()
                .AddEntityFrameworkStores<ApplicationDbContext>();

            services.AddIdentityServer(o =>
                {
                    o.UserInteraction.ErrorUrl = "/myErrorsHandler";
                    o.Events.RaiseErrorEvents = true;
                    o.Events.RaiseFailureEvents = true;
                    o.Events.RaiseInformationEvents = true;
                    o.Events.RaiseSuccessEvents = true;
                })
                .AddInMemoryApiResources(Config.GetApis())
                .AddInMemoryIdentityResources(Config.GetIdentityResources())
.AddApiAuthorization<ApplicationUser, ApplicationDbContext>()
                .AddInMemoryClients(Config.GetClients())   ;

Then I am trying in Postman: enter image description here and always getting:

{"displayMode":null,"uiLocales":null,"error":"unauthorized_client","errorDescription":"Unknown client or client not enabled","requestId":"0HLPL86NBMDRG:00000001","redirectUri":null,"responseMode":null,"clientId":"spa"}

I really don't understand why this is not working. The same client on demo server with the same in Postman dialog works without any issues.

UPDATE: I found this docs: https://learn.microsoft.com/en-us/aspnet/core/security/authentication/identity-api-authorization?view=aspnetcore-3.0#application-profiles but I am still not able to get it working. It recognizes the client, but despite the config (SPA, IdentityServerSPA) throwing:

{"displayMode":null,"uiLocales":null,"error":"invalid_request","errorDescription":"code challenge required","requestId":"0HLPL8VD22382:00000001","redirectUri":"http://localhost:5000/authentication/login-callback?error=invalid_request&error_description=code%20challenge%20required#_=_","responseMode":"query","clientId":"spa"}

UPDATE 2: It is "working" with client defined in configuration JSON but only with predefined templates as per doc, but it is impossible (or possibility is not documented) to disable PKCE to make it work e.g. with Postman etc.

like image 977
Marek Urbanowicz Avatar asked Sep 09 '19 16:09

Marek Urbanowicz


2 Answers

You're not defining the client_secret. Based on the code you've provided on the client's configuration you did not setup a client secret, so If no client secret is specified, there's no direct way for your client to prove its authenticity to your Authority (IDserver). This is when PKCE comes in handy, at least you can guarantee that same system is doing both requests.

I see you're asking to disable PKCE, that should not be possible (I'm not sure if it can be done but you definitely shouldn't do that) because you're using code authentication grant for an SPA. (which is the current recommended way of doing things)

As an SPA is a non-confidential client (uncapable of keeping a secret secure) this means that any other application could use your client_id spa to make requests to the token endpoint. To prevent this we combine two things:

  • Redirect URI: this enforces the response code token to be redirected to a previously known address which should be your client (unless using hosts file to suplant your site)

  • PKCE: a mechanism that aims to guarantee that both /authorize and /token requests come from the same client, so even if someone manages to intercept the code, he/she should not be able to use it in exchange for a token, because not knowing the original secret used in PKCE.

like image 57
Pablo Recalde Avatar answered Nov 19 '22 15:11

Pablo Recalde


I struggled with the unauthorized_client error for the Resource Owner Password Validation flow in IdentityServer 4 because the grant type password was missing in [dbo].[ClientGrantTypes] for the associated client_id. I had to insert a new line into the table to fix this error.

INSERT INTO [dbo].[ClientGrantTypes] (
     [GrantType]
    ,[ClientId])
VALUES ('password', X) --where X is value of [dbo].[Clients].[Id] of used client
like image 2
Serg.ID Avatar answered Nov 19 '22 15:11

Serg.ID