public override async Task HandleIntrospectionRequest([NotNull] HandleIntrospectionRequestContext context) { var services = context.HttpContext.RequestServices.GetRequiredService <OpenIddictServices <TUser, TApplication> >(); var options = context.HttpContext.RequestServices.GetRequiredService <IOptions <IdentityOptions> >(); // If the user manager doesn't support security // stamps, skip the additional validation logic. if (!services.Users.SupportsUserSecurityStamp) { return; } var principal = context.Ticket?.Principal; Debug.Assert(principal != null); var user = await services.Users.GetUserAsync(principal); if (user == null) { context.Active = false; return; } var identifier = principal.GetClaim(options.Value.ClaimsIdentity.SecurityStampClaimType); if (!string.IsNullOrEmpty(identifier) && !string.Equals(identifier, await services.Users.GetSecurityStampAsync(user), StringComparison.Ordinal)) { context.Active = false; return; } }
public override async Task HandleIntrospectionRequest([NotNull] HandleIntrospectionRequestContext context) { var services = context.HttpContext.RequestServices.GetRequiredService <OpenIddictServices <TUser, TApplication, TAuthorization, TScope, TToken> >(); Debug.Assert(context.Ticket != null, "The authentication ticket shouldn't be null."); Debug.Assert(!string.IsNullOrEmpty(context.Request.ClientId), "The client_id parameter shouldn't be null."); // Note: the OpenID Connect server middleware allows authorized presenters (e.g relying parties) to introspect access tokens // but OpenIddict uses a stricter policy that only allows resource servers to use the introspection endpoint, unless the ticket // doesn't have any audience: in this case, the caller is allowed to introspect the token even if it's not listed as a valid audience. if (context.Ticket.IsAccessToken() && context.Ticket.HasAudience() && !context.Ticket.HasAudience(context.Request.ClientId)) { services.Logger.LogWarning("The client application '{ClientId}' is not allowed to introspect the access " + "token '{Identifier}' because it's not listed as a valid audience.", context.Request.ClientId, context.Ticket.GetTicketId()); context.Active = false; return; } var user = await services.Users.GetUserAsync(context.Ticket.Principal); if (user == null) { services.Logger.LogInformation("The token {Identifier} was declared as inactive because the " + "corresponding user ({Username}) was not found in the database.", context.Ticket.GetTicketId(), services.Users.GetUserName(context.Ticket.Principal)); context.Active = false; return; } // When the received ticket is revocable, ensure it is still valid. if (context.Ticket.IsAuthorizationCode() || context.Ticket.IsRefreshToken()) { // Retrieve the token from the database using the unique identifier stored in the authentication ticket: // if the corresponding entry cannot be found, return Active = false to indicate that is is no longer valid. var token = await services.Tokens.FindByIdAsync(context.Ticket.GetTicketId()); if (token == null) { services.Logger.LogInformation("The token {Identifier} was declared as inactive because " + "it was revoked.", context.Ticket.GetTicketId()); context.Active = false; return; } } }
public override async Task HandleIntrospectionRequest([NotNull] HandleIntrospectionRequestContext context) { var options = (OpenIddictOptions)context.Options; Debug.Assert(context.Ticket != null, "The authentication ticket shouldn't be null."); Debug.Assert(!string.IsNullOrEmpty(context.Request.ClientId), "The client_id parameter shouldn't be null."); var identifier = context.Ticket.GetProperty(OpenIdConnectConstants.Properties.TokenId); Debug.Assert(!string.IsNullOrEmpty(identifier), "The token identifier shouldn't be null or empty."); // Note: the OpenID Connect server middleware allows authorized presenters (e.g relying parties) to introspect access tokens // but OpenIddict uses a stricter policy that only allows resource servers to use the introspection endpoint, unless the ticket // doesn't have any audience: in this case, the caller is allowed to introspect the token even if it's not listed as a valid audience. if (context.Ticket.IsAccessToken() && context.Ticket.HasAudience() && !context.Ticket.HasAudience(context.Request.ClientId)) { Logger.LogWarning("The client application '{ClientId}' is not allowed to introspect the access " + "token '{Identifier}' because it's not listed as a valid audience.", context.Request.ClientId, identifier); context.Active = false; return; } if (options.DisableTokenRevocation) { return; } // When the received ticket is revocable, ensure it is still valid. if (options.UseReferenceTokens || context.Ticket.IsAuthorizationCode() || context.Ticket.IsRefreshToken()) { // Retrieve the token from the database using the unique identifier stored in the authentication ticket: // if the corresponding entry cannot be found, return Active = false to indicate that is is no longer valid. var token = await Tokens.FindByIdAsync(identifier, context.HttpContext.RequestAborted); if (token == null || !await Tokens.IsValidAsync(token, context.HttpContext.RequestAborted)) { Logger.LogInformation("The token '{Identifier}' was declared as inactive because it was revoked.", identifier); context.Active = false; return; } } }
public override async Task HandleIntrospectionRequest([NotNull] HandleIntrospectionRequestContext context) { var options = (OpenIddictOptions)context.Options; Debug.Assert(context.Ticket != null, "The authentication ticket shouldn't be null."); Debug.Assert(!string.IsNullOrEmpty(context.Request.ClientId), "The client_id parameter shouldn't be null."); var identifier = context.Ticket.GetTokenId(); Debug.Assert(!string.IsNullOrEmpty(identifier), "The authentication ticket should contain a token identifier."); if (!context.Ticket.IsAccessToken()) { Logger.LogError("The token '{Identifier}' is not an access token and thus cannot be introspected.", identifier); context.Active = false; return; } // Note: the OpenID Connect server middleware allows authorized presenters (e.g relying parties) to introspect // tokens but OpenIddict uses a stricter policy that only allows resource servers to use the introspection endpoint. // For that, an error is automatically returned if no explicit audience is attached to the authentication ticket. if (!context.Ticket.HasAudience()) { Logger.LogError("The token '{Identifier}' doesn't have any audience attached " + "and cannot be introspected. To add an audience, use the " + "'ticket.SetResources(...)' extension when creating the ticket.", identifier); context.Active = false; return; } if (!context.Ticket.HasAudience(context.Request.ClientId)) { Logger.LogError("The client application '{ClientId}' is not allowed to introspect the access " + "token '{Identifier}' because it's not listed as a valid audience.", context.Request.ClientId, identifier); context.Active = false; return; } // If the received token is not a reference access token, // skip the additional reference token validation checks. if (!options.UseReferenceTokens) { return; } // Retrieve the token from the request properties. If it's marked as invalid, return active = false. var token = context.Request.GetProperty <TToken>($"{OpenIddictConstants.Properties.Token}:{identifier}"); Debug.Assert(token != null, "The token shouldn't be null."); if (!await Tokens.IsValidAsync(token)) { Logger.LogInformation("The token '{Identifier}' was declared as inactive because it was revoked.", identifier); context.Active = false; return; } }
public override async Task HandleIntrospectionRequest([NotNull] HandleIntrospectionRequestContext context) { var options = (OpenIddictServerOptions)context.Options; Debug.Assert(context.Ticket != null, "The authentication ticket shouldn't be null."); Debug.Assert(!string.IsNullOrEmpty(context.Request.ClientId), "The client_id parameter shouldn't be null."); var identifier = context.Ticket.GetProperty(OpenIddictConstants.Properties.InternalTokenId); Debug.Assert(!string.IsNullOrEmpty(identifier), "The authentication ticket should contain a token identifier."); if (!context.Ticket.IsAccessToken()) { _logger.LogError("The token '{Identifier}' is not an access token and thus cannot be introspected.", identifier); context.Active = false; return; } // Note: the OpenID Connect server middleware allows authorized presenters (e.g relying parties) to introspect // tokens but OpenIddict uses a stricter policy that only allows resource servers to use the introspection endpoint. // For that, an error is automatically returned if no explicit audience is attached to the authentication ticket. if (!context.Ticket.HasAudience()) { _logger.LogError("The token '{Identifier}' doesn't have any audience attached " + "and cannot be introspected. To add an audience, use the " + "'ticket.SetResources(...)' extension when creating the ticket.", identifier); context.Active = false; return; } if (!context.Ticket.HasAudience(context.Request.ClientId)) { _logger.LogError("The client application '{ClientId}' is not allowed to introspect the access " + "token '{Identifier}' because it's not listed as a valid audience.", context.Request.ClientId, identifier); context.Active = false; return; } // If an authorization was attached to the access token, ensure it is still valid. if (!options.DisableAuthorizationStorage && context.Ticket.HasProperty(OpenIddictConstants.Properties.InternalAuthorizationId)) { var authorization = await _authorizationManager.FindByIdAsync( context.Ticket.GetProperty(OpenIddictConstants.Properties.InternalAuthorizationId)); if (authorization == null || !await _authorizationManager.IsValidAsync(authorization)) { _logger.LogError("The token '{Identifier}' was declared as inactive because " + "the associated authorization was no longer valid.", identifier); context.Active = false; return; } } // If the received token is a reference access token - i.e a token for // which an entry exists in the database - ensure it is still valid. if (options.UseReferenceTokens) { // Retrieve the token from the request properties. If it's marked as invalid, return active = false. var token = context.Request.GetProperty($"{OpenIddictConstants.Properties.Token}:{identifier}"); Debug.Assert(token != null, "The token shouldn't be null."); if (!await _tokenManager.IsValidAsync(token)) { _logger.LogInformation("The token '{Identifier}' was declared as inactive because it was revoked.", identifier); context.Active = false; return; } } await _eventService.PublishAsync(new OpenIddictServerEvents.HandleIntrospectionRequest(context)); }
public Task HandleIntrospectionRequest(HandleIntrospectionRequestContext context) { throw new NotImplementedException(); }