Attempting to validate a token using an introspection endpoint on IdentityServer4. I keep getting 401: Unauthorized. My log is as follows:
dbug: IdentityServer4.EntityFramework.Stores.ResourceStore[0] Found MyAPI API resource in database info: IdentityServer4.Validation.HashedSharedSecretValidator[0] Secret: MyAPI API uses invalid hashing algorithm. dbug: IdentityServer4.Validation.SecretValidator[0] Secret validators could not validate secret fail: IdentityServer4.Validation.ApiSecretValidator[0] API validation failed. fail: IdentityServer4.Endpoints.IntrospectionEndpoint[0] API unauthorized to call introspection endpoint. aborting.
My API is configured like this:
new ApiResource { Name = "MyAPI", DisplayName = "My API", ApiSecrets = { new Secret("TopSecret".Sha256()) }, }
I pass the headers for the content type as application / x-www-form-urlencoded and authorization as Basic xxxxxxxxxxxxxxxxx, where x is my base64 encoded string (myapi: TopSecret). My token is in the message body
What am I missing? Why am I getting the "MyAPI API uses the wrong hash algorithm"? If this is not valid, what is a valid hashing algorithm?
Additional Information: My resources are contained in SQL-DB, accessed through the Entity Framework. In particular, the setup is the same as in the quick start documentation found here . To get to what I find, I had to manually add my API to the ApiSecrets table and provide it with a type (SharedSecret) and a value that is a Sha256 password.
In Startup.cs, my COnfigureServices features include
services.AddIdentityServer() .AddTemporarySigningCredential() .AddInMemoryApiResources(Configurations.Scopes.GetApiResources()) .AddInMemoryClients(Configurations.Clients.GetClients()) .AddConfigurationStore(builder => builder.UseSqlServer(connectionString, options => options.MigrationsAssembly(migrationsAssembly))) .AddOperationalStore(builder => builder.UseSqlServer(connectionString, options => options.MigrationsAssembly(migrationsAssembly)));
In the Configure section:
app.UseIdentityServerAuthentication(new IdentityServerAuthenticationOptions { Authority = "http://localhost:5000", RequireHttpsMetadata = false, ApiSecret = "TopSecret", AutomaticAuthenticate = true, AutomaticChallenge = false, ApiName = "MyAPI" }); InitializeDatabase(app); app.UseIdentityServer(); app.UseMvc();
Please note that I added ApiSecret, AutomaticAuthenticate and AutomaticChallenge to this section only after I had a problem to get it working.
In my Scopes.cs, I describe the following API:
public static IEnumerable<ApiResource> GetApiResources() { return new[] { new ApiResource { Name = "MyAPI", DisplayName = "My API", ApiSecrets = { new Secret("TopSecret".Sha256()), }, } }; }
For clients:
public static IEnumerable<Client> GetClients() { return new List<Client> { new Client { ClientName = "My Client", AlwaysSendClientClaims=true, ClientId = "MyClient", ClientSecrets = { new Secret("TopSecret".Sha256()) }, RequireClientSecret=false, AllowAccessTokensViaBrowser =true, AllowedGrantTypes = GrantTypes.HybridAndClientCredentials, AllowedScopes = { "MyAPI" }, RequireConsent = false, AllowOfflineAccess = true, },
This is more or less all that is in the code part. The database that hosts the configuration seems to override any code changes I make, so I'm not sure how useful this is to everyone. In the database, I created an entry in the ApiSecrets table with ApiResourceId of 1, added a description and expiration date, set the type to “SharedSecret” and added “Secret” using various formats, including plain text, sha256 and base64.
Here is the full magazine during the conversation. Perhaps this will help. I see that there are some things that Bearer was not found or something like that, but I'm not sure why this would be, and if it would affect the result of the procedure.
info: Microsoft.AspNetCore.Hosting.Internal.WebHost[2] Request finished in 29.4277ms 401 info: Microsoft.AspNetCore.Hosting.Internal.WebHost[1] Request starting HTTP/1.1 POST http://localhost:5000/connect/introspect application/x-www-form-urlencoded 762 info: IdentityServer4.AccessTokenValidation.Infrastructure.NopAuthenticationMiddleware[7] Bearer was not authenticated. Failure message: No token found. dbug: IdentityServer4.CorsPolicyProvider[0] CORS request made for path: /connect/introspect from origin: chrome-extension://aicmkgpgakddgnaphhhpliifpcfhicfo but rejected because invalid CORS path info: Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationMiddleware[7] idsrv was not authenticated. Failure message: Unprotect ticket failed dbug: IdentityServer4.Hosting.EndpointRouter[0] Request path /connect/introspect matched to endpoint type Introspection dbug: IdentityServer4.Hosting.EndpointRouter[0] Mapping found for endpoint: Introspection, creating handler: IdentityServer4.Endpoints.IntrospectionEndpoint info: IdentityServer4.Hosting.IdentityServerMiddleware[0] Invoking IdentityServer endpoint: IdentityServer4.Endpoints.IntrospectionEndpoint for /connect/introspect dbug: IdentityServer4.Endpoints.IntrospectionEndpoint[0] Starting introspection request. dbug: IdentityServer4.Validation.BasicAuthenticationSecretParser[0] Start parsing Basic Authentication secret dbug: IdentityServer4.Validation.SecretParser[0] Parser found secret: BasicAuthenticationSecretParser dbug: IdentityServer4.Validation.SecretParser[0] Secret id found: MyAPI info: Microsoft.EntityFrameworkCore.Storage.IRelationalCommandBuilderFactory[1] Executed DbCommand (0ms) [Parameters=[@__name_0='?' (Size = 200)], CommandType='Text', CommandTimeout='30'] SELECT TOP(1) [apiResource].[Id], [apiResource].[Description], [apiResource].[DisplayName], [apiResource].[Enabled], [apiResource].[Name] FROM [ApiResources] AS [apiResource] WHERE [apiResource].[Name] = @__name_0 ORDER BY [apiResource].[Id] info: Microsoft.EntityFrameworkCore.Storage.IRelationalCommandBuilderFactory[1] Executed DbCommand (0ms) [Parameters=[@__name_0='?' (Size = 200)], CommandType='Text', CommandTimeout='30'] SELECT [a3].[Id], [a3].[ApiResourceId], [a3].[Type] FROM [ApiClaims] AS [a3] INNER JOIN ( SELECT DISTINCT TOP(1) [apiResource].[Id] FROM [ApiResources] AS [apiResource] WHERE [apiResource].[Name] = @__name_0 ORDER BY [apiResource].[Id] ) AS [apiResource2] ON [a3].[ApiResourceId] = [apiResource2].[Id] ORDER BY [apiResource2].[Id] info: Microsoft.EntityFrameworkCore.Storage.IRelationalCommandBuilderFactory[1] Executed DbCommand (0ms) [Parameters=[@__name_0='?' (Size = 200)], CommandType='Text', CommandTimeout='30'] SELECT [a2].[Id], [a2].[ApiResourceId], [a2].[Description], [a2].[Expiration], [a2].[Type], [a2].[Value] FROM [ApiSecrets] AS [a2] INNER JOIN ( SELECT DISTINCT TOP(1) [apiResource].[Id] FROM [ApiResources] AS [apiResource] WHERE [apiResource].[Name] = @__name_0 ORDER BY [apiResource].[Id] ) AS [apiResource1] ON [a2].[ApiResourceId] = [apiResource1].[Id] ORDER BY [apiResource1].[Id] info: Microsoft.EntityFrameworkCore.Storage.IRelationalCommandBuilderFactory[1] Executed DbCommand (0ms) [Parameters=[@__name_0='?' (Size = 200)], CommandType='Text', CommandTimeout='30'] SELECT [a].[Id], [a].[ApiResourceId], [a].[Description], [a].[DisplayName], [a].[Emphasize], [a].[Name], [a].[Required], [a].[ShowInDiscoveryDocument] FROM [ApiScopes] AS [a] INNER JOIN ( SELECT DISTINCT TOP(1) [apiResource].[Id] FROM [ApiResources] AS [apiResource] WHERE [apiResource].[Name] = @__name_0 ORDER BY [apiResource].[Id] ) AS [apiResource0] ON [a].[ApiResourceId] = [apiResource0].[Id] ORDER BY [apiResource0].[Id], [a].[Id] info: Microsoft.EntityFrameworkCore.Storage.IRelationalCommandBuilderFactory[1] Executed DbCommand (0ms) [Parameters=[@__name_0='?' (Size = 200)], CommandType='Text', CommandTimeout='30'] SELECT [a0].[Id], [a0].[ApiScopeId], [a0].[Type] FROM [ApiScopeClaims] AS [a0] INNER JOIN ( SELECT DISTINCT [apiResource0].[Id], [a].[Id] AS [Id0] FROM [ApiScopes] AS [a] INNER JOIN ( SELECT DISTINCT TOP(1) [apiResource].[Id] FROM [ApiResources] AS [apiResource] WHERE [apiResource].[Name] = @__name_0 ORDER BY [apiResource].[Id] ) AS [apiResource0] ON [a].[ApiResourceId] = [apiResource0].[Id] ) AS [a1] ON [a0].[ApiScopeId] = [a1].[Id0] ORDER BY [a1].[Id], [a1].[Id0] dbug: IdentityServer4.EntityFramework.Stores.ResourceStore[0] Found MyAPI API resource in database info: IdentityServer4.Validation.HashedSharedSecretValidator[0] Secret: MyAPI Secret uses invalid hashing algorithm. info: IdentityServer4.Validation.HashedSharedSecretValidator[0] Secret: MyAPI Secret uses invalid hashing algorithm. dbug: IdentityServer4.Validation.SecretValidator[0] Secret validators could not validate secret fail: IdentityServer4.Validation.ApiSecretValidator[0] API validation failed. fail: IdentityServer4.Endpoints.IntrospectionEndpoint[0] API unauthorized to call introspection endpoint. aborting. info: Microsoft.AspNetCore.Hosting.Internal.WebHost[2] Request finished in 30.673ms 401