Browse Source

Update ValidateClientAuthentication to return an error when client_secret is null

pull/27/merge
Kévin Chalet 11 years ago
parent
commit
79a483a38a
  1. 7
      src/OpenIddict.Core/OpenIddictManager.cs
  2. 57
      src/OpenIddict.Core/OpenIddictProvider.cs

7
src/OpenIddict.Core/OpenIddictManager.cs

@ -104,6 +104,13 @@ namespace OpenIddict {
} }
var hash = await Store.GetHashedSecretAsync(application, Context.RequestAborted); var hash = await Store.GetHashedSecretAsync(application, Context.RequestAborted);
if (string.IsNullOrEmpty(hash)) {
Logger.LogError("Client authentication failed for {Client} because " +
"no client secret was associated with the application.");
return false;
}
if (!Crypto.VerifyHashedPassword(hash, secret)) { if (!Crypto.VerifyHashedPassword(hash, secret)) {
Logger.LogWarning("Client authentication failed for {Client}.", await GetDisplayNameAsync(application)); Logger.LogWarning("Client authentication failed for {Client}.", await GetDisplayNameAsync(application));

57
src/OpenIddict.Core/OpenIddictProvider.cs

@ -34,7 +34,7 @@ namespace OpenIddict {
if (string.IsNullOrEmpty(context.RedirectUri)) { if (string.IsNullOrEmpty(context.RedirectUri)) {
context.Rejected( context.Rejected(
error: OpenIdConnectConstants.Errors.InvalidRequest, error: OpenIdConnectConstants.Errors.InvalidRequest,
description: "The required redirect_uri parameter was missing"); description: "The required redirect_uri parameter was missing.");
return; return;
} }
@ -46,7 +46,7 @@ namespace OpenIddict {
if (application == null) { if (application == null) {
context.Rejected( context.Rejected(
error: OpenIdConnectConstants.Errors.InvalidClient, error: OpenIdConnectConstants.Errors.InvalidClient,
description: "Application not found in the database: ensure that your client_id is correct"); description: "Application not found in the database: ensure that your client_id is correct.");
return; return;
} }
@ -54,7 +54,7 @@ namespace OpenIddict {
if (!await manager.ValidateRedirectUriAsync(application, context.RedirectUri)) { if (!await manager.ValidateRedirectUriAsync(application, context.RedirectUri)) {
context.Rejected( context.Rejected(
error: OpenIdConnectConstants.Errors.InvalidClient, error: OpenIdConnectConstants.Errors.InvalidClient,
description: "Invalid redirect_uri"); description: "Invalid redirect_uri.");
return; return;
} }
@ -69,7 +69,7 @@ namespace OpenIddict {
if (application == null) { if (application == null) {
context.Rejected( context.Rejected(
error: OpenIdConnectConstants.Errors.InvalidClient, error: OpenIdConnectConstants.Errors.InvalidClient,
description: "Invalid post_logout_redirect_uri"); description: "Invalid post_logout_redirect_uri.");
return; return;
} }
@ -87,7 +87,7 @@ namespace OpenIddict {
context.Rejected( context.Rejected(
error: OpenIdConnectConstants.Errors.InvalidGrant, error: OpenIdConnectConstants.Errors.InvalidGrant,
description: "Missing credentials: ensure that your credentials were correctly " + description: "Missing credentials: ensure that your credentials were correctly " +
"flowed in the request body or in the authorization header"); "flowed in the request body or in the authorization header.");
return; return;
} }
@ -107,29 +107,38 @@ namespace OpenIddict {
if (application == null) { if (application == null) {
context.Rejected( context.Rejected(
error: OpenIdConnectConstants.Errors.InvalidClient, error: OpenIdConnectConstants.Errors.InvalidClient,
description: "Application not found in the database: ensure that your client_id is correct"); description: "Application not found in the database: ensure that your client_id is correct.");
return; return;
} }
// Reject tokens requests containing a client_secret // Reject tokens requests containing a client_secret if the client application is not confidential.
// if the client application is not confidential.
if (await manager.IsPublicApplicationAsync(application) && !string.IsNullOrEmpty(context.ClientSecret)) { if (await manager.IsPublicApplicationAsync(application) && !string.IsNullOrEmpty(context.ClientSecret)) {
context.Rejected( context.Rejected(
error: OpenIdConnectConstants.Errors.InvalidRequest, error: OpenIdConnectConstants.Errors.InvalidRequest,
description: "Public clients are not allowed to send a client_secret"); description: "Public clients are not allowed to send a client_secret.");
return; return;
} }
// Confidential applications MUST authenticate. // Confidential applications MUST authenticate. Note: this security
else if (await manager.IsConfidentialApplicationAsync(application) && // measure also helps protecting them from impersonation attacks.
!await manager.ValidateSecretAsync(application, context.ClientSecret)) { else if (await manager.IsConfidentialApplicationAsync(application)) {
context.Rejected( if (string.IsNullOrEmpty(context.ClientSecret)) {
error: OpenIdConnectConstants.Errors.InvalidClient, context.Rejected(
description: "Invalid credentials: ensure that you specified a correct client_secret"); error: OpenIdConnectConstants.Errors.InvalidClient,
description: "Missing credentials: ensure that you specified a client_secret.");
return; return;
}
if (!await manager.ValidateSecretAsync(application, context.ClientSecret)) {
context.Rejected(
error: OpenIdConnectConstants.Errors.InvalidClient,
description: "Invalid credentials: ensure that you specified a correct client_secret.");
return;
}
} }
context.Validated(); context.Validated();
@ -159,7 +168,7 @@ namespace OpenIddict {
if (principal == null) { if (principal == null) {
context.Rejected( context.Rejected(
error: OpenIdConnectConstants.Errors.InvalidRequest, error: OpenIdConnectConstants.Errors.InvalidRequest,
description: "The required id_token_hint parameter is missing"); description: "The required id_token_hint parameter is missing.");
return; return;
} }
@ -167,7 +176,7 @@ namespace OpenIddict {
if (!string.Equals(principal.FindFirstValue(JwtRegisteredClaimNames.Aud), context.Request.ClientId)) { if (!string.Equals(principal.FindFirstValue(JwtRegisteredClaimNames.Aud), context.Request.ClientId)) {
context.Rejected( context.Rejected(
error: OpenIdConnectConstants.Errors.InvalidRequest, error: OpenIdConnectConstants.Errors.InvalidRequest,
description: "The id_token_hint parameter is invalid"); description: "The id_token_hint parameter is invalid.");
return; return;
} }
@ -177,7 +186,7 @@ namespace OpenIddict {
if (user == null) { if (user == null) {
context.Rejected( context.Rejected(
error: OpenIdConnectConstants.Errors.InvalidRequest, error: OpenIdConnectConstants.Errors.InvalidRequest,
description: "The id_token_hint parameter is invalid"); description: "The id_token_hint parameter is invalid.");
return; return;
} }
@ -194,7 +203,7 @@ namespace OpenIddict {
context.Rejected( context.Rejected(
error: OpenIdConnectConstants.Errors.UnsupportedGrantType, error: OpenIdConnectConstants.Errors.UnsupportedGrantType,
description: "Only authorization code and refresh token grant types " + description: "Only authorization code and refresh token grant types " +
"are accepted by this authorization server"); "are accepted by this authorization server.");
} }
return Task.FromResult<object>(null); return Task.FromResult<object>(null);
@ -307,7 +316,7 @@ namespace OpenIddict {
if (user == null) { if (user == null) {
context.Rejected( context.Rejected(
error: OpenIdConnectConstants.Errors.InvalidGrant, error: OpenIdConnectConstants.Errors.InvalidGrant,
description: "Invalid credentials"); description: "Invalid credentials.");
return; return;
} }
@ -316,7 +325,7 @@ namespace OpenIddict {
if (manager.SupportsUserLockout && await manager.IsLockedOutAsync(user)) { if (manager.SupportsUserLockout && await manager.IsLockedOutAsync(user)) {
context.Rejected( context.Rejected(
error: OpenIdConnectConstants.Errors.InvalidGrant, error: OpenIdConnectConstants.Errors.InvalidGrant,
description: "Account locked out"); description: "Account locked out.");
return; return;
} }
@ -325,7 +334,7 @@ namespace OpenIddict {
if (!await manager.CheckPasswordAsync(user, context.Password)) { if (!await manager.CheckPasswordAsync(user, context.Password)) {
context.Rejected( context.Rejected(
error: OpenIdConnectConstants.Errors.InvalidGrant, error: OpenIdConnectConstants.Errors.InvalidGrant,
description: "Invalid credentials"); description: "Invalid credentials.");
if (manager.SupportsUserLockout) { if (manager.SupportsUserLockout) {
await manager.AccessFailedAsync(user); await manager.AccessFailedAsync(user);
@ -334,7 +343,7 @@ namespace OpenIddict {
if (await manager.IsLockedOutAsync(user)) { if (await manager.IsLockedOutAsync(user)) {
context.Rejected( context.Rejected(
error: OpenIdConnectConstants.Errors.InvalidGrant, error: OpenIdConnectConstants.Errors.InvalidGrant,
description: "Account locked out"); description: "Account locked out.");
} }
} }

Loading…
Cancel
Save