summaryrefslogtreecommitdiffstats
path: root/src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2
diff options
context:
space:
mode:
Diffstat (limited to 'src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2')
-rw-r--r--src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/AuthorizationServer.cs2
-rw-r--r--src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/ChannelElements/MessageValidationBindingElement.cs5
-rw-r--r--src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/ClientDescription.cs39
3 files changed, 36 insertions, 10 deletions
diff --git a/src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/AuthorizationServer.cs b/src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/AuthorizationServer.cs
index 9696402..c7a1a23 100644
--- a/src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/AuthorizationServer.cs
+++ b/src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/AuthorizationServer.cs
@@ -63,7 +63,7 @@ namespace DotNetOpenAuth.OAuth2 {
if (message.ResponseType == EndUserAuthorizationResponseType.AuthorizationCode) {
// Clients with no secrets can only request implicit grant types.
var client = this.AuthorizationServerServices.GetClientOrThrow(message.ClientIdentifier);
- ErrorUtilities.VerifyProtocol(!string.IsNullOrEmpty(client.Secret), Protocol.EndUserAuthorizationRequestErrorCodes.UnauthorizedClient);
+ ErrorUtilities.VerifyProtocol(client.HasNonEmptySecret, Protocol.EndUserAuthorizationRequestErrorCodes.UnauthorizedClient);
}
}
diff --git a/src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/ChannelElements/MessageValidationBindingElement.cs b/src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/ChannelElements/MessageValidationBindingElement.cs
index be4f70d..23dcbf5 100644
--- a/src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/ChannelElements/MessageValidationBindingElement.cs
+++ b/src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/ChannelElements/MessageValidationBindingElement.cs
@@ -81,9 +81,8 @@ namespace DotNetOpenAuth.OAuth2.ChannelElements {
var authenticatedClientRequest = message as AuthenticatedClientRequestBase;
if (authenticatedClientRequest != null) {
var client = this.AuthorizationServer.GetClientOrThrow(authenticatedClientRequest.ClientIdentifier);
- string secret = client.Secret;
- AuthServerUtilities.TokenEndpointVerify(!string.IsNullOrEmpty(secret), Protocol.AccessTokenRequestErrorCodes.UnauthorizedClient); // an empty secret is not allowed for client authenticated calls.
- AuthServerUtilities.TokenEndpointVerify(MessagingUtilities.EqualsConstantTime(secret, authenticatedClientRequest.ClientSecret), Protocol.AccessTokenRequestErrorCodes.InvalidClient, AuthServerStrings.ClientSecretMismatch);
+ AuthServerUtilities.TokenEndpointVerify(client.HasNonEmptySecret, Protocol.AccessTokenRequestErrorCodes.UnauthorizedClient); // an empty secret is not allowed for client authenticated calls.
+ AuthServerUtilities.TokenEndpointVerify(client.IsValidClientSecret(authenticatedClientRequest.ClientSecret), Protocol.AccessTokenRequestErrorCodes.InvalidClient, AuthServerStrings.ClientSecretMismatch);
if (clientCredentialOnly != null) {
clientCredentialOnly.CredentialsValidated = true;
diff --git a/src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/ClientDescription.cs b/src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/ClientDescription.cs
index 76c3ea6..1ec9789 100644
--- a/src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/ClientDescription.cs
+++ b/src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/ClientDescription.cs
@@ -9,6 +9,7 @@ namespace DotNetOpenAuth.OAuth2 {
using System.Collections.Generic;
using System.Linq;
using System.Text;
+ using DotNetOpenAuth.Messaging;
/// <summary>
/// A default implementation of the <see cref="IClientDescription"/> interface.
@@ -20,6 +21,11 @@ namespace DotNetOpenAuth.OAuth2 {
private readonly Func<Uri, bool> isCallbackAllowed;
/// <summary>
+ /// The client's secret, if any.
+ /// </summary>
+ private readonly string secret;
+
+ /// <summary>
/// Initializes a new instance of the <see cref="ClientDescription"/> class.
/// </summary>
/// <param name="secret">The secret.</param>
@@ -27,18 +33,13 @@ namespace DotNetOpenAuth.OAuth2 {
/// <param name="clientType">Type of the client.</param>
/// <param name="isCallbackAllowed">A delegate that determines whether the callback is allowed.</param>
public ClientDescription(string secret, Uri defaultCallback, ClientType clientType, Func<Uri, bool> isCallbackAllowed = null) {
- this.Secret = secret;
+ this.secret = secret;
this.DefaultCallback = defaultCallback;
this.ClientType = clientType;
this.isCallbackAllowed = isCallbackAllowed;
}
/// <summary>
- /// Gets the client secret.
- /// </summary>
- public string Secret { get; private set; }
-
- /// <summary>
/// Gets the callback to use when an individual authorization request
/// does not include an explicit callback URI.
/// </summary>
@@ -53,6 +54,13 @@ namespace DotNetOpenAuth.OAuth2 {
public ClientType ClientType { get; private set; }
/// <summary>
+ /// Gets a value indicating whether a non-empty secret is registered for this client.
+ /// </summary>
+ public bool HasNonEmptySecret {
+ get { return !string.IsNullOrEmpty(this.secret); }
+ }
+
+ /// <summary>
/// Determines whether a callback URI included in a client's authorization request
/// is among those allowed callbacks for the registered client.
/// </summary>
@@ -67,5 +75,24 @@ namespace DotNetOpenAuth.OAuth2 {
return EqualityComparer<Uri>.Default.Equals(this.DefaultCallback, callback);
}
+
+ #region IClientDescription Members
+
+ /// <summary>
+ /// Checks whether the specified client secret is correct.
+ /// </summary>
+ /// <param name="secret">The secret obtained from the client.</param>
+ /// <returns><c>true</c> if the secret matches the one in the authorization server's record for the client; <c>false</c> otherwise.</returns>
+ /// <remarks>
+ /// All string equality checks, whether checking secrets or their hashes,
+ /// should be done using <see cref="MessagingUtilites.EqualsConstantTime"/> to mitigate timing attacks.
+ /// </remarks>
+ public bool IsValidClientSecret(string secret) {
+ Requires.NotNullOrEmpty(secret, "secret");
+
+ return MessagingUtilities.EqualsConstantTime(secret, this.secret);
+ }
+
+ #endregion
}
}