diff options
author | Andrew Arnott <andrewarnott@gmail.com> | 2012-04-18 20:24:55 -0700 |
---|---|---|
committer | Andrew Arnott <andrewarnott@gmail.com> | 2012-04-18 20:24:55 -0700 |
commit | 5cd3b789f3966dc386cf91aa5c988ad0155fdd5d (patch) | |
tree | 26bb97deedd9a23e028c44e9552326832b01c65d | |
parent | 2ddd19d9f037bebbbdc80d7de35ce4d899710859 (diff) | |
download | DotNetOpenAuth-5cd3b789f3966dc386cf91aa5c988ad0155fdd5d.zip DotNetOpenAuth-5cd3b789f3966dc386cf91aa5c988ad0155fdd5d.tar.gz DotNetOpenAuth-5cd3b789f3966dc386cf91aa5c988ad0155fdd5d.tar.bz2 |
StyleCop cleanup, and reversal of some code changes that were no longer necessary.
24 files changed, 272 insertions, 126 deletions
diff --git a/src/DotNetOpenAuth.Core/Messaging/IHttpDirectRequestContract.cs b/src/DotNetOpenAuth.Core/Messaging/IHttpDirectRequestContract.cs index c17a4c2..cfde6cf 100644 --- a/src/DotNetOpenAuth.Core/Messaging/IHttpDirectRequestContract.cs +++ b/src/DotNetOpenAuth.Core/Messaging/IHttpDirectRequestContract.cs @@ -34,14 +34,38 @@ namespace DotNetOpenAuth.Messaging { #region IMessage Members + /// <summary> + /// Gets the version of the protocol or extension this message is prepared to implement. + /// </summary> + /// <remarks> + /// Implementations of this interface should ensure that this property never returns null. + /// </remarks> Version IMessage.Version { get { throw new NotImplementedException(); } } + /// <summary> + /// Gets the extra, non-standard Protocol parameters included in the message. + /// </summary> + /// <remarks> + /// Implementations of this interface should ensure that this property never returns null. + /// </remarks> IDictionary<string, string> IMessage.ExtraData { get { throw new NotImplementedException(); } } + /// <summary> + /// Checks the message state for conformity to the protocol specification + /// and throws an exception if the message is invalid. + /// </summary> + /// <remarks> + /// <para>Some messages have required fields, or combinations of fields that must relate to each other + /// in specialized ways. After deserializing a message, this method checks the state of the + /// message to see if it conforms to the protocol.</para> + /// <para>Note that this property should <i>not</i> check signatures or perform any state checks + /// outside this scope of this particular message.</para> + /// </remarks> + /// <exception cref="ProtocolException">Thrown if the message is invalid.</exception> void IMessage.EnsureValidMessage() { throw new NotImplementedException(); } diff --git a/src/DotNetOpenAuth.Core/Requires.cs b/src/DotNetOpenAuth.Core/Requires.cs index 5cd8b6a..7d4d5be 100644 --- a/src/DotNetOpenAuth.Core/Requires.cs +++ b/src/DotNetOpenAuth.Core/Requires.cs @@ -43,6 +43,7 @@ namespace DotNetOpenAuth { /// </summary> /// <param name="value">The value.</param> /// <param name="parameterName">Name of the parameter.</param> + /// <returns>The validated value.</returns> #if !CLR4 [ContractArgumentValidator] #endif diff --git a/src/DotNetOpenAuth.OAuth2.AuthorizationServer/DotNetOpenAuth.OAuth2.AuthorizationServer.csproj b/src/DotNetOpenAuth.OAuth2.AuthorizationServer/DotNetOpenAuth.OAuth2.AuthorizationServer.csproj index ad21f21..a65afdf 100644 --- a/src/DotNetOpenAuth.OAuth2.AuthorizationServer/DotNetOpenAuth.OAuth2.AuthorizationServer.csproj +++ b/src/DotNetOpenAuth.OAuth2.AuthorizationServer/DotNetOpenAuth.OAuth2.AuthorizationServer.csproj @@ -35,7 +35,7 @@ <Compile Include="OAuth2\ChannelElements\IOAuth2ChannelWithAuthorizationServer.cs" /> <Compile Include="OAuth2\ChannelElements\OAuth2AuthorizationServerChannel.cs" /> <Compile Include="OAuth2\ChannelElements\RefreshToken.cs" /> - <Compile Include="OAuth2\ChannelElements\ClientCredentialReader.cs" /> + <Compile Include="OAuth2\ChannelElements\ClientAuthenticationModuleBase.cs" /> <Compile Include="OAuth2\ClientDescription.cs" /> <Compile Include="OAuth2\Messages\AccessTokenAuthorizationCodeRequestAS.cs" /> <Compile Include="OAuth2\Messages\AccessTokenRefreshRequestAS.cs" /> diff --git a/src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/AuthorizationServer.cs b/src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/AuthorizationServer.cs index dc8245d..fdcab8b 100644 --- a/src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/AuthorizationServer.cs +++ b/src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/AuthorizationServer.cs @@ -28,8 +28,14 @@ namespace DotNetOpenAuth.OAuth2 { private static readonly TypeConfigurationCollection<IClientAuthenticationModule> defaultClientAuthenticationModules = new TypeConfigurationCollection<IClientAuthenticationModule>(new Type[] { typeof(ClientCredentialHttpBasicReader), typeof(ClientCredentialMessagePartReader) }); + /// <summary> + /// The list of modules that verify client authentication data. + /// </summary> private readonly List<IClientAuthenticationModule> clientAuthenticationModules = new List<IClientAuthenticationModule>(); + /// <summary> + /// The lone aggregate client authentication module that uses the <see cref="clientAuthenticationModules"/> and applies aggregating policy. + /// </summary> private readonly ClientAuthenticationModuleBase aggregatingClientAuthenticationModule; /// <summary> @@ -50,7 +56,6 @@ namespace DotNetOpenAuth.OAuth2 { ////this.clientAuthenticationModules.AddRange(modules.CreateInstances(true)); this.clientAuthenticationModules.Add(new ClientCredentialMessagePartReader(authorizationServer)); this.clientAuthenticationModules.Add(new ClientCredentialHttpBasicReader(authorizationServer)); - } /// <summary> @@ -67,6 +72,9 @@ namespace DotNetOpenAuth.OAuth2 { get { return ((IOAuth2ChannelWithAuthorizationServer)this.Channel).AuthorizationServer; } } + /// <summary> + /// Gets the extension modules that can read client authentication data from incoming messages. + /// </summary> public IList<IClientAuthenticationModule> ClientAuthenticationModules { get { return this.clientAuthenticationModules; } } diff --git a/src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/ChannelElements/AggregatingClientCredentialReader.cs b/src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/ChannelElements/AggregatingClientCredentialReader.cs index 4248c6f..6eff5f5 100644 --- a/src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/ChannelElements/AggregatingClientCredentialReader.cs +++ b/src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/ChannelElements/AggregatingClientCredentialReader.cs @@ -32,6 +32,12 @@ namespace DotNetOpenAuth.OAuth2.ChannelElements { this.authenticators = authenticators; } + /// <summary> + /// Attempts to extract client identification/authentication information from a message. + /// </summary> + /// <param name="requestMessage">The incoming message.</param> + /// <param name="clientIdentifier">Receives the client identifier, if one was found.</param> + /// <returns>The level of the extracted client information.</returns> public override ClientAuthenticationResult TryAuthenticateClient(AuthenticatedClientRequestBase requestMessage, out string clientIdentifier) { Requires.NotNull(requestMessage, "requestMessage"); diff --git a/src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/ChannelElements/ClientCredentialReader.cs b/src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/ChannelElements/ClientAuthenticationModuleBase.cs index 085600a..262116d 100644 --- a/src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/ChannelElements/ClientCredentialReader.cs +++ b/src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/ChannelElements/ClientAuthenticationModuleBase.cs @@ -1,5 +1,5 @@ //----------------------------------------------------------------------- -// <copyright file="ClientCredentialReader.cs" company="Andrew Arnott"> +// <copyright file="ClientAuthenticationModuleBase.cs" company="Andrew Arnott"> // Copyright (c) Andrew Arnott. All rights reserved. // </copyright> //----------------------------------------------------------------------- @@ -14,16 +14,41 @@ namespace DotNetOpenAuth.OAuth2.ChannelElements { using DotNetOpenAuth.Messaging; using DotNetOpenAuth.OAuth2.Messages; + /// <summary> + /// A convenient base class for imlementations of the <see cref="IClientAuthenticationModule"/> interface. + /// </summary> public abstract class ClientAuthenticationModuleBase : IClientAuthenticationModule { + /// <summary> + /// Initializes a new instance of the <see cref="ClientAuthenticationModuleBase"/> class. + /// </summary> protected ClientAuthenticationModuleBase() { } + /// <summary> + /// Attempts to extract client identification/authentication information from a message. + /// </summary> + /// <param name="requestMessage">The incoming message.</param> + /// <param name="clientIdentifier">Receives the client identifier, if one was found.</param> + /// <returns>The level of the extracted client information.</returns> public abstract ClientAuthenticationResult TryAuthenticateClient(AuthenticatedClientRequestBase requestMessage, out string clientIdentifier); + /// <summary> + /// Attempts to extract client identification/authentication information from a message. + /// </summary> + /// <param name="requestMessage">The incoming message. Always an instance of <see cref="AuthenticatedClientRequestBase"/></param> + /// <param name="clientIdentifier">Receives the client identifier, if one was found.</param> + /// <returns>The level of the extracted client information.</returns> public ClientAuthenticationResult TryAuthenticateClient(IDirectedProtocolMessage requestMessage, out string clientIdentifier) { return this.TryAuthenticateClient((AuthenticatedClientRequestBase)requestMessage, out clientIdentifier); } + /// <summary> + /// Validates a client identifier and shared secret against the authoriation server's database. + /// </summary> + /// <param name="authorizationServerHost">The authorization server host; cannot be <c>null</c>.</param> + /// <param name="clientIdentifier">The alleged client identifier.</param> + /// <param name="clientSecret">The alleged client secret to be verified.</param> + /// <returns>An indication as to the outcome of the validation.</returns> protected static ClientAuthenticationResult TryAuthenticateClient(IAuthorizationServerHost authorizationServerHost, string clientIdentifier, string clientSecret) { Requires.NotNull(authorizationServerHost, "authorizationServerHost"); diff --git a/src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/ChannelElements/ClientCredentialHttpBasicReader.cs b/src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/ChannelElements/ClientCredentialHttpBasicReader.cs index da3f8ff..b375d29 100644 --- a/src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/ChannelElements/ClientCredentialHttpBasicReader.cs +++ b/src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/ChannelElements/ClientCredentialHttpBasicReader.cs @@ -13,14 +13,30 @@ namespace DotNetOpenAuth.OAuth2.ChannelElements { using DotNetOpenAuth.Messaging; using DotNetOpenAuth.OAuth2.Messages; + /// <summary> + /// Reads client authentication information from the HTTP Authorization header via Basic authentication. + /// </summary> public class ClientCredentialHttpBasicReader : ClientAuthenticationModuleBase { + /// <summary> + /// The authorization server host. + /// </summary> private readonly IAuthorizationServerHost authorizationServerHost; + /// <summary> + /// Initializes a new instance of the <see cref="ClientCredentialHttpBasicReader"/> class. + /// </summary> + /// <param name="authorizationServerHost">The authorization server host.</param> public ClientCredentialHttpBasicReader(IAuthorizationServerHost authorizationServerHost) { Requires.NotNull(authorizationServerHost, "authorizationServerHost"); this.authorizationServerHost = authorizationServerHost; } + /// <summary> + /// Attempts to extract client identification/authentication information from a message. + /// </summary> + /// <param name="requestMessage">The incoming message.</param> + /// <param name="clientIdentifier">Receives the client identifier, if one was found.</param> + /// <returns>The level of the extracted client information.</returns> public override ClientAuthenticationResult TryAuthenticateClient(AuthenticatedClientRequestBase requestMessage, out string clientIdentifier) { Requires.NotNull(requestMessage, "requestMessage"); diff --git a/src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/ChannelElements/ClientCredentialMessagePartReader.cs b/src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/ChannelElements/ClientCredentialMessagePartReader.cs index 07ededf..2df68a6 100644 --- a/src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/ChannelElements/ClientCredentialMessagePartReader.cs +++ b/src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/ChannelElements/ClientCredentialMessagePartReader.cs @@ -12,14 +12,30 @@ namespace DotNetOpenAuth.OAuth2.ChannelElements { using System.Web; using DotNetOpenAuth.OAuth2.Messages; + /// <summary> + /// Reads client authentication information from the message payload itself (POST entity as a URI-encoded parameter). + /// </summary> public class ClientCredentialMessagePartReader : ClientAuthenticationModuleBase { + /// <summary> + /// The authorization server host. + /// </summary> private readonly IAuthorizationServerHost authorizationServerHost; + /// <summary> + /// Initializes a new instance of the <see cref="ClientCredentialMessagePartReader"/> class. + /// </summary> + /// <param name="authorizationServerHost">The authorization server host.</param> public ClientCredentialMessagePartReader(IAuthorizationServerHost authorizationServerHost) { Requires.NotNull(authorizationServerHost, "authorizationServerHost"); this.authorizationServerHost = authorizationServerHost; } + /// <summary> + /// Attempts to extract client identification/authentication information from a message. + /// </summary> + /// <param name="requestMessage">The incoming message.</param> + /// <param name="clientIdentifier">Receives the client identifier, if one was found.</param> + /// <returns>The level of the extracted client information.</returns> public override ClientAuthenticationResult TryAuthenticateClient(AuthenticatedClientRequestBase requestMessage, out string clientIdentifier) { Requires.NotNull(requestMessage, "requestMessage"); clientIdentifier = requestMessage.ClientIdentifier; diff --git a/src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/ChannelElements/MessageValidationBindingElement.cs b/src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/ChannelElements/MessageValidationBindingElement.cs index fa21bdd..40f3df8 100644 --- a/src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/ChannelElements/MessageValidationBindingElement.cs +++ b/src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/ChannelElements/MessageValidationBindingElement.cs @@ -23,8 +23,15 @@ namespace DotNetOpenAuth.OAuth2.ChannelElements { /// not been revoked and that an access token has not expired. /// </remarks> internal class MessageValidationBindingElement : AuthServerBindingElementBase { + /// <summary> + /// The aggregating client authentication module. + /// </summary> private readonly IClientAuthenticationModule clientAuthenticationModule; + /// <summary> + /// Initializes a new instance of the <see cref="MessageValidationBindingElement"/> class. + /// </summary> + /// <param name="clientAuthenticationModule">The aggregating client authentication module.</param> internal MessageValidationBindingElement(IClientAuthenticationModule clientAuthenticationModule) { Requires.NotNull(clientAuthenticationModule, "clientAuthenticationModule"); this.clientAuthenticationModule = clientAuthenticationModule; diff --git a/src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/ChannelElements/OAuth2AuthorizationServerChannel.cs b/src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/ChannelElements/OAuth2AuthorizationServerChannel.cs index 2521e5f..8c3ed4a 100644 --- a/src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/ChannelElements/OAuth2AuthorizationServerChannel.cs +++ b/src/DotNetOpenAuth.OAuth2.AuthorizationServer/OAuth2/ChannelElements/OAuth2AuthorizationServerChannel.cs @@ -35,6 +35,7 @@ namespace DotNetOpenAuth.OAuth2.ChannelElements { /// Initializes a new instance of the <see cref="OAuth2AuthorizationServerChannel"/> class. /// </summary> /// <param name="authorizationServer">The authorization server.</param> + /// <param name="clientAuthenticationModule">The aggregating client authentication module.</param> protected internal OAuth2AuthorizationServerChannel(IAuthorizationServerHost authorizationServer, IClientAuthenticationModule clientAuthenticationModule) : base(MessageTypes, InitializeBindingElements(authorizationServer, clientAuthenticationModule)) { Requires.NotNull(authorizationServer, "authorizationServer"); @@ -106,13 +107,14 @@ namespace DotNetOpenAuth.OAuth2.ChannelElements { /// Initializes the binding elements for the OAuth channel. /// </summary> /// <param name="authorizationServer">The authorization server.</param> + /// <param name="clientAuthenticationModule">The aggregating client authentication module.</param> /// <returns> /// An array of binding elements used to initialize the channel. /// </returns> private static IChannelBindingElement[] InitializeBindingElements(IAuthorizationServerHost authorizationServer, IClientAuthenticationModule clientAuthenticationModule) { Requires.NotNull(authorizationServer, "authorizationServer"); Requires.NotNull(clientAuthenticationModule, "clientAuthenticationModule"); - + var bindingElements = new List<IChannelBindingElement>(); // The order they are provided is used for outgoing messgaes, and reversed for incoming messages. diff --git a/src/DotNetOpenAuth.OAuth2.Client/DotNetOpenAuth.OAuth2.Client.csproj b/src/DotNetOpenAuth.OAuth2.Client/DotNetOpenAuth.OAuth2.Client.csproj index cfe7d6d..6b84c72 100644 --- a/src/DotNetOpenAuth.OAuth2.Client/DotNetOpenAuth.OAuth2.Client.csproj +++ b/src/DotNetOpenAuth.OAuth2.Client/DotNetOpenAuth.OAuth2.Client.csproj @@ -20,7 +20,6 @@ <ItemGroup> <Compile Include="OAuth2\AuthorizationServerDescription.cs" /> <Compile Include="OAuth2\AuthorizationState.cs" /> - <Compile Include="OAuth2\ChannelElements\IOAuth2ChannelWithClient.cs" /> <Compile Include="OAuth2\ChannelElements\OAuth2ClientChannel.cs" /> <Compile Include="OAuth2\ClientCredentialApplicator.cs" /> <Compile Include="OAuth2\IAuthorizationState.cs" /> diff --git a/src/DotNetOpenAuth.OAuth2.Client/OAuth2/ChannelElements/IOAuth2ChannelWithClient.cs b/src/DotNetOpenAuth.OAuth2.Client/OAuth2/ChannelElements/IOAuth2ChannelWithClient.cs deleted file mode 100644 index 85c3242..0000000 --- a/src/DotNetOpenAuth.OAuth2.Client/OAuth2/ChannelElements/IOAuth2ChannelWithClient.cs +++ /dev/null @@ -1,15 +0,0 @@ -namespace DotNetOpenAuth.OAuth2.ChannelElements { - using System; - using System.Collections.Generic; - using System.Linq; - using System.Text; - - internal interface IOAuth2ChannelWithClient { - /// <summary> - /// Gets or sets the identifier by which this client is known to the Authorization Server. - /// </summary> - string ClientIdentifier { get; set; } - - ClientCredentialApplicator ClientCredentialApplicator { get; set; } - } -} diff --git a/src/DotNetOpenAuth.OAuth2.Client/OAuth2/ChannelElements/OAuth2ClientChannel.cs b/src/DotNetOpenAuth.OAuth2.Client/OAuth2/ChannelElements/OAuth2ClientChannel.cs index 51b1646..10a92e0 100644 --- a/src/DotNetOpenAuth.OAuth2.Client/OAuth2/ChannelElements/OAuth2ClientChannel.cs +++ b/src/DotNetOpenAuth.OAuth2.Client/OAuth2/ChannelElements/OAuth2ClientChannel.cs @@ -18,7 +18,7 @@ namespace DotNetOpenAuth.OAuth2.ChannelElements { /// <summary> /// The messaging channel used by OAuth 2.0 Clients. /// </summary> - internal class OAuth2ClientChannel : OAuth2ChannelBase, IOAuth2ChannelWithClient { + internal class OAuth2ClientChannel : OAuth2ChannelBase { /// <summary> /// The messages receivable by this channel. /// </summary> @@ -39,13 +39,6 @@ namespace DotNetOpenAuth.OAuth2.ChannelElements { } /// <summary> - /// Gets or sets the identifier by which this client is known to the Authorization Server. - /// </summary> - public string ClientIdentifier { get; set; } - - public ClientCredentialApplicator ClientCredentialApplicator { get; set; } - - /// <summary> /// Prepares an HTTP request that carries a given message. /// </summary> /// <param name="request">The message to send.</param> @@ -139,13 +132,5 @@ namespace DotNetOpenAuth.OAuth2.ChannelElements { // Clients don't ever send direct responses. throw new NotImplementedException(); } - - protected override IncomingWebResponse GetDirectResponse(HttpWebRequest webRequest) { - if (this.ClientCredentialApplicator != null) { - this.ClientCredentialApplicator.ApplyClientCredential(this.ClientIdentifier, webRequest); - } - - return base.GetDirectResponse(webRequest); - } } } diff --git a/src/DotNetOpenAuth.OAuth2.Client/OAuth2/ClientBase.cs b/src/DotNetOpenAuth.OAuth2.Client/OAuth2/ClientBase.cs index 271a87e..2cfaede 100644 --- a/src/DotNetOpenAuth.OAuth2.Client/OAuth2/ClientBase.cs +++ b/src/DotNetOpenAuth.OAuth2.Client/OAuth2/ClientBase.cs @@ -53,23 +53,13 @@ namespace DotNetOpenAuth.OAuth2 { /// <summary> /// Gets or sets the identifier by which this client is known to the Authorization Server. /// </summary> - public string ClientIdentifier { - get { return this.OAuthChannel.ClientIdentifier; } - set { this.OAuthChannel.ClientIdentifier = value; } - } + public string ClientIdentifier { get; set; } /// <summary> /// Gets or sets the tool to use to apply client credentials to authenticated requests to the Authorization Server. /// </summary> /// <value>May be <c>null</c> if this client has no client secret.</value> - public ClientCredentialApplicator ClientCredentialApplicator { - get { return this.OAuthChannel.ClientCredentialApplicator; } - set { this.OAuthChannel.ClientCredentialApplicator = value; } - } - - internal IOAuth2ChannelWithClient OAuthChannel { - get { return (IOAuth2ChannelWithClient)this.Channel; } - } + public ClientCredentialApplicator ClientCredentialApplicator { get; set; } /// <summary> /// Adds the necessary HTTP Authorization header to an HTTP request for protected resources @@ -283,9 +273,18 @@ namespace DotNetOpenAuth.OAuth2 { } /// <summary> + /// Applies the default client authentication mechanism given a client secret. + /// </summary> + /// <param name="secret">The client secret. May be <c>null</c></param> + /// <returns>The client credential applicator.</returns> + protected static ClientCredentialApplicator DefaultSecretApplicator(string secret) { + return secret == null ? ClientCredentialApplicator.NoSecret() : ClientCredentialApplicator.SecretParameter(secret); + } + + /// <summary> /// Applies any applicable client credential to an authenticated outbound request to the authorization server. /// </summary> - /// <param name="request"></param> + /// <param name="request">The request to apply authentication information to.</param> protected void ApplyClientCredential(AuthenticatedClientRequestBase request) { Requires.NotNull(request, "request"); @@ -294,10 +293,6 @@ namespace DotNetOpenAuth.OAuth2 { } } - protected static ClientCredentialApplicator DefaultSecretApplicator(string secret) { - return secret == null ? ClientCredentialApplicator.NoSecret() : ClientCredentialApplicator.SecretParameter(secret); - } - /// <summary> /// Calculates the fraction of life remaining in an access token. /// </summary> diff --git a/src/DotNetOpenAuth.OAuth2.Client/OAuth2/ClientCredentialApplicator.cs b/src/DotNetOpenAuth.OAuth2.Client/OAuth2/ClientCredentialApplicator.cs index ac78a90..67e7234 100644 --- a/src/DotNetOpenAuth.OAuth2.Client/OAuth2/ClientCredentialApplicator.cs +++ b/src/DotNetOpenAuth.OAuth2.Client/OAuth2/ClientCredentialApplicator.cs @@ -13,63 +13,108 @@ namespace DotNetOpenAuth.OAuth2 { using DotNetOpenAuth.Messaging; using DotNetOpenAuth.OAuth2.Messages; + /// <summary> + /// A base class for extensions that apply client authentication to messages for the authorization server in specific ways. + /// </summary> public abstract class ClientCredentialApplicator { + /// <summary> + /// Initializes a new instance of the <see cref="ClientCredentialApplicator"/> class. + /// </summary> protected ClientCredentialApplicator() { } + /// <summary> + /// Transmits the secret the client shares with the authorization server as a parameter in the POST entity payload. + /// </summary> + /// <param name="clientSecret">The secret the client shares with the authorization server.</param> + /// <returns>The credential applicator to provide to the <see cref="ClientBase"/> instance.</returns> public static ClientCredentialApplicator SecretParameter(string clientSecret) { Requires.NotNullOrEmpty(clientSecret, "clientSecret"); return new SecretParameterApplicator(clientSecret); } - public static ClientCredentialApplicator NetworkCredential(NetworkCredential credential) { - Requires.NotNull(credential, "credential"); - return new NetworkCredentialApplicator(credential); + /// <summary> + /// Transmits the client identifier and secret in the HTTP Authorization header via HTTP Basic authentication. + /// </summary> + /// <param name="clientSecret">The secret the client shares with the authorization server.</param> + /// <returns>The credential applicator to provide to the <see cref="ClientBase"/> instance.</returns> + public static ClientCredentialApplicator HttpBasic(string clientSecret) { + Requires.NotNullOrEmpty(clientSecret, "clientSecret"); + return new HttpBasicApplicator(clientSecret); } + /// <summary> + /// Never transmits a secret. Useful for anonymous clients or clients unable to keep a secret. + /// </summary> + /// <returns>The credential applicator to provide to the <see cref="ClientBase"/> instance.</returns> public static ClientCredentialApplicator NoSecret() { return null; } - public virtual void ApplyClientCredential(string clientIdentifier, AuthenticatedClientRequestBase request) { - } + /// <summary> + /// Applies the client identifier and (when applicable) the client authentication to an outbound message. + /// </summary> + /// <param name="clientIdentifier">The identifier by which the authorization server should recognize this client.</param> + /// <param name="request">The outbound message to apply authentication information to.</param> + public abstract void ApplyClientCredential(string clientIdentifier, AuthenticatedClientRequestBase request); - public virtual void ApplyClientCredential(string clientIdentifier, HttpWebRequest request) { - } + /// <summary> + /// Authenticates the client via HTTP Basic. + /// </summary> + private class HttpBasicApplicator : ClientCredentialApplicator { + /// <summary> + /// The client secret. + /// </summary> + private readonly string clientSecret; - private class NetworkCredentialApplicator : ClientCredentialApplicator { - private readonly NetworkCredential credential; - - internal NetworkCredentialApplicator(NetworkCredential credential) { - Requires.NotNull(credential, "credential"); - this.credential = credential; + /// <summary> + /// Initializes a new instance of the <see cref="HttpBasicApplicator"/> class. + /// </summary> + /// <param name="clientSecret">The client secret.</param> + internal HttpBasicApplicator(string clientSecret) { + Requires.NotNullOrEmpty(clientSecret, "clientSecret"); + this.clientSecret = clientSecret; } + /// <summary> + /// Applies the client identifier and (when applicable) the client authentication to an outbound message. + /// </summary> + /// <param name="clientIdentifier">The identifier by which the authorization server should recognize this client.</param> + /// <param name="request">The outbound message to apply authentication information to.</param> public override void ApplyClientCredential(string clientIdentifier, AuthenticatedClientRequestBase request) { // When using network credentials, the client authentication is not done as standard message parts. request.ClientIdentifier = null; request.ClientSecret = null; - OAuthUtilities.ApplyHttpBasicAuth(request.Headers, clientIdentifier, this.credential.Password); - } - - public override void ApplyClientCredential(string clientIdentifier, HttpWebRequest request) { + OAuthUtilities.ApplyHttpBasicAuth(request.Headers, clientIdentifier, this.clientSecret); } } + /// <summary> + /// Authenticates the client via a client_secret parameter in the message. + /// </summary> private class SecretParameterApplicator : ClientCredentialApplicator { + /// <summary> + /// The client secret. + /// </summary> private readonly string secret; + /// <summary> + /// Initializes a new instance of the <see cref="SecretParameterApplicator"/> class. + /// </summary> + /// <param name="clientSecret">The client secret.</param> internal SecretParameterApplicator(string clientSecret) { Requires.NotNullOrEmpty(clientSecret, "clientSecret"); this.secret = clientSecret; } + /// <summary> + /// Applies the client identifier and (when applicable) the client authentication to an outbound message. + /// </summary> + /// <param name="clientIdentifier">The identifier by which the authorization server should recognize this client.</param> + /// <param name="request">The outbound message to apply authentication information to.</param> public override void ApplyClientCredential(string clientIdentifier, AuthenticatedClientRequestBase request) { request.ClientSecret = this.secret; } - - public override void ApplyClientCredential(string clientIdentifier, HttpWebRequest request) { - } } } } diff --git a/src/DotNetOpenAuth.OAuth2.ClientAuthorization/OAuth2/Messages/AuthenticatedClientRequestBase.cs b/src/DotNetOpenAuth.OAuth2.ClientAuthorization/OAuth2/Messages/AuthenticatedClientRequestBase.cs index 03d5c8a..4631d83 100644 --- a/src/DotNetOpenAuth.OAuth2.ClientAuthorization/OAuth2/Messages/AuthenticatedClientRequestBase.cs +++ b/src/DotNetOpenAuth.OAuth2.ClientAuthorization/OAuth2/Messages/AuthenticatedClientRequestBase.cs @@ -13,6 +13,9 @@ namespace DotNetOpenAuth.OAuth2.Messages { /// A direct message from the client to the authorization server that includes the client's credentials. /// </summary> public abstract class AuthenticatedClientRequestBase : MessageBase, IHttpDirectRequest { + /// <summary> + /// The backing for the <see cref="Headers"/> property. + /// </summary> private readonly WebHeaderCollection headers = new WebHeaderCollection(); /// <summary> @@ -44,6 +47,10 @@ namespace DotNetOpenAuth.OAuth2.Messages { [MessagePart(Protocol.client_secret, IsRequired = false)] public string ClientSecret { get; internal set; } + /// <summary> + /// Gets the HTTP headers of the request. + /// </summary> + /// <value>May be an empty collection, but must not be <c>null</c>.</value> public WebHeaderCollection Headers { get { return this.headers; } } diff --git a/src/DotNetOpenAuth.OAuth2/Configuration/OAuth2AuthorizationServerElement.cs b/src/DotNetOpenAuth.OAuth2/Configuration/OAuth2AuthorizationServerElement.cs index fa7b52e..1329ce2 100644 --- a/src/DotNetOpenAuth.OAuth2/Configuration/OAuth2AuthorizationServerElement.cs +++ b/src/DotNetOpenAuth.OAuth2/Configuration/OAuth2AuthorizationServerElement.cs @@ -14,7 +14,6 @@ namespace DotNetOpenAuth.Configuration { /// Represents the <oauth2/authorizationServer> element in the host's .config file. /// </summary> internal class OAuth2AuthorizationServerElement : ConfigurationElement { - /// <summary> /// The name of the <clientAuthenticationModules> sub-element. /// </summary> @@ -23,7 +22,7 @@ namespace DotNetOpenAuth.Configuration { /// <summary> /// The built-in set of identifier discovery services. /// </summary> - private static readonly TypeConfigurationCollection<IClientAuthenticationModule> defaultClientAuthenticationModules = + private static readonly TypeConfigurationCollection<IClientAuthenticationModule> defaultClientAuthenticationModules = new TypeConfigurationCollection<IClientAuthenticationModule>(); /// <summary> diff --git a/src/DotNetOpenAuth.OAuth2/DotNetOpenAuth.OAuth2.csproj b/src/DotNetOpenAuth.OAuth2/DotNetOpenAuth.OAuth2.csproj index a3eda22..74dd1b6 100644 --- a/src/DotNetOpenAuth.OAuth2/DotNetOpenAuth.OAuth2.csproj +++ b/src/DotNetOpenAuth.OAuth2/DotNetOpenAuth.OAuth2.csproj @@ -25,6 +25,7 @@ <Compile Include="GlobalSuppressions.cs" /> <Compile Include="OAuth2\AccessToken.cs" /> <Compile Include="OAuth2\ChannelElements\AuthorizationDataBag.cs" /> + <Compile Include="OAuth2\ChannelElements\ClientAuthenticationResult.cs" /> <Compile Include="OAuth2\ChannelElements\IAccessTokenCarryingRequest.cs" /> <Compile Include="OAuth2\ChannelElements\IClientAuthenticationModule.cs" /> <Compile Include="OAuth2\ChannelElements\ScopeEncoder.cs" /> diff --git a/src/DotNetOpenAuth.OAuth2/OAuth2/ChannelElements/ClientAuthenticationResult.cs b/src/DotNetOpenAuth.OAuth2/OAuth2/ChannelElements/ClientAuthenticationResult.cs new file mode 100644 index 0000000..b0f86a9 --- /dev/null +++ b/src/DotNetOpenAuth.OAuth2/OAuth2/ChannelElements/ClientAuthenticationResult.cs @@ -0,0 +1,32 @@ +//----------------------------------------------------------------------- +// <copyright file="ClientAuthenticationResult.cs" company="Andrew Arnott"> +// Copyright (c) Andrew Arnott. All rights reserved. +// </copyright> +//----------------------------------------------------------------------- + +namespace DotNetOpenAuth.OAuth2.ChannelElements { + /// <summary> + /// Describes the various levels at which client information may be extracted from an inbound message. + /// </summary> + public enum ClientAuthenticationResult { + /// <summary> + /// No client identification or authentication was discovered. + /// </summary> + NoAuthenticationRecognized, + + /// <summary> + /// The client identified itself, but did not attempt to authenticate itself. + /// </summary> + ClientIdNotAuthenticated, + + /// <summary> + /// The client authenticated itself (provided compelling evidence that it was who it claims to be). + /// </summary> + ClientAuthenticated, + + /// <summary> + /// The client failed in an attempt to authenticate itself, claimed to be an unrecognized client, or otherwise messed up. + /// </summary> + ClientAuthenticationRejected, + } +} diff --git a/src/DotNetOpenAuth.OAuth2/OAuth2/ChannelElements/IClientAuthenticationModule.cs b/src/DotNetOpenAuth.OAuth2/OAuth2/ChannelElements/IClientAuthenticationModule.cs index b7c4792..470e533 100644 --- a/src/DotNetOpenAuth.OAuth2/OAuth2/ChannelElements/IClientAuthenticationModule.cs +++ b/src/DotNetOpenAuth.OAuth2/OAuth2/ChannelElements/IClientAuthenticationModule.cs @@ -1,22 +1,23 @@ -namespace DotNetOpenAuth.OAuth2.ChannelElements { - using System; - using System.Collections.Generic; - using System.Linq; - using System.Text; - using System.Web; - using DotNetOpenAuth.Messaging; - - public enum ClientAuthenticationResult { - NoAuthenticationRecognized, - - ClientIdNotAuthenticated, +//----------------------------------------------------------------------- +// <copyright file="IClientAuthenticationModule.cs" company="Andrew Arnott"> +// Copyright (c) Andrew Arnott. All rights reserved. +// </copyright> +//----------------------------------------------------------------------- - ClientAuthenticated, - - ClientAuthenticationRejected, - } +namespace DotNetOpenAuth.OAuth2.ChannelElements { + using DotNetOpenAuth.Messaging; + /// <summary> + /// An interface implemented by extension that can read incoming messages and extract the client identifier and + /// possibly authentication information (like a shared secret, signed nonce, etc.) + /// </summary> public interface IClientAuthenticationModule { + /// <summary> + /// Attempts to extract client identification/authentication information from a message. + /// </summary> + /// <param name="requestMessage">The incoming message. Always an instance of <see cref="AuthenticatedClientRequestBase"/></param> + /// <param name="clientIdentifier">Receives the client identifier, if one was found.</param> + /// <returns>The level of the extracted client information.</returns> ClientAuthenticationResult TryAuthenticateClient(IDirectedProtocolMessage requestMessage, out string clientIdentifier); } } diff --git a/src/DotNetOpenAuth.OAuth2/OAuth2/OAuthUtilities.cs b/src/DotNetOpenAuth.OAuth2/OAuth2/OAuthUtilities.cs index 2e83482..661d102 100644 --- a/src/DotNetOpenAuth.OAuth2/OAuth2/OAuthUtilities.cs +++ b/src/DotNetOpenAuth.OAuth2/OAuth2/OAuthUtilities.cs @@ -18,21 +18,32 @@ namespace DotNetOpenAuth.OAuth2 { /// Some common utility methods for OAuth 2.0. /// </summary> public static class OAuthUtilities { - private const string HttpBasicAuthScheme = "Basic "; - /// <summary> /// The <see cref="StringComparer"/> instance to use when comparing scope equivalence. /// </summary> public static readonly StringComparer ScopeStringComparer = StringComparer.Ordinal; /// <summary> + /// The string "Basic ". + /// </summary> + private const string HttpBasicAuthScheme = "Basic "; + + /// <summary> /// The delimiter between scope elements. /// </summary> - private static char[] scopeDelimiter = new char[] { ' ' }; + private static readonly char[] scopeDelimiter = new char[] { ' ' }; + /// <summary> + /// A colon, in a 1-length character array. + /// </summary> private static readonly char[] ColonSeparator = new char[] { ':' }; /// <summary> + /// The encoding to use when preparing credentials for transit in HTTP Basic base64 encoding form. + /// </summary> + private static readonly Encoding HttpBasicEncoding = Encoding.UTF8; + + /// <summary> /// The characters that may appear in an access token that is included in an HTTP Authorization header. /// </summary> /// <remarks> @@ -134,8 +145,12 @@ namespace DotNetOpenAuth.OAuth2 { accessToken); } - private static readonly Encoding HttpBasicEncoding = Encoding.UTF8; - + /// <summary> + /// Applies the HTTP Authorization header for HTTP Basic authentication. + /// </summary> + /// <param name="headers">The headers collection to set the authorization header to.</param> + /// <param name="userName">The username. Cannot be empty.</param> + /// <param name="password">The password. Cannot be null.</param> internal static void ApplyHttpBasicAuth(WebHeaderCollection headers, string userName, string password) { Requires.NotNull(headers, "headers"); Requires.NotNullOrEmpty(userName, "userName"); @@ -148,6 +163,11 @@ namespace DotNetOpenAuth.OAuth2 { headers[HttpRequestHeader.Authorization] = header; } + /// <summary> + /// Extracts the username and password from an HTTP Basic authorized web header. + /// </summary> + /// <param name="headers">The incoming web headers.</param> + /// <returns>The network credentials; or <c>null</c> if none could be discovered in the request.</returns> internal static NetworkCredential ParseHttpBasicAuth(WebHeaderCollection headers) { Requires.NotNull(headers, "headers"); diff --git a/src/DotNetOpenAuth.Test/DotNetOpenAuth.Test.csproj b/src/DotNetOpenAuth.Test/DotNetOpenAuth.Test.csproj index dae4a65..a3edcf6 100644 --- a/src/DotNetOpenAuth.Test/DotNetOpenAuth.Test.csproj +++ b/src/DotNetOpenAuth.Test/DotNetOpenAuth.Test.csproj @@ -219,7 +219,6 @@ <Compile Include="Mocks\CoordinatingChannel.cs" /> <Compile Include="Mocks\CoordinatingHttpRequestInfo.cs" /> <Compile Include="Mocks\CoordinatingOAuth2AuthServerChannel.cs" /> - <Compile Include="Mocks\CoordinatingOAuth2ClientChannel.cs" /> <Compile Include="Mocks\CoordinatingOutgoingWebResponse.cs" /> <Compile Include="Mocks\CoordinatingOAuthConsumerChannel.cs" /> <Compile Include="Mocks\IBaseMessageExplicitMembers.cs" /> diff --git a/src/DotNetOpenAuth.Test/Mocks/CoordinatingOAuth2ClientChannel.cs b/src/DotNetOpenAuth.Test/Mocks/CoordinatingOAuth2ClientChannel.cs deleted file mode 100644 index 1e70f80..0000000 --- a/src/DotNetOpenAuth.Test/Mocks/CoordinatingOAuth2ClientChannel.cs +++ /dev/null @@ -1,27 +0,0 @@ -namespace DotNetOpenAuth.Test.Mocks { - using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using DotNetOpenAuth.Messaging; -using DotNetOpenAuth.OAuth2.ChannelElements; - - internal class CoordinatingOAuth2ClientChannel : CoordinatingChannel, IOAuth2ChannelWithClient { - private OAuth2ClientChannel wrappedChannel; - - internal CoordinatingOAuth2ClientChannel(Channel wrappedChannel, Action<IProtocolMessage> incomingMessageFilter, Action<IProtocolMessage> outgoingMessageFilter) - : base(wrappedChannel, incomingMessageFilter, outgoingMessageFilter) { - this.wrappedChannel = (OAuth2ClientChannel)wrappedChannel; - } - - public string ClientIdentifier { - get { return this.wrappedChannel.ClientIdentifier; } - set { this.wrappedChannel.ClientIdentifier = value; } - } - - public DotNetOpenAuth.OAuth2.ClientCredentialApplicator ClientCredentialApplicator { - get { return this.wrappedChannel.ClientCredentialApplicator; } - set { this.wrappedChannel.ClientCredentialApplicator = value; } - } - } -} diff --git a/src/DotNetOpenAuth.Test/OAuth2/OAuth2Coordinator.cs b/src/DotNetOpenAuth.Test/OAuth2/OAuth2Coordinator.cs index fa4ffef..afc1335 100644 --- a/src/DotNetOpenAuth.Test/OAuth2/OAuth2Coordinator.cs +++ b/src/DotNetOpenAuth.Test/OAuth2/OAuth2Coordinator.cs @@ -35,13 +35,13 @@ namespace DotNetOpenAuth.Test.OAuth2 { this.client = client; this.client.ClientIdentifier = OAuth2TestBase.ClientId; - this.client.ClientCredentialApplicator = ClientCredentialApplicator.NetworkCredential(new NetworkCredential(OAuth2TestBase.ClientId, OAuth2TestBase.ClientSecret)); + this.client.ClientCredentialApplicator = ClientCredentialApplicator.HttpBasic(OAuth2TestBase.ClientSecret); } internal override void Run() { var authServer = new AuthorizationServer(this.authServerHost); - var rpCoordinatingChannel = new CoordinatingOAuth2ClientChannel(this.client.Channel, this.IncomingMessageFilter, this.OutgoingMessageFilter); + var rpCoordinatingChannel = new CoordinatingChannel(this.client.Channel, this.IncomingMessageFilter, this.OutgoingMessageFilter); var opCoordinatingChannel = new CoordinatingOAuth2AuthServerChannel(authServer.Channel, this.IncomingMessageFilter, this.OutgoingMessageFilter); rpCoordinatingChannel.RemoteChannel = opCoordinatingChannel; opCoordinatingChannel.RemoteChannel = rpCoordinatingChannel; |