openiddict-core icon indicating copy to clipboard operation
openiddict-core copied to clipboard

Resource server requests result in 403 (insufficient_access)

Open Thodor12 opened this issue 2 years ago • 35 comments

Confirm you've already contributed to this project or that you sponsor it

  • [X] I confirm I'm a sponsor or a contributor

Version

3.x

Question

Hello, first off thanks for making this amazing library. I'm running into an issue where my resource server is constantly giving back errors saying insufficient_access.

I get the following log (enabled trace logging):

info: Microsoft.EntityFrameworkCore.Database.Command[20101]
      Executed DbCommand (2ms) [Parameters=[@__identifier_0='?' (Size = 4000)], CommandType='Text', CommandTimeout='30']
      SELECT TOP(1) [c].[Id], [c].[Name], [c].[TenantIdentifier]
      FROM [CRM_Company] AS [c]
      WHERE [c].[TenantIdentifier] = @__identifier_0
dbug: OpenIddict.Validation.OpenIddictValidationDispatcher[0]
      The event OpenIddict.Validation.OpenIddictValidationEvents+ProcessRequestContext was successfully processed by OpenIddict.Validation.AspNetCore.OpenIddictValidationAspNetCoreHandlers+InferIssuerFromHost.
dbug: OpenIddict.Validation.OpenIddictValidationDispatcher[0]
      The event OpenIddict.Validation.OpenIddictValidationEvents+ProcessAuthenticationContext was successfully processed by OpenIddict.Validation.AspNetCore.OpenIddictValidationAspNetCoreHandlers+ExtractAccessTokenFromAuthorizationHeader.
dbug: OpenIddict.Validation.OpenIddictValidationDispatcher[0]
      The event OpenIddict.Validation.OpenIddictValidationEvents+ProcessAuthenticationContext was successfully processed by OpenIddict.Validation.AspNetCore.OpenIddictValidationAspNetCoreHandlers+ExtractAccessTokenFromBodyForm.
dbug: OpenIddict.Validation.OpenIddictValidationDispatcher[0]
      The event OpenIddict.Validation.OpenIddictValidationEvents+ProcessAuthenticationContext was successfully processed by OpenIddict.Validation.AspNetCore.OpenIddictValidationAspNetCoreHandlers+ExtractAccessTokenFromQueryString.
dbug: OpenIddict.Validation.OpenIddictValidationDispatcher[0]
      The event OpenIddict.Validation.OpenIddictValidationEvents+ProcessAuthenticationContext was successfully processed by OpenIddict.Validation.OpenIddictValidationHandlers+ValidateToken.
trce: OpenIddict.Validation.OpenIddictValidationDispatcher[0]
      The ASP.NET Core Data Protection token 'CfDJ8OpP9CaZdrhJkH68OTXlDjysdPNz2QHn-sGvfq4CWi8XFygCCaOPUO3an6nR0e5hRgQNglVRf1XDM8WenPn3PlSGu97v3ecOjBXT3O8nU7dRn9WWu18yshJEuflKgGwM9zNpyy7KETAxGSGmhWQl7N103HV47KulgAZavtNvS12m6WfLzCJrfe3N0cuWamr6nKKR6MNSv3g1da4Kxo53EtT2UeKUaCl_I21K-KsOnFwubWpfKzuCELkF4LaM_1qDFObvKKRb3Itl2o8FlDeTJmlEPoBA0G3chi_XuC8L2HjahqkY_mcLHGY15OWfeYuQdDbV9DnpCKscg8Bufj56_lszn2KNHzabkldZIE5lVMC318Vx7-_S5L_nLwv0J69mVkQzmvjX9Sr8oT8YrFNpu6b7IZV9Jd5AeyI6CcyXniGovv14nLA2u6-qYqtsrZCkgx-MJ1hgjrg83ykDTknaxg09bpcZUOBTQusW9JLhcEd0cyyGgykMsSFE271sYoHS1FkPFy8XL_NuFzqMwwwadePE14Fu6WUpUEr_RltsZB-2BSXUohq4fVF2KF8DMgbMSjslBoAQbf8bUvYK-eFKhTaObhATNh7sGf9N6JklwcWaEAq8uKSlVbn25iPRfkrieEU6kecwbMT5uwt94njWYS04-LNzU4WJ9LT9ZfeMWzt9D1Qs5b9p95oY5mBdcobn1LPu_qAjOng3qmwfjJNBpqE' was successfully validated and the following claims could be extracted: sub: 5, email: [email protected], name: Admin, role: Admin, client_id: mobile-app, oi_prst: mobile-app, oi_scp: openid, oi_scp: profile, oi_scp: email, oi_scp: roles, oi_scp: offline_access, oi_scp: mobile.access, oi_au_id: 874, oi_crt_dt: Thu, 04 Aug 2022 18:15:34 GMT, oi_exp_dt: Thu, 04 Aug 2022 18:18:34 GMT, oi_tkn_id: 857, oi_tkn_typ: access_token.
dbug: OpenIddict.Validation.OpenIddictValidationDispatcher[0]
      The event OpenIddict.Validation.OpenIddictValidationEvents+ProcessAuthenticationContext was successfully processed by OpenIddict.Validation.DataProtection.OpenIddictValidationDataProtectionHandlers+ValidateDataProtectionToken.
dbug: OpenIddict.Validation.OpenIddictValidationDispatcher[0]
      The event OpenIddict.Validation.OpenIddictValidationEvents+ProcessAuthenticationContext was successfully processed by OpenIddict.Validation.OpenIddictValidationHandlers+IntrospectToken.
dbug: OpenIddict.Validation.OpenIddictValidationDispatcher[0]
      The event OpenIddict.Validation.OpenIddictValidationEvents+ProcessAuthenticationContext was successfully processed by OpenIddict.Validation.OpenIddictValidationHandlers+NormalizeScopeClaims.
dbug: OpenIddict.Validation.OpenIddictValidationDispatcher[0]
      The event OpenIddict.Validation.OpenIddictValidationEvents+ProcessAuthenticationContext was successfully processed by OpenIddict.Validation.OpenIddictValidationHandlers+MapInternalClaims.
dbug: OpenIddict.Validation.OpenIddictValidationDispatcher[0]
      The event OpenIddict.Validation.OpenIddictValidationEvents+ProcessAuthenticationContext was successfully processed by OpenIddict.Validation.OpenIddictValidationHandlers+ValidatePrincipal.
dbug: OpenIddict.Validation.OpenIddictValidationDispatcher[0]
      The event OpenIddict.Validation.OpenIddictValidationEvents+ProcessAuthenticationContext was successfully processed by OpenIddict.Validation.OpenIddictValidationHandlers+ValidateExpirationDate.
dbug: OpenIddict.Validation.OpenIddictValidationDispatcher[0]
      The event OpenIddict.Validation.OpenIddictValidationEvents+ProcessAuthenticationContext was successfully processed by OpenIddict.Validation.OpenIddictValidationHandlers+ValidateAudience.
dbug: OpenIddict.Validation.OpenIddictValidationDispatcher[0]
      The event OpenIddict.Validation.OpenIddictValidationEvents+ProcessChallengeContext was successfully processed by OpenIddict.Validation.AspNetCore.OpenIddictValidationAspNetCoreHandlers+AttachHostChallengeError.
dbug: OpenIddict.Validation.OpenIddictValidationDispatcher[0]
      The event OpenIddict.Validation.OpenIddictValidationEvents+ProcessChallengeContext was successfully processed by OpenIddict.Validation.OpenIddictValidationHandlers+AttachDefaultChallengeError.
dbug: OpenIddict.Validation.OpenIddictValidationDispatcher[0]
      The event OpenIddict.Validation.OpenIddictValidationEvents+ProcessChallengeContext was successfully processed by OpenIddict.Validation.AspNetCore.OpenIddictValidationAspNetCoreHandlers+AttachHttpResponseCode`1[[OpenIddict.Validation.OpenIddictValidationEvents+ProcessChallengeContext, OpenIddict.Validation, Version=3.1.1.0, Culture=neutral, PublicKeyToken=35a561290d20de2f]].
dbug: OpenIddict.Validation.OpenIddictValidationDispatcher[0]
      The event OpenIddict.Validation.OpenIddictValidationEvents+ProcessChallengeContext was successfully processed by OpenIddict.Validation.AspNetCore.OpenIddictValidationAspNetCoreHandlers+AttachCacheControlHeader`1[[OpenIddict.Validation.OpenIddictValidationEvents+ProcessChallengeContext, OpenIddict.Validation, Version=3.1.1.0, Culture=neutral, PublicKeyToken=35a561290d20de2f]].
dbug: OpenIddict.Validation.OpenIddictValidationDispatcher[0]
      The event OpenIddict.Validation.OpenIddictValidationEvents+ProcessChallengeContext was successfully processed by OpenIddict.Validation.AspNetCore.OpenIddictValidationAspNetCoreHandlers+AttachWwwAuthenticateHeader`1[[OpenIddict.Validation.OpenIddictValidationEvents+ProcessChallengeContext, OpenIddict.Validation, Version=3.1.1.0, Culture=neutral, PublicKeyToken=35a561290d20de2f]].
info: OpenIddict.Validation.OpenIddictValidationDispatcher[0]
      The response was successfully returned as a challenge response: {
        "error": "insufficient_access",
        "error_description": "The user represented by the token is not allowed to perform the requested action.",
        "error_uri": "https://documentation.openiddict.com/errors/ID2095"
      }.
dbug: OpenIddict.Validation.OpenIddictValidationDispatcher[0]
      The event OpenIddict.Validation.OpenIddictValidationEvents+ProcessChallengeContext was successfully processed by OpenIddict.Validation.AspNetCore.OpenIddictValidationAspNetCoreHandlers+ProcessChallengeErrorResponse`1[[OpenIddict.Validation.OpenIddictValidationEvents+ProcessChallengeContext, OpenIddict.Validation, Version=3.1.1.0, Culture=neutral, PublicKeyToken=35a561290d20de2f]].
dbug: OpenIddict.Validation.OpenIddictValidationDispatcher[0]
      The event OpenIddict.Validation.OpenIddictValidationEvents+ProcessChallengeContext was marked as handled by OpenIddict.Validation.AspNetCore.OpenIddictValidationAspNetCoreHandlers+ProcessChallengeErrorResponse`1[[OpenIddict.Validation.OpenIddictValidationEvents+ProcessChallengeContext, OpenIddict.Validation, Version=3.1.1.0, Culture=neutral, PublicKeyToken=35a561290d20de2f]].
info: OpenIddict.Validation.AspNetCore.OpenIddictValidationAspNetCoreHandler[13]
      AuthenticationScheme: OpenIddict.Validation.AspNetCore was forbidden.

I find this strange because my I debugged my authorization policies and the conditions seem to be correct (at least the scope assertion does). I don't know where this error comes from but it seems to be something that OpenIddict throws (because of the error format).

I'm using the following configuration for: Authorization server: https://gist.github.com/Thodor12/eab711b9e2d5cfbc96616a1e31911945 Resource server: https://gist.github.com/Thodor12/0a4bd83157d3470590e61e0989c56b67 Authorization endpoint: https://gist.github.com/Thodor12/d6d65143e9b19335668525c2b2142ece

I have populated my scopes through code, not in the database, my endpoints use the Authorize attribute like so: [Authorize(Policy = nameof(Scope.Customers))].

I also have a small middleware to unpack the scopes (so that mobile.access is transformed into mobile.access customers etc (mobile.access is a combination of other scopes).

Let me know if you need any more info or see something out of the ordinary, I'm a bit stumped on the problem.

Thodor12 avatar Aug 04 '22 18:08 Thodor12

Hey,

Hello, first off thanks for making this amazing library.

Thanks for your kind words 😄

I don't know where this error comes from but it seems to be something that OpenIddict throws (because of the error format).

The line AuthenticationScheme: OpenIddict.Validation.AspNetCore was forbidden present in the logs - thanks for including them! - indicates that the 403 error response is likely not triggered by OpenIddict itself but by something else in your pipeline (that called IAuthenticaticationService.ForbidAsync()). In most cases, ForbidAsync() is indirectly called by the authorization middleware.

Sadly, the authorization middleware is not very good at logging useful stuff so I'd start by removing your custom authorization policy to see if the error disappears or not.

kevinchalet avatar Aug 04 '22 18:08 kevinchalet

If I remove the [Authorize] attribute entirely (the one I mentioned) it still does not work.

My base controller does have [Authorize(AuthenticationSchemes = OpenIddictValidationAspNetCoreDefaults.AuthenticationScheme)] could that have anything to do with it?

Thodor12 avatar Aug 04 '22 18:08 Thodor12

My base controller does have [Authorize(AuthenticationSchemes = OpenIddictValidationAspNetCoreDefaults.AuthenticationScheme)] could that have anything to do with it?

It's unlikely: 403 responses indicate an authorization issue that can't be resolved by (re)authenticating. If there was an authentication issue, you'd get a 401 response.

Can you please add the following event handler in the OpenIddict validation configuration in your API project?

options.AddEventHandler<OpenIddictValidationEvents.ProcessChallengeContext>(builder =>
{
    builder.SetOrder(int.MinValue);

    builder.UseInlineHandler(context =>
    {
        var trace = new StackTrace().ToString();

        return default;
    });
});

Then put a breakpoint on the return default; line and grab the stack trace from the trace variable. This should help figure out what's triggering it.

kevinchalet avatar Aug 04 '22 19:08 kevinchalet

   at NextLevel.API.Extensions.AuthorizationExtensions.<>c.<AddAndConfigureAuthorization>b__0_6(ProcessChallengeContext context)
   at OpenIddict.Validation.OpenIddictValidationDispatcher.DispatchAsync[TContext](TContext context)
   at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[TStateMachine](TStateMachine& stateMachine)
   at OpenIddict.Validation.OpenIddictValidationDispatcher.DispatchAsync[TContext](TContext context)
   at OpenIddict.Validation.AspNetCore.OpenIddictValidationAspNetCoreHandler.HandleChallengeAsync(AuthenticationProperties properties)
   at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[TStateMachine](TStateMachine& stateMachine)
   at OpenIddict.Validation.AspNetCore.OpenIddictValidationAspNetCoreHandler.HandleChallengeAsync(AuthenticationProperties properties)
   at Microsoft.AspNetCore.Authentication.AuthenticationHandler`1.ForbidAsync(AuthenticationProperties properties)
   at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[TStateMachine](TStateMachine& stateMachine)
   at Microsoft.AspNetCore.Authentication.AuthenticationHandler`1.ForbidAsync(AuthenticationProperties properties)
   at Microsoft.AspNetCore.Authentication.AuthenticationService.ForbidAsync(HttpContext context, String scheme, AuthenticationProperties properties)
   at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[TStateMachine](TStateMachine& stateMachine)
   at Microsoft.AspNetCore.Authentication.AuthenticationService.ForbidAsync(HttpContext context, String scheme, AuthenticationProperties properties)
   at Microsoft.AspNetCore.Authentication.AuthenticationHttpContextExtensions.ForbidAsync(HttpContext context, String scheme, AuthenticationProperties properties)
   at Microsoft.AspNetCore.Authentication.AuthenticationHttpContextExtensions.ForbidAsync(HttpContext context, String scheme)
   at Microsoft.AspNetCore.Authorization.Policy.AuthorizationMiddlewareResultHandler.HandleAsync(RequestDelegate next, HttpContext context, AuthorizationPolicy policy, PolicyAuthorizationResult authorizeResult)
   at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[TStateMachine](TStateMachine& stateMachine)
   at Microsoft.AspNetCore.Authorization.Policy.AuthorizationMiddlewareResultHandler.HandleAsync(RequestDelegate next, HttpContext context, AuthorizationPolicy policy, PolicyAuthorizationResult authorizeResult)
   at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
   at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[TStateMachine](TStateMachine& stateMachine)
   at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
   at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[TStateMachine](TStateMachine& stateMachine)
   at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)

There's more lines below this but those don't seem relevant. Also, I'm still testing this currently with the authorization policy commented out.

Thodor12 avatar Aug 04 '22 19:08 Thodor12

   at Microsoft.AspNetCore.Authentication.AuthenticationService.ChallengeAsync(HttpContext context, String scheme, AuthenticationProperties properties)
   at Microsoft.AspNetCore.Authentication.AuthenticationHttpContextExtensions.ChallengeAsync(HttpContext context, String scheme, AuthenticationProperties properties)
   at Microsoft.AspNetCore.Authentication.AuthenticationHttpContextExtensions.ChallengeAsync(HttpContext context, String scheme)

It's super weird, the authorization middleware triggers a challenge operation even though authentication seemed successful (in OpenIddict, Challenge and Forbid are assimilated to the same operation concept and OpenIddict automatically choses between 401 and 403 depending on whether the authentication was initially successful or not).

Try to remove [Authorize(...)] and add var result = await HttpContext.AuthenticateAsync(OpenIddictValidationAspNetCoreDefaults.AuthenticationScheme) in one of your actions and take a look at the properties of AuthenticateResult to see if there's a principal returned or an error.

kevinchalet avatar Aug 04 '22 19:08 kevinchalet

Ah, I see you edited your message, so my first remark no longer applies (did you forget to attach the token? 😄)

kevinchalet avatar Aug 04 '22 19:08 kevinchalet

2022-08-04 21_24_05-THOM-PC_SQLEXPRESS IPM_Dev - dbo CRM_Company - Microsoft SQL Server Management S My tokens do get attached to the requests yes

Thodor12 avatar Aug 04 '22 19:08 Thodor12

My tokens do get attached to the requests yes

I meant before you edited your message.

Your updated logs include the following lines:

   at Microsoft.AspNetCore.Authentication.AuthenticationService.ForbidAsync(HttpContext context, String scheme, AuthenticationProperties properties)
   at Microsoft.AspNetCore.Authentication.AuthenticationHttpContextExtensions.ForbidAsync(HttpContext context, String scheme, AuthenticationProperties properties)
   at Microsoft.AspNetCore.Authentication.AuthenticationHttpContextExtensions.ForbidAsync(HttpContext context, String scheme)
   at Microsoft.AspNetCore.Authorization.Policy.AuthorizationMiddlewareResultHandler.HandleAsync(RequestDelegate next, HttpContext context, AuthorizationPolicy policy, PolicyAuthorizationResult authorizeResult)

This indicates that for some reasons, one of the authorization policies enforced for the request failed and ForbidAsync() was called by the authorization middleware. It's definitely not OpenIddict that is triggering this errored response.

Do you see anything related to authorization in the logs?

kevinchalet avatar Aug 04 '22 19:08 kevinchalet

I don't have any other logging but everything from OpenIddict, do you know of any way I can debug the authorization policy so I can check if all the requirements pass?

I did notice the following 2022-08-04 21_33_06-IPMWebsite (Debugging) - Microsoft Visual Studio

The IsInRole check claims I'm not part of the given role even though the claims do include the role claim, shouldn't the identity have this role set?

Thodor12 avatar Aug 04 '22 19:08 Thodor12

The IsInRole check claims I'm not part of the given role even though the claims do include the role claim, shouldn't the identity have this role set?

If this check doesn't work, it's likely because the ClaimsIdentity doesn't have its RoleClaimType correctly configured. In your claims transformer, do you re-create the ClaimsIdentity? If so, do you specify the correct claim type in the constructor?

kevinchalet avatar Aug 04 '22 19:08 kevinchalet

The claims transformer returns the original principal passed to it, only modifying the scopes. The identity says that the RoleClaimType is http://schemas.microsoft.com/ws/2008/06/identity/claims/role, does it have to be this exact string?

Thodor12 avatar Aug 04 '22 19:08 Thodor12

It's not the correct value, it should be role. Can you share your transformer?

kevinchalet avatar Aug 04 '22 19:08 kevinchalet

public class ScopeClaimResolver : IClaimsTransformation
{
    public Task<ClaimsPrincipal> TransformAsync(ClaimsPrincipal principal)
    {
        var scopes = new HashSet<string>();
        foreach (var scope in principal.GetScopes().ToHashSet())
        {
            scopes.Add(scope);
            ExtractScopes(scopes, scope);
        }

        principal.SetScopes(scopes);
        return Task.FromResult(principal);
    }

    private static void ExtractScopes(HashSet<string> scopes, string scope)
    {
        var scopesByKey = ApplicationScopes.GetScopesByKey();
        var scopesByName = ApplicationScopes.GetScopesByName();

        if (scopesByName.ContainsKey(scope))
        {
            var childScopes = scopesByName[scope].ChildScopes
                .Where(w => scopesByKey.ContainsKey(w))
                .Select(s => scopesByKey[s].ScopeName)
                .ToList();
            foreach (var childScope in childScopes)
            {
                scopes.Add(childScope);
                ExtractScopes(scopes, childScope);
            }
        }
    }
}

Thodor12 avatar Aug 04 '22 19:08 Thodor12

Also here's what the Identity looks like in total: 2022-08-04 21_50_02-+ Actor = null

(It's what I get from assertion.User in the policy)

Thodor12 avatar Aug 04 '22 19:08 Thodor12

Oddly enough, the AuthenticationType says Server, I'd expect Validation since this is the resource server, is that correct?

Thodor12 avatar Aug 04 '22 19:08 Thodor12

Ahhhhhhh, that's because you use the opt-in ASP.NET Core Data Protection integration (there's an issue in 3.x where the OpenIddict validation handler will allow the DP integration to validate tokens locally even if you enabled introspection but it should be fixed in 4.x: I'll consider backporting this fix to 3.x).

Unlike JWTs, Data Protection tokens preserve the AuthenticationType, NameClaimType and RoleClaimType properties you set server-side. Since you use new ClaimsIdentity(OpenIddictServerAspNetCoreDefaults.AuthenticationScheme), the identity will use the default name/role claims (the WS-Fed versions, not the OIDC ones) and these values will be preserved in the DP token. API-side, when validating the tokens, these properties are restored but they don't match the name of the "role" claims you use (i.e role).

TL;DR: replace new ClaimsIdentity(OpenIddictServerAspNetCoreDefaults.AuthenticationScheme) by new ClaimsIdentity(TokenValidationParameters.DefaultAuthenticationType, Claims.Name, Claims.Role) and it should work. I'll fix the 4.0 preview samples to use this overload so that things work flawlessly when using the opt-in ASP.NET Core Data Protection integration.

kevinchalet avatar Aug 04 '22 20:08 kevinchalet

You're a lifesaver, I would not have figured that one out 😄, it works like a charm!

Thodor12 avatar Aug 04 '22 20:08 Thodor12

BTW, you can remove options.AddEncryptionCredentials(encryptionKey); and options.UseDataProtection(); as they should have no effect when using introspection.

kevinchalet avatar Aug 04 '22 20:08 kevinchalet

I'm not 100% on what everything does, introspection asks the authorization server if the token they received is valid or what does it do?

Thodor12 avatar Aug 04 '22 20:08 Thodor12

introspection asks the authorization server if the token they received is valid

Yes, that's exactly what it does (by sending a backchannel HTTP request)

kevinchalet avatar Aug 04 '22 20:08 kevinchalet

Alright, good to know, saves me the trouble of having to throw that certificate around to multiple runtimes, haha. Thanks so much for your help, I'll close this now.

Thodor12 avatar Aug 04 '22 20:08 Thodor12

Glad I could help 😃

kevinchalet avatar Aug 04 '22 20:08 kevinchalet

Hey, I ran into the bug again but for a different reason now. I'm using the introspection endpoint now so my resource server cannot decode my access token anymore, however the claims identity does not get any scopes anymore. This is because the introspection endpoint doesn't give back any scopes so how would the resource server be able to validate if the token has any of the required scopes to call an endpoint?

This is the only thing that the introspection returns:

{
  "active": true,
  "iss": "https://localhost:7068/",
  "sub": "5",
  "token_type": "Bearer",
  "token_usage": "access_token",
  "client_id": "mobile",
  "iat": 1660114571,
  "nbf": 1660114571,
  "exp": 1660118171
}

Thodor12 avatar Aug 10 '22 06:08 Thodor12

Hey,

For security reasons, OpenIddict will return a stripped-down introspection response in two cases:

  • The caller is a public client.
  • The caller is not explicitly listed as an audience for the token.

You'll likely want to double-check the client_id of your introspection client is listed when calling principal.SetResources().

Cheers.

kevinchalet avatar Aug 10 '22 11:08 kevinchalet

I added audencies to my resource server and authorization server but now it's erroring saying that the authorized party is not valid:

warn: OpenIddict.Server.OpenIddictServerDispatcher[0]
      The introspection request was rejected because the access token was issued to a different client or for another resource server.
dbug: OpenIddict.Server.OpenIddictServerDispatcher[0]
      The event OpenIddict.Server.OpenIddictServerEvents+ValidateIntrospectionRequestContext was successfully processed by OpenIddict.Server.OpenIddictServerHandlers+Introspection+ValidateAuthorizedParty.
dbug: OpenIddict.Server.OpenIddictServerDispatcher[0]

Authorization endpoint:

        var identity = new ClaimsIdentity(OpenIddictServerAspNetCoreDefaults.AuthenticationScheme, Claims.Name, Claims.Role);
        var principal = new ClaimsPrincipal(identity)
            .SetClaim(Claims.Audience, "ipm-api")
            .SetClaim(Claims.Subject, userId)
            .SetClaim(Claims.Email, await _userManager.GetEmailAsync(user))
            .SetClaim(Claims.Name, await _userManager.GetUserNameAsync(user))
            .SetClaims(Claims.Role, (await _userManager.GetRolesAsync(user)).ToImmutableArray());

Resource server:

        services.AddOpenIddict()
            .AddValidation(options =>
            {
                options.SetIssuer(configuration.GetValue<string>("OpenId:Authority"));
                options.AddAudiences("ipm-api");

                options.UseIntrospection()
                    .SetClientId(configuration.GetValue<string>("OpenId:IntrospectionClientId"))
                    .SetClientSecret(configuration.GetValue<string>("OpenId:IntrospectionClientSecret"));

                options.UseSystemNetHttp();
                options.UseAspNetCore();
            });

Thodor12 avatar Aug 10 '22 12:08 Thodor12

As I said in my last post, you must set the resources using principal.SetResources():

You'll likely want to double-check the client_id of your introspection client is listed when calling principal.SetResources().

kevinchalet avatar Aug 10 '22 12:08 kevinchalet

Sorry, I added "api" to principal.SetResource() but now I'm getting the error:

info: OpenIddict.Validation.OpenIddictValidationDispatcher[0]
      The response was successfully returned as a challenge response: {
        "error": "missing_token",
        "error_description": "The security token is missing.",
        "error_uri": "https://documentation.openiddict.com/errors/ID2000"
      }.

However I can see just prior in the logging:

dbug: OpenIddict.Validation.OpenIddictValidationDispatcher[0]
      The event OpenIddict.Validation.OpenIddictValidationEvents+HandleIntrospectionResponseContext was successfully processed by OpenIddict.Validation.OpenIddictValidationHandlers+Introspection+PopulateClaims.
trce: OpenIddict.Validation.OpenIddictValidationDispatcher[0]
      The token 'CfDJ8OpP9CaZdrhJkH68OTXlDjyxLfMygosTBD8KR6LPeIEsrDKq8XXvkJ9hqz0O8zwWDlnknjX8XeymEJ3Q65V6u5-GS2bBF3lpQLCxqwmrZWjUm7qMyULSm0s8R4lrksE2yU3yKPPCw9RJ_vKpYGPhOxYLEZNBZJUoIjTdKIyES8A-HU3BONJ8xZPOHxIgru-Ap0QGc88ysfKt17_jCDh-MbFaBG53mnruCRX06eJCXZG7Q_p3lUyI_5Cyi5Lkf_DM_Oro2_VRp--YLVeVHszKAiP3U4ptXcLYY-fu5ddcTaa7QUv_gKmuyfH_1A1BLQrrPA9vbxuE_xXsZOJXHImqayJqQylUlPK0b-0iJrbvILQWKqg5KxXYkVQ_DN89HksEpNl2tK7Bl7W9ATsVs2aAHQlOG24EZGlHfcf-RvWwLngMhtcWbkVrds7JUw-bbE1ngI1JKTQ3PW0me44uAwftrTuOIra6yNQAkiM61xHjqm-sIKh_C_CZjRdeSEZJ7CXfPZFso0g4hGhvt380S83WV0TWlhxiT7W9fsNmwTRz1ff_Q2Ue4YmP9xY2bmsAvNDwOL6cNz-8FsH3Jrr4d1w1jzi0hk1St6_4pGomxpuPD8Q3h8KyaAP6AJ54nmGCH-jDwFM2aq7wuTw2XePq4nqSJtDDxzKXj31Y2NaR8YyhcMlu_dWu77aNTqTKYApZ7LnhCMBz9FUUIomS1tEG2ryuKirTo5g_v0KrqfJNMfVI_z7Q' was successfully introspected and the following claims could be extracted: username: Admin, sub: 5, scope: openid profile email roles offline_access mobile.access, client_id: mobile, iat: 1660137667, exp: 1660141267, aud: api, email: [email protected], name: Admin, role: Admin, oi_tkn_typ: access_token.

Thodor12 avatar Aug 10 '22 13:08 Thodor12

I tested locally with the latest OpenIddict 3.1.1 bits and I wasn't able to reproduce this issue. Is your application open-source? If it's not, a repro app would help.

kevinchalet avatar Aug 10 '22 13:08 kevinchalet

I can add you to the repo, maybe you can see something I don't

Thodor12 avatar Aug 10 '22 13:08 Thodor12

I sent an invite, there's 2 projects, NextLevel.Auth and NextLevel.API, those are the authorization server and resource server respectively.

Both projects have the OpenIddict configuration inside AuthorizationExtensions.cs

Thodor12 avatar Aug 10 '22 13:08 Thodor12