Browse Source

Update OpenIddictProvider.ValidateRevocationRequest to skip request validation when client authentication cannot be enforced

pull/153/head
Kévin Chalet 10 years ago
parent
commit
c1d1d426d2
  1. 5
      src/OpenIddict.Core/Infrastructure/OpenIddictProvider.Exchange.cs
  2. 50
      src/OpenIddict.Core/Infrastructure/OpenIddictProvider.Revocation.cs
  3. 5
      src/OpenIddict.Core/Infrastructure/OpenIddictProvider.Serialization.cs

5
src/OpenIddict.Core/Infrastructure/OpenIddictProvider.Exchange.cs

@ -134,7 +134,8 @@ namespace OpenIddict.Infrastructure {
return;
}
// Confidential applications MUST authenticate to protect them from impersonation attacks.
// Confidential applications MUST authenticate
// to protect them from impersonation attacks.
if (string.IsNullOrEmpty(context.ClientSecret)) {
services.Logger.LogError("The token request was rejected because the confidential application " +
"'{ClientId}' didn't specify a client secret.", context.ClientId);
@ -158,8 +159,6 @@ namespace OpenIddict.Infrastructure {
}
context.Validate();
return;
}
public override async Task HandleTokenRequest([NotNull] HandleTokenRequestContext context) {

50
src/OpenIddict.Core/Infrastructure/OpenIddictProvider.Revocation.cs

@ -54,34 +54,44 @@ namespace OpenIddict.Infrastructure {
return;
}
// Reject tokens requests containing a client_secret if the client application is not confidential.
// Reject revocation requests containing a client_secret if the client application is not confidential.
var type = await services.Applications.GetClientTypeAsync(application);
if (!string.Equals(type, OpenIddictConstants.ClientTypes.Confidential, StringComparison.OrdinalIgnoreCase) &&
!string.IsNullOrEmpty(context.ClientSecret)) {
context.Reject(
error: OpenIdConnectConstants.Errors.InvalidRequest,
description: "Public clients are not allowed to send a client_secret.");
if (string.Equals(type, OpenIddictConstants.ClientTypes.Public, StringComparison.OrdinalIgnoreCase)) {
// Reject tokens requests containing a client_secret when the client is a public application.
if (!string.IsNullOrEmpty(context.ClientSecret)) {
context.Reject(
error: OpenIdConnectConstants.Errors.InvalidRequest,
description: "Public clients are not allowed to send a client_secret.");
return;
}
services.Logger.LogInformation("The revocation request validation process was not fully validated because " +
"the client '{ClientId}' was a public application.", context.ClientId);
// If client authentication cannot be enforced, call context.Skip() to inform
// the OpenID Connect server middleware that the caller cannot be fully trusted.
context.Skip();
return;
}
// Confidential applications MUST authenticate to protect them from impersonation attacks.
else if (!string.Equals(type, OpenIddictConstants.ClientTypes.Public)) {
if (string.IsNullOrEmpty(context.ClientSecret)) {
context.Reject(
error: OpenIdConnectConstants.Errors.InvalidClient,
description: "Missing credentials: ensure that you specified a client_secret.");
// Confidential applications MUST authenticate
// to protect them from impersonation attacks.
if (string.IsNullOrEmpty(context.ClientSecret)) {
context.Reject(
error: OpenIdConnectConstants.Errors.InvalidClient,
description: "Missing credentials: ensure that you specified a client_secret.");
return;
}
return;
}
if (!await services.Applications.ValidateSecretAsync(application, context.ClientSecret)) {
context.Reject(
error: OpenIdConnectConstants.Errors.InvalidClient,
description: "Invalid credentials: ensure that you specified a correct client_secret.");
if (!await services.Applications.ValidateSecretAsync(application, context.ClientSecret)) {
context.Reject(
error: OpenIdConnectConstants.Errors.InvalidClient,
description: "Invalid credentials: ensure that you specified a correct client_secret.");
return;
}
return;
}
context.Validate();

5
src/OpenIddict.Core/Infrastructure/OpenIddictProvider.Serialization.cs

@ -38,7 +38,7 @@ namespace OpenIddict.Infrastructure {
// Persist a new token entry in the database and attach it to the user and the client application it is issued to.
var identifier = await services.Users.CreateTokenAsync(user, context.Request.ClientId, OpenIdConnectConstants.TokenTypeHints.AuthorizationCode);
if (string.IsNullOrEmpty(identifier)) {
throw new InvalidOperationException("The unique key associated with a authorization code cannot be null or empty.");
throw new InvalidOperationException("The unique key associated with an authorization code cannot be null or empty.");
}
// Attach the key returned by the underlying store
@ -54,8 +54,7 @@ namespace OpenIddict.Infrastructure {
Debug.Assert(!context.Request.IsClientCredentialsGrantType(), "A refresh token should not be issued when using grant_type=client_credentials.");
// Note: a null value could be returned by FindByIdAsync if the user was removed after the initial
// check made by GrantAuthorizationCode/GrantRefreshToken/GrantResourceOwnerCredentials.
// In this case, throw an exception to abort the token request.
// check made by HandleTokenRequest. In this case, throw an exception to abort the token request.
var user = await services.Users.FindByIdAsync(context.Ticket.Principal.GetClaim(ClaimTypes.NameIdentifier));
if (user == null) {
throw new InvalidOperationException("The token request was aborted because the user associated " +

Loading…
Cancel
Save