diff options
author | Andrew Arnott <andrewarnott@gmail.com> | 2012-04-19 20:58:49 -0700 |
---|---|---|
committer | Andrew Arnott <andrewarnott@gmail.com> | 2012-04-19 20:58:49 -0700 |
commit | c0e019b7ff53df92f76b325d28a931b9036ab73a (patch) | |
tree | 788bfe014785d32b64c136c6c66d372a68b9cdd4 /src/DotNetOpenAuth.OAuth2.Client/OAuth2 | |
parent | 548147a67be56f046a7d4515d61a8210d78677de (diff) | |
download | DotNetOpenAuth-c0e019b7ff53df92f76b325d28a931b9036ab73a.zip DotNetOpenAuth-c0e019b7ff53df92f76b325d28a931b9036ab73a.tar.gz DotNetOpenAuth-c0e019b7ff53df92f76b325d28a931b9036ab73a.tar.bz2 |
Fixed HTTP Basic authentication for OAuth 2 clients so that it actually works in the sample.
Diffstat (limited to 'src/DotNetOpenAuth.OAuth2.Client/OAuth2')
4 files changed, 116 insertions, 11 deletions
diff --git a/src/DotNetOpenAuth.OAuth2.Client/OAuth2/ChannelElements/IOAuth2ChannelWithClient.cs b/src/DotNetOpenAuth.OAuth2.Client/OAuth2/ChannelElements/IOAuth2ChannelWithClient.cs new file mode 100644 index 0000000..c802be6 --- /dev/null +++ b/src/DotNetOpenAuth.OAuth2.Client/OAuth2/ChannelElements/IOAuth2ChannelWithClient.cs @@ -0,0 +1,27 @@ +//----------------------------------------------------------------------- +// <copyright file="IOAuth2ChannelWithClient.cs" company="Andrew Arnott"> +// Copyright (c) Andrew Arnott. All rights reserved. +// </copyright> +//----------------------------------------------------------------------- + +namespace DotNetOpenAuth.OAuth2.ChannelElements { + using System; + using System.Collections.Generic; + using System.Linq; + using System.Text; + + /// <summary> + /// An interface that defines the OAuth2 client specific channel additions. + /// </summary> + internal interface IOAuth2ChannelWithClient { + /// <summary> + /// Gets or sets the identifier by which this client is known to the Authorization Server. + /// </summary> + string ClientIdentifier { get; set; } + + /// <summary> + /// Gets or sets the client credentials applicator extension to use. + /// </summary> + 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 10a92e0..8ad2ed9 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 { + internal class OAuth2ClientChannel : OAuth2ChannelBase, IOAuth2ChannelWithClient { /// <summary> /// The messages receivable by this channel. /// </summary> @@ -39,6 +39,17 @@ 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; } + + /// <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; set; } + + /// <summary> /// Prepares an HTTP request that carries a given message. /// </summary> /// <param name="request">The message to send.</param> @@ -132,5 +143,17 @@ namespace DotNetOpenAuth.OAuth2.ChannelElements { // Clients don't ever send direct responses. throw new NotImplementedException(); } + + /// <summary> + /// Performs additional processing on an outgoing web request before it is sent to the remote server. + /// </summary> + /// <param name="request">The request.</param> + protected override void PrepareHttpWebRequest(HttpWebRequest request) { + base.PrepareHttpWebRequest(request); + + if (this.ClientCredentialApplicator != null) { + this.ClientCredentialApplicator.ApplyClientCredential(this.ClientIdentifier, request); + } + } } } diff --git a/src/DotNetOpenAuth.OAuth2.Client/OAuth2/ClientBase.cs b/src/DotNetOpenAuth.OAuth2.Client/OAuth2/ClientBase.cs index dd34b12..77b0f92 100644 --- a/src/DotNetOpenAuth.OAuth2.Client/OAuth2/ClientBase.cs +++ b/src/DotNetOpenAuth.OAuth2.Client/OAuth2/ClientBase.cs @@ -53,13 +53,23 @@ namespace DotNetOpenAuth.OAuth2 { /// <summary> /// Gets or sets the identifier by which this client is known to the Authorization Server. /// </summary> - public string ClientIdentifier { get; set; } + public string ClientIdentifier { + get { return this.OAuthChannel.ClientIdentifier; } + set { this.OAuthChannel.ClientIdentifier = value; } + } /// <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; set; } + public ClientCredentialApplicator ClientCredentialApplicator { + get { return this.OAuthChannel.ClientCredentialApplicator; } + set { this.OAuthChannel.ClientCredentialApplicator = value; } + } + + internal IOAuth2ChannelWithClient OAuthChannel { + get { return (IOAuth2ChannelWithClient)this.Channel; } + } /// <summary> /// Adds the necessary HTTP Authorization header to an HTTP request for protected resources @@ -278,7 +288,7 @@ namespace DotNetOpenAuth.OAuth2 { /// <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.HttpBasic(secret); + return secret == null ? ClientCredentialApplicator.NoSecret() : ClientCredentialApplicator.NetworkCredential(secret); } /// <summary> diff --git a/src/DotNetOpenAuth.OAuth2.Client/OAuth2/ClientCredentialApplicator.cs b/src/DotNetOpenAuth.OAuth2.Client/OAuth2/ClientCredentialApplicator.cs index a95f3d0..2a9a8a7 100644 --- a/src/DotNetOpenAuth.OAuth2.Client/OAuth2/ClientCredentialApplicator.cs +++ b/src/DotNetOpenAuth.OAuth2.Client/OAuth2/ClientCredentialApplicator.cs @@ -36,11 +36,21 @@ namespace DotNetOpenAuth.OAuth2 { /// <summary> /// Transmits the client identifier and secret in the HTTP Authorization header via HTTP Basic authentication. /// </summary> + /// <param name="credential">The client id and secret.</param> + /// <returns>The credential applicator to provide to the <see cref="ClientBase"/> instance.</returns> + 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) { + public static ClientCredentialApplicator NetworkCredential(string clientSecret) { Requires.NotNullOrEmpty(clientSecret, "clientSecret"); - return new HttpBasicApplicator(clientSecret); + return new NetworkCredentialApplicator(clientSecret); } /// <summary> @@ -56,27 +66,50 @@ namespace DotNetOpenAuth.OAuth2 { /// </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, 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 virtual void ApplyClientCredential(string clientIdentifier, HttpWebRequest request) { + } /// <summary> /// Authenticates the client via HTTP Basic. /// </summary> - private class HttpBasicApplicator : ClientCredentialApplicator { + private class NetworkCredentialApplicator : ClientCredentialApplicator { + /// <summary> + /// The client identifier and secret. + /// </summary> + private readonly NetworkCredential credential; + /// <summary> /// The client secret. /// </summary> private readonly string clientSecret; /// <summary> - /// Initializes a new instance of the <see cref="HttpBasicApplicator"/> class. + /// Initializes a new instance of the <see cref="NetworkCredentialApplicator"/> class. /// </summary> /// <param name="clientSecret">The client secret.</param> - internal HttpBasicApplicator(string clientSecret) { + internal NetworkCredentialApplicator(string clientSecret) { Requires.NotNullOrEmpty(clientSecret, "clientSecret"); this.clientSecret = clientSecret; } /// <summary> + /// Initializes a new instance of the <see cref="NetworkCredentialApplicator"/> class. + /// </summary> + /// <param name="credential">The client credential.</param> + internal NetworkCredentialApplicator(NetworkCredential credential) { + Requires.NotNull(credential, "credential"); + this.credential = credential; + } + + /// <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> @@ -85,7 +118,19 @@ namespace DotNetOpenAuth.OAuth2 { // 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.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, HttpWebRequest request) { + if (this.credential != null && this.credential.UserName == clientIdentifier) { + ErrorUtilities.VerifyHost(false, "Client identifiers \"{0}\" and \"{1}\" do not match.", this.credential.UserName, clientIdentifier); + } + + request.Credentials = this.credential ?? new NetworkCredential(clientIdentifier, this.clientSecret); } } |