J'utilise IdentityServer4 avec IdentityServer4.AccessTokenValidation pour gérer le jeton de référence .
C'est ce que j'ai fait dans Startup.cs
:
Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request starting HTTP/1.1 POST http://localhost:56219/api/user/search application/json 5 Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request finished in 10.9132ms 307 Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request starting HTTP/1.1 POST https://localhost:44386/api/user/search application/json 5 Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request starting HTTP/1.1 POST https://localhost:44386/connect/introspect application/x-www-form-urlencoded 143 IdentityServer4.AccessTokenValidation.IdentityServerAuthenticationHandler:Debug: AuthenticationScheme: Bearer was not authenticated. IdentityServer4.AccessTokenValidation.IdentityServerAuthenticationHandler:Debug: AuthenticationScheme: Bearer was not authenticated. IdentityServer4.Hosting.EndpointRouter:Debug: Request path /connect/introspect matched to endpoint type Introspection IdentityServer4.Hosting.EndpointRouter:Debug: Endpoint enabled: Introspection, successfully created handler: IdentityServer4.Endpoints.IntrospectionEndpoint IdentityServer4.Hosting.IdentityServerMiddleware:Information: Invoking IdentityServer endpoint: IdentityServer4.Endpoints.IntrospectionEndpoint for /connect/introspect IdentityServer4.Endpoints.IntrospectionEndpoint:Debug: Starting introspection request. IdentityServer4.Validation.BasicAuthenticationSecretParser:Debug: Start parsing Basic Authentication secret IdentityServer4.Validation.PostBodySecretParser:Debug: Start parsing for secret in post body IdentityServer4.Validation.SecretParser:Debug: Parser found secret: PostBodySecretParser IdentityServer4.Validation.SecretParser:Debug: Secret id found: api1 IdentityServer4.Validation.HashedSharedSecretValidator:Debug: No shared secret configured for client. IdentityServer4.Validation.SecretValidator:Debug: Secret validators could not validate secret IdentityServer4.Validation.ApiSecretValidator:Error: API validation failed. IdentityServer4.Endpoints.IntrospectionEndpoint:Error: API unauthorized to call introspection endpoint. aborting. Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request finished in 57.8551ms 401 IdentityModel.AspNetCore.OAuth2Introspection.OAuth2IntrospectionHandler:Error: Error returned from introspection endpoint: Unauthorized IdentityModel.AspNetCore.OAuth2Introspection.OAuth2IntrospectionHandler:Information: BearerIdentityServerAuthenticationIntrospection was not authenticated. Failure message: Error returned from introspection endpoint: Unauthorized IdentityServer4.AccessTokenValidation.IdentityServerAuthenticationHandler:Information: Bearer was not authenticated. Failure message: Error returned from introspection endpoint: Unauthorized IdentityServer4.AccessTokenValidation.IdentityServerAuthenticationHandler:Information: Bearer was not authenticated. Failure message: Error returned from introspection endpoint: Unauthorized IdentityServer4.AccessTokenValidation.IdentityServerAuthenticationHandler:Information: Bearer was not authenticated. Failure message: Error returned from introspection endpoint: Unauthorized Microsoft.AspNetCore.Routing.EndpointMiddleware:Information: Executing endpoint 'QrApi.Controllers.UserController.SearchUsersAsync (QrApi)' Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker:Information: Route matched with {action = "SearchUsersAsync", controller = "User"}. Executing action QrApi.Controllers.UserController.SearchUsersAsync (QrApi) Microsoft.AspNetCore.Authorization.DefaultAuthorizationService:Information: Authorization failed. Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker:Information: Authorization failed for the request at filter 'Microsoft.AspNetCore.Mvc.Authorization.AuthorizeFilter'. Microsoft.AspNetCore.Mvc.ChallengeResult:Information: Executing ChallengeResult with authentication schemes (). IdentityModel.AspNetCore.OAuth2Introspection.OAuth2IntrospectionHandler:Information: AuthenticationScheme: BearerIdentityServerAuthenticationIntrospection was challenged. IdentityServer4.AccessTokenValidation.IdentityServerAuthenticationHandler:Information: AuthenticationScheme: Bearer was challenged. Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker:Information: Executed action QrApi.Controllers.UserController.SearchUsersAsync (QrApi) in 10.8603ms Microsoft.AspNetCore.Routing.EndpointMiddleware:Information: Executed endpoint 'QrApi.Controllers.UserController.SearchUsersAsync (QrApi)' Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request finished in 135.7991ms 401
Lorsque je fais une demande avec la structure indiquée dans l'image ci-dessous:
J'ai reçu un jeton.
Après avoir utilisé le jeton reçu pour faire une demande à la ressource api protégée api / user / search
. Cela m'a donné le code de statut 401.
Dans la sortie de Visual Studio. Voici ce que j'ai vu:
public void ConfigureServices(IServiceCollection services) { // Add identity server 4. services.AddIdentityServer() .AddProfileService<IdentityServerProfileService>() .AddInMemoryClients(LoadInMemoryIdentityServerClients()) .AddInMemoryApiResources(LoadInMemoryApiResources()) .AddInMemoryIdentityResources(LoadInMemoryIdentityResource()) .AddProfileService<IdentityServerProfileService>() .AddResourceOwnerValidator<ResourceOwnerPasswordValidator>() .AddDeveloperSigningCredential(); // Add jwt validation. services.AddAuthentication(options => { options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; }) .AddIdentityServerAuthentication(options => { // base-address of your identityserver options.Authority = "https://localhost:44386"; options.ClaimsIssuer = "https://localhost:44386"; // name of the API resource options.ApiName = "api1"; options.ApiSecret = "web-api-secret"; options.RequireHttpsMetadata = false; }); } protected static IEnumerable<Client> LoadInMemoryIdentityServerClients() { var clients = new List<Client>(); var client = new Client(); client.ClientId = "web-api-client"; client.AllowedGrantTypes = GrantTypes.ResourceOwnerPassword; client.ClientSecrets = new[] {new Secret("web-api-secret".Sha256())}; client.AccessTokenType = AccessTokenType.Reference; client.AllowedScopes = new[] { IdentityServerConstants.StandardScopes.OpenId, IdentityServerConstants.StandardScopes.Profile, IdentityServerConstants.StandardScopes.Email, IdentityServerConstants.StandardScopes.Address, "api1" }; clients.Add(client); return clients; } protected static IEnumerable<IdentityResource> LoadInMemoryIdentityResource() { //var profileIdentityResource = new IdentityResource("repository-read", "repository-read", new List<string> { "claim-01", "age" }); return new List<IdentityResource> { new IdentityResources.OpenId(), new IdentityResources.Profile() //profileIdentityResource }; } protected static IEnumerable<ApiResource> LoadInMemoryApiResources() { var apiResources = new List<ApiResource>(); var apiResource = new ApiResource("api1", "My API"); apiResource.UserClaims = new[] { "age" }; apiResources.Add(apiResource); return apiResources; }
J'ai trouvé des tutoriels sur les jetons de référence, mais aucun d'entre eux ne m'aide à résoudre ce cas.
Que suis-je manquant?
Merci,
3 Réponses :
Il semble que ma configuration n'est pas valide pour API Resource
.
Voici mon paramètre d'origine pour API Resources
:
protected static IEnumerable<ApiResource> LoadInMemoryApiResources() { //... var apiResource = new ApiResource("api1", "My API"); api1Resource.ApiSecrets.Add(new Secret("web-api-secret".Sha256())); //... }
Ma solution a été d'ajouter le secret lors de l'instanciation de la ressource API.
protected static IEnumerable<ApiResource> LoadInMemoryApiResources() { var apiResources = new List<ApiResource>(); var apiResource = new ApiResource("api1", "My API"){ ApiSecrets = new List<Secret>{ new Secret("web-api-secret".Sha256()) }, Scopes = { new Scope("openid") } }; apiResources.Add(apiResource); return apiResources; }
Il semble que le problème soit dû au fait que vous n'avez pas configuré de secret d'API. Dans votre fichier de configuration, modifiez la ressource API pour qu'elle corresponde à la configuration ci-dessous. Je pense que pour communiquer avec le point de terminaison d'introspection, le secret de l'API est requis.
return new List<ApiResource> { new ApiResource("api1", "My API") { ApiSecrets = new List<Secret> { new Secret("secret".Sha256()) } } };
Il y a d'autres réponses (et une a été acceptée par le PO lui-même) qui fournissent la question du PO, et elles ont été publiées il y a quelque temps. Lorsque vous publiez une réponse voir: Comment rédiger une bonne réponse? , assurez-vous d'ajouter une nouvelle solution. , ou une explication nettement meilleure, en particulier pour répondre à des questions plus anciennes.
Avez-vous trouvé une solution?
@NIMRODMAINA, oui je l'ai fait. Après avoir passé des heures à trouver des solutions, je l'ai fait fonctionner. Veuillez voir ma réponse ci-dessous. J'espère que cela aidera quelqu'un à réduire le temps perdu à rechercher ce type d'erreur.
Merci d'avoir pris votre temps pour répondre à cette question. J'ai également trouvé un moyen similaire de le faire fonctionner. Je l'afficherai comme deuxième réponse.