1

I'm fairly new IdentityServer4 and I'm trying to configure access control for our different internal APIs. By internal I mean that it's not over the internet. I've chosen IdentityServer4 since it seem to have great flexibility when it comes to different clients and grant types.

Right now I'm trying to get Windows Authentication (against AD) to work. First let me show you how I want it to work, then I will show you what I've tried.

Any user that's logged in to the AD should be able to request a token from the token endpoint. So for any application with integrated Windows authentication it should work automatically.

Here is an example of how I would like if to work in PowerShell. I'm not sure exactly how the body should look like, but you hopefully get the point.

$cred = Get-Credential
$body = @{grant_type='client_credentials';client_id='client'}
Invoke-RestMethod http://localhost:5000/connect/token -Method POST -Credential $cred -Body $body

So I studied the Quickstart examples of IdentityServer4 and I read the docs on Windows Authentication. I took the simplest quickstart example and tried to modify it to work with windows authentication.

The example use WebHost.CreateDefaultBuilder for the server which means that Kestrel should be automatically configured (according to the docs). Then I modify ConfigureServices accordingly:

public void ConfigureServices(IServiceCollection services)
{
    services.AddIdentityServer()
        .AddDeveloperSigningCredential()
        .AddInMemoryApiResources(Config.GetApiResources())
        .AddInMemoryClients(Config.GetClients());

    services.Configure<IISOptions>(iis =>
    {
        iis.AuthenticationDisplayName = "Windows";
        iis.AutomaticAuthentication = false;
    });
}

and in the launchSettings.json I set

iisSettings": {
    "windowsAuthentication": true,
    "anonymousAuthentication": true,
    "iisExpress": {
      "applicationUrl": "http://localhost:5000/",
      "sslPort": 0
    }
  }

However, this doesn't work. When I run the server and try to request a token with the above PowerShell script I get the following error log from the IdentityServer:

[10:24:56 Debug] IdentityServer4.Validation.ClientSecretValidator
Start client validation

[10:24:56 Debug] IdentityServer4.Validation.BasicAuthenticationSecretParser
Start parsing Basic Authentication secret

[10:24:56 Debug] IdentityServer4.Validation.PostBodySecretParser
Start parsing for secret in post body

[10:24:56 Debug] IdentityServer4.Validation.PostBodySecretParser
client id without secret found

[10:24:56 Debug] IdentityServer4.Validation.SecretParser
Parser found secret: PostBodySecretParser

[10:24:56 Debug] IdentityServer4.Validation.SecretParser
Secret id found: client

[10:24:56 Debug] IdentityServer4.Validation.HashedSharedSecretValidator
Hashed shared secret validator cannot process NoSecret

[10:24:56 Debug] IdentityServer4.Validation.SecretValidator
Secret validators could not validate secret

[10:24:56 Error] IdentityServer4.Validation.ClientSecretValidator
Client secret validation failed for client: client.

[10:24:56 Verbose] IdentityServer4.Hosting.IdentityServerMiddleware
Invoking result: IdentityServer4.Endpoints.Results.TokenErrorResult

I feel a bit clueless and like I'm missing something here (like setting up the client correctly?). I would greatly appreciate any help here!

DoubleTrouble
  • 902
  • 2
  • 7
  • 19

1 Answers1

0

The logs says it - you are missing the client secret.

But you have a bigger missing here. You are trying to use client credentials grant type. From what I understood from your explanations, you want to authenticate with the current Windows user, am I right?

If so - your approach is wrong. Client credentials grant type is for client (understand app) authenticating. In other words - it will authenticate the app itself (no matter is it your powershell script, console app or whatever else), but not the user that is using it.

For example if we (me and you) execute the same script on different machines, under different user credentials, we will still receive the same claims in the access token, because we are authenticated as the client.

Check the token endpoint documentation for more options.

If you want to get a token, based on the user and password, you need to use the password grant type.

Hope that this helps and gives you some clues.

m3n7alsnak3
  • 3,026
  • 1
  • 15
  • 24