namespace OAuthAuthorizationServer.Code { using System; using System.Collections.Generic; using DotNetOpenAuth.Messaging; using DotNetOpenAuth.OAuth2; /// /// An OAuth 2.0 Client that has registered with this Authorization Server. /// public partial class Client : IClientDescription { #region IConsumerDescription Members /// /// Gets the callback to use when an individual authorization request /// does not include an explicit callback URI. /// /// /// An absolute URL; or null if none is registered. /// Uri IClientDescription.DefaultCallback { get { return string.IsNullOrEmpty(this.Callback) ? null : new Uri(this.Callback); } } /// /// Gets the type of the client. /// ClientType IClientDescription.ClientType { get { return (ClientType)this.ClientType; } } /// /// Gets a value indicating whether a non-empty secret is registered for this client. /// bool IClientDescription.HasNonEmptySecret { get { return !string.IsNullOrEmpty(this.ClientSecret); } } /// /// Determines whether a callback URI included in a client's authorization request /// is among those allowed callbacks for the registered client. /// /// The absolute URI the client has requested the authorization result be received at. /// /// true if the callback URL is allowable for this client; otherwise, false. /// bool IClientDescription.IsCallbackAllowed(Uri callback) { if (string.IsNullOrEmpty(this.Callback)) { // No callback rules have been set up for this client. return true; } // In this sample, it's enough of a callback URL match if the scheme and host match. // In a production app, it is advisable to require a match on the path as well. Uri acceptableCallbackPattern = new Uri(this.Callback); if (string.Equals(acceptableCallbackPattern.GetLeftPart(UriPartial.Authority), callback.GetLeftPart(UriPartial.Authority), StringComparison.Ordinal)) { return true; } return false; } /// /// Checks whether the specified client secret is correct. /// /// The secret obtained from the client. /// true if the secret matches the one in the authorization server's record for the client; false otherwise. /// /// All string equality checks, whether checking secrets or their hashes, /// should be done using to mitigate timing attacks. /// bool IClientDescription.IsValidClientSecret(string secret) { return MessagingUtilities.EqualsConstantTime(secret, this.ClientSecret); } #endregion } }