summaryrefslogtreecommitdiffstats
path: root/src/DotNetOAuth/OAuth/ChannelElements
diff options
context:
space:
mode:
authorAndrew Arnott <andrewarnott@gmail.com>2008-11-03 17:22:00 -0800
committerAndrew <andrewarnott@gmail.com>2008-11-04 08:12:52 -0800
commit462e19abd9034c11a12cad30e9899740f2bef8ff (patch)
treee08667f1d69249f8daa6c348a919bd0fd5434415 /src/DotNetOAuth/OAuth/ChannelElements
parent6a79be0eca3929d8fb4e797799dac8d6f7875475 (diff)
downloadDotNetOpenAuth-462e19abd9034c11a12cad30e9899740f2bef8ff.zip
DotNetOpenAuth-462e19abd9034c11a12cad30e9899740f2bef8ff.tar.gz
DotNetOpenAuth-462e19abd9034c11a12cad30e9899740f2bef8ff.tar.bz2
Changed namepace and project names in preparation for merge with DotNetOpenId.
Diffstat (limited to 'src/DotNetOAuth/OAuth/ChannelElements')
-rw-r--r--src/DotNetOAuth/OAuth/ChannelElements/HmacSha1SigningBindingElement.cs48
-rw-r--r--src/DotNetOAuth/OAuth/ChannelElements/IOAuthDirectedMessage.cs25
-rw-r--r--src/DotNetOAuth/OAuth/ChannelElements/ITamperResistantOAuthMessage.cs41
-rw-r--r--src/DotNetOAuth/OAuth/ChannelElements/ITokenGenerator.cs40
-rw-r--r--src/DotNetOAuth/OAuth/ChannelElements/ITokenManager.cs80
-rw-r--r--src/DotNetOAuth/OAuth/ChannelElements/IWebRequestHandler.cs31
-rw-r--r--src/DotNetOAuth/OAuth/ChannelElements/OAuthChannel.cs397
-rw-r--r--src/DotNetOAuth/OAuth/ChannelElements/OAuthConsumerMessageTypeProvider.cs97
-rw-r--r--src/DotNetOAuth/OAuth/ChannelElements/OAuthHttpMethodBindingElement.cs73
-rw-r--r--src/DotNetOAuth/OAuth/ChannelElements/OAuthServiceProviderMessageTypeProvider.cs106
-rw-r--r--src/DotNetOAuth/OAuth/ChannelElements/PlaintextSigningBindingElement.cs55
-rw-r--r--src/DotNetOAuth/OAuth/ChannelElements/RsaSha1SigningBindingElement.cs48
-rw-r--r--src/DotNetOAuth/OAuth/ChannelElements/SigningBindingElementBase.cs242
-rw-r--r--src/DotNetOAuth/OAuth/ChannelElements/SigningBindingElementChain.cs132
-rw-r--r--src/DotNetOAuth/OAuth/ChannelElements/StandardTokenGenerator.cs68
-rw-r--r--src/DotNetOAuth/OAuth/ChannelElements/StandardWebRequestHandler.cs70
-rw-r--r--src/DotNetOAuth/OAuth/ChannelElements/TokenType.cs30
17 files changed, 0 insertions, 1583 deletions
diff --git a/src/DotNetOAuth/OAuth/ChannelElements/HmacSha1SigningBindingElement.cs b/src/DotNetOAuth/OAuth/ChannelElements/HmacSha1SigningBindingElement.cs
deleted file mode 100644
index a0878aa..0000000
--- a/src/DotNetOAuth/OAuth/ChannelElements/HmacSha1SigningBindingElement.cs
+++ /dev/null
@@ -1,48 +0,0 @@
-//-----------------------------------------------------------------------
-// <copyright file="HmacSha1SigningBindingElement.cs" company="Andrew Arnott">
-// Copyright (c) Andrew Arnott. All rights reserved.
-// </copyright>
-//-----------------------------------------------------------------------
-
-namespace DotNetOAuth.OAuth.ChannelElements {
- using System;
- using System.Security.Cryptography;
- using System.Text;
- using DotNetOAuth.Messaging;
-
- /// <summary>
- /// A binding element that signs outgoing messages and verifies the signature on incoming messages.
- /// </summary>
- public class HmacSha1SigningBindingElement : SigningBindingElementBase {
- /// <summary>
- /// Initializes a new instance of the <see cref="HmacSha1SigningBindingElement"/> class
- /// </summary>
- public HmacSha1SigningBindingElement()
- : base("HMAC-SHA1") {
- }
-
- /// <summary>
- /// Calculates a signature for a given message.
- /// </summary>
- /// <param name="message">The message to sign.</param>
- /// <returns>The signature for the message.</returns>
- /// <remarks>
- /// This method signs the message per OAuth 1.0 section 9.2.
- /// </remarks>
- protected override string GetSignature(ITamperResistantOAuthMessage message) {
- string key = GetConsumerAndTokenSecretString(message);
- HashAlgorithm hasher = new HMACSHA1(Encoding.ASCII.GetBytes(key));
- string baseString = ConstructSignatureBaseString(message);
- byte[] digest = hasher.ComputeHash(Encoding.ASCII.GetBytes(baseString));
- return Convert.ToBase64String(digest);
- }
-
- /// <summary>
- /// Clones this instance.
- /// </summary>
- /// <returns>A new instance of the binding element.</returns>
- protected override ITamperProtectionChannelBindingElement Clone() {
- return new HmacSha1SigningBindingElement();
- }
- }
-}
diff --git a/src/DotNetOAuth/OAuth/ChannelElements/IOAuthDirectedMessage.cs b/src/DotNetOAuth/OAuth/ChannelElements/IOAuthDirectedMessage.cs
deleted file mode 100644
index 9151464..0000000
--- a/src/DotNetOAuth/OAuth/ChannelElements/IOAuthDirectedMessage.cs
+++ /dev/null
@@ -1,25 +0,0 @@
-//-----------------------------------------------------------------------
-// <copyright file="IOAuthDirectedMessage.cs" company="Andrew Arnott">
-// Copyright (c) Andrew Arnott. All rights reserved.
-// </copyright>
-//-----------------------------------------------------------------------
-
-namespace DotNetOAuth.OAuth.ChannelElements {
- using System;
- using DotNetOAuth.Messaging;
-
- /// <summary>
- /// Additional properties that apply specifically to OAuth messages.
- /// </summary>
- public interface IOAuthDirectedMessage : IDirectedProtocolMessage {
- /// <summary>
- /// Gets the preferred method of transport for the message.
- /// </summary>
- HttpDeliveryMethods HttpMethods { get; }
-
- /// <summary>
- /// Gets or sets the URL of the intended receiver of this message.
- /// </summary>
- new Uri Recipient { get; set; }
- }
-}
diff --git a/src/DotNetOAuth/OAuth/ChannelElements/ITamperResistantOAuthMessage.cs b/src/DotNetOAuth/OAuth/ChannelElements/ITamperResistantOAuthMessage.cs
deleted file mode 100644
index aaba53b..0000000
--- a/src/DotNetOAuth/OAuth/ChannelElements/ITamperResistantOAuthMessage.cs
+++ /dev/null
@@ -1,41 +0,0 @@
-//-----------------------------------------------------------------------
-// <copyright file="ITamperResistantOAuthMessage.cs" company="Andrew Arnott">
-// Copyright (c) Andrew Arnott. All rights reserved.
-// </copyright>
-//-----------------------------------------------------------------------
-
-namespace DotNetOAuth.OAuth.ChannelElements {
- using System.Collections.Generic;
- using DotNetOAuth.Messaging;
- using DotNetOAuth.Messaging.Bindings;
-
- /// <summary>
- /// An interface that OAuth messages implement to support signing.
- /// </summary>
- public interface ITamperResistantOAuthMessage : IOAuthDirectedMessage, ITamperResistantProtocolMessage {
- /// <summary>
- /// Gets or sets the method used to sign the message.
- /// </summary>
- string SignatureMethod { get; set; }
-
- /// <summary>
- /// Gets or sets the Token Secret used to sign the message.
- /// </summary>
- string TokenSecret { get; set; }
-
- /// <summary>
- /// Gets or sets the Consumer key.
- /// </summary>
- string ConsumerKey { get; set; }
-
- /// <summary>
- /// Gets or sets the Consumer Secret used to sign the message.
- /// </summary>
- string ConsumerSecret { get; set; }
-
- /// <summary>
- /// Gets or sets the HTTP method that will be used to transmit the message.
- /// </summary>
- string HttpMethod { get; set; }
- }
-}
diff --git a/src/DotNetOAuth/OAuth/ChannelElements/ITokenGenerator.cs b/src/DotNetOAuth/OAuth/ChannelElements/ITokenGenerator.cs
deleted file mode 100644
index 888ba05..0000000
--- a/src/DotNetOAuth/OAuth/ChannelElements/ITokenGenerator.cs
+++ /dev/null
@@ -1,40 +0,0 @@
-//-----------------------------------------------------------------------
-// <copyright file="ITokenGenerator.cs" company="Andrew Arnott">
-// Copyright (c) Andrew Arnott. All rights reserved.
-// </copyright>
-//-----------------------------------------------------------------------
-
-namespace DotNetOAuth.OAuth.ChannelElements {
- /// <summary>
- /// An interface allowing OAuth hosts to inject their own algorithm for generating tokens and secrets.
- /// </summary>
- public interface ITokenGenerator {
- /// <summary>
- /// Generates a new token to represent a not-yet-authorized request to access protected resources.
- /// </summary>
- /// <param name="consumerKey">The consumer that requested this token.</param>
- /// <returns>The newly generated token.</returns>
- /// <remarks>
- /// This method should not store the newly generated token in any persistent store.
- /// This will be done in <see cref="ITokenManager.StoreNewRequestToken"/>.
- /// </remarks>
- string GenerateRequestToken(string consumerKey);
-
- /// <summary>
- /// Generates a new token to represent an authorized request to access protected resources.
- /// </summary>
- /// <param name="consumerKey">The consumer that requested this token.</param>
- /// <returns>The newly generated token.</returns>
- /// <remarks>
- /// This method should not store the newly generated token in any persistent store.
- /// This will be done in <see cref="ITokenManager.ExpireRequestTokenAndStoreNewAccessToken"/>.
- /// </remarks>
- string GenerateAccessToken(string consumerKey);
-
- /// <summary>
- /// Returns a cryptographically strong random string for use as a token secret.
- /// </summary>
- /// <returns>The generated string.</returns>
- string GenerateSecret();
- }
-}
diff --git a/src/DotNetOAuth/OAuth/ChannelElements/ITokenManager.cs b/src/DotNetOAuth/OAuth/ChannelElements/ITokenManager.cs
deleted file mode 100644
index 257e44e..0000000
--- a/src/DotNetOAuth/OAuth/ChannelElements/ITokenManager.cs
+++ /dev/null
@@ -1,80 +0,0 @@
-//-----------------------------------------------------------------------
-// <copyright file="ITokenManager.cs" company="Andrew Arnott">
-// Copyright (c) Andrew Arnott. All rights reserved.
-// </copyright>
-//-----------------------------------------------------------------------
-
-namespace DotNetOAuth.OAuth.ChannelElements {
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using DotNetOAuth.OAuth.Messages;
-
- /// <summary>
- /// An interface OAuth hosts must implement for persistent storage and recall of tokens and secrets.
- /// </summary>
- public interface ITokenManager {
- /// <summary>
- /// Gets the Consumer Secret given a Consumer Key.
- /// </summary>
- /// <param name="consumerKey">The Consumer Key.</param>
- /// <returns>The Consumer Secret.</returns>
- /// <exception cref="ArgumentException">Thrown if the consumer key cannot be found.</exception>
- /// <remarks>
- /// TODO: In the case of RSA hashing, the consumer may not have a secret
- /// like this. What to do in that case?
- /// </remarks>
- string GetConsumerSecret(string consumerKey);
-
- /// <summary>
- /// Gets the Token Secret given a request or access token.
- /// </summary>
- /// <param name="token">The request or access token.</param>
- /// <returns>The secret associated with the given token.</returns>
- /// <exception cref="ArgumentException">Thrown if the secret cannot be found for the given token.</exception>
- string GetTokenSecret(string token);
-
- /// <summary>
- /// Stores a newly generated unauthorized request token, secret, and optional
- /// application-specific parameters for later recall.
- /// </summary>
- /// <param name="request">The request message that resulted in the generation of a new unauthorized request token.</param>
- /// <param name="response">The response message that includes the unauthorized request token.</param>
- /// <exception cref="ArgumentException">Thrown if the consumer key is not registered, or a required parameter was not found in the parameters collection.</exception>
- void StoreNewRequestToken(UnauthorizedTokenRequest request, ITokenSecretContainingMessage response);
-
- /// <summary>
- /// Checks whether a given request token has already been authorized
- /// by some user for use by the Consumer that requested it.
- /// </summary>
- /// <param name="requestToken">The Consumer's request token.</param>
- /// <returns>
- /// True if the request token has already been fully authorized by the user
- /// who owns the relevant protected resources. False if the token has not yet
- /// been authorized, has expired or does not exist.
- /// </returns>
- bool IsRequestTokenAuthorized(string requestToken);
-
- /// <summary>
- /// Deletes a request token and its associated secret and stores a new access token and secret.
- /// </summary>
- /// <param name="consumerKey">The Consumer that is exchanging its request token for an access token.</param>
- /// <param name="requestToken">The Consumer's request token that should be deleted/expired.</param>
- /// <param name="accessToken">The new access token that is being issued to the Consumer.</param>
- /// <param name="accessTokenSecret">The secret associated with the newly issued access token.</param>
- /// <remarks>
- /// Any scope of granted privileges associated with the request token from the
- /// original call to <see cref="StoreNewRequestToken"/> should be carried over
- /// to the new Access Token.
- /// </remarks>
- void ExpireRequestTokenAndStoreNewAccessToken(string consumerKey, string requestToken, string accessToken, string accessTokenSecret);
-
- /// <summary>
- /// Classifies a token as a request token or an access token.
- /// </summary>
- /// <param name="token">The token to classify.</param>
- /// <returns>Request or Access token, or invalid if the token is not recognized.</returns>
- TokenType GetTokenType(string token);
- }
-}
diff --git a/src/DotNetOAuth/OAuth/ChannelElements/IWebRequestHandler.cs b/src/DotNetOAuth/OAuth/ChannelElements/IWebRequestHandler.cs
deleted file mode 100644
index d4a56f3..0000000
--- a/src/DotNetOAuth/OAuth/ChannelElements/IWebRequestHandler.cs
+++ /dev/null
@@ -1,31 +0,0 @@
-//-----------------------------------------------------------------------
-// <copyright file="IWebRequestHandler.cs" company="Andrew Arnott">
-// Copyright (c) Andrew Arnott. All rights reserved.
-// </copyright>
-//-----------------------------------------------------------------------
-
-namespace DotNetOAuth.OAuth.ChannelElements {
- using System.IO;
- using System.Net;
- using DotNetOAuth.Messaging;
-
- /// <summary>
- /// A contract for <see cref="HttpWebRequest"/> handling.
- /// </summary>
- internal interface IWebRequestHandler {
- /// <summary>
- /// Prepares an <see cref="HttpWebRequest"/> that contains an POST entity for sending the entity.
- /// </summary>
- /// <param name="request">The <see cref="HttpWebRequest"/> that should contain the entity.</param>
- /// <returns>The writer the caller should write out the entity data to.</returns>
- TextWriter GetRequestStream(HttpWebRequest request);
-
- /// <summary>
- /// Processes an <see cref="HttpWebRequest"/> and converts the
- /// <see cref="HttpWebResponse"/> to a <see cref="Response"/> instance.
- /// </summary>
- /// <param name="request">The <see cref="HttpWebRequest"/> to handle.</param>
- /// <returns>An instance of <see cref="Response"/> describing the response.</returns>
- Response GetResponse(HttpWebRequest request);
- }
-}
diff --git a/src/DotNetOAuth/OAuth/ChannelElements/OAuthChannel.cs b/src/DotNetOAuth/OAuth/ChannelElements/OAuthChannel.cs
deleted file mode 100644
index 4be38a0..0000000
--- a/src/DotNetOAuth/OAuth/ChannelElements/OAuthChannel.cs
+++ /dev/null
@@ -1,397 +0,0 @@
-//-----------------------------------------------------------------------
-// <copyright file="OAuthChannel.cs" company="Andrew Arnott">
-// Copyright (c) Andrew Arnott. All rights reserved.
-// </copyright>
-//-----------------------------------------------------------------------
-
-namespace DotNetOAuth.OAuth.ChannelElements {
- using System;
- using System.Collections.Generic;
- using System.Globalization;
- using System.IO;
- using System.Net;
- using System.Text;
- using System.Web;
- using DotNetOAuth.Messaging;
- using DotNetOAuth.Messaging.Bindings;
- using DotNetOAuth.Messaging.Reflection;
- using DotNetOAuth.OAuth.Messages;
-
- /// <summary>
- /// An OAuth-specific implementation of the <see cref="Channel"/> class.
- /// </summary>
- internal class OAuthChannel : Channel {
- /// <summary>
- /// The object that will transmit <see cref="HttpWebRequest"/> instances
- /// and return their responses.
- /// </summary>
- private IWebRequestHandler webRequestHandler;
-
- /// <summary>
- /// Initializes a new instance of the <see cref="OAuthChannel"/> class.
- /// </summary>
- /// <param name="signingBindingElement">The binding element to use for signing.</param>
- /// <param name="store">The web application store to use for nonces.</param>
- /// <param name="tokenManager">The token manager instance to use.</param>
- /// <param name="isConsumer">A value indicating whether this channel is being constructed for a Consumer (as opposed to a Service Provider).</param>
- internal OAuthChannel(ITamperProtectionChannelBindingElement signingBindingElement, INonceStore store, ITokenManager tokenManager, bool isConsumer)
- : this(
- signingBindingElement,
- store,
- tokenManager,
- isConsumer ? (IMessageTypeProvider)new OAuthConsumerMessageTypeProvider() : new OAuthServiceProviderMessageTypeProvider(tokenManager),
- new StandardWebRequestHandler()) {
- }
-
- /// <summary>
- /// Initializes a new instance of the <see cref="OAuthChannel"/> class.
- /// </summary>
- /// <param name="signingBindingElement">The binding element to use for signing.</param>
- /// <param name="store">The web application store to use for nonces.</param>
- /// <param name="tokenManager">The ITokenManager instance to use.</param>
- /// <param name="messageTypeProvider">
- /// An injected message type provider instance.
- /// Except for mock testing, this should always be one of
- /// <see cref="OAuthConsumerMessageTypeProvider"/> or <see cref="OAuthServiceProviderMessageTypeProvider"/>.
- /// </param>
- /// <param name="webRequestHandler">
- /// An instance to a <see cref="IWebRequestHandler"/> that will be used when submitting HTTP
- /// requests and waiting for responses.
- /// </param>
- /// <remarks>
- /// This overload for testing purposes only.
- /// </remarks>
- internal OAuthChannel(ITamperProtectionChannelBindingElement signingBindingElement, INonceStore store, ITokenManager tokenManager, IMessageTypeProvider messageTypeProvider, IWebRequestHandler webRequestHandler)
- : base(messageTypeProvider, new OAuthHttpMethodBindingElement(), signingBindingElement, new StandardExpirationBindingElement(), new StandardReplayProtectionBindingElement(store)) {
- if (tokenManager == null) {
- throw new ArgumentNullException("tokenManager");
- }
- if (webRequestHandler == null) {
- throw new ArgumentNullException("webRequestHandler");
- }
-
- this.webRequestHandler = webRequestHandler;
- this.TokenManager = tokenManager;
- if (signingBindingElement.SignatureCallback != null) {
- throw new ArgumentException(Strings.SigningElementAlreadyAssociatedWithChannel, "signingBindingElement");
- }
-
- signingBindingElement.SignatureCallback = this.SignatureCallback;
- }
-
- /// <summary>
- /// Gets or sets the Consumer web application path.
- /// </summary>
- internal Uri Realm { get; set; }
-
- /// <summary>
- /// Gets the token manager being used.
- /// </summary>
- protected internal ITokenManager TokenManager { get; private set; }
-
- /// <summary>
- /// Encodes the names and values that are part of the message per OAuth 1.0 section 5.1.
- /// </summary>
- /// <param name="message">The message with data to encode.</param>
- /// <returns>A dictionary of name-value pairs with their strings encoded.</returns>
- internal static IDictionary<string, string> GetEncodedParameters(IProtocolMessage message) {
- var encodedDictionary = new Dictionary<string, string>();
- EncodeParameters(new MessageDictionary(message), encodedDictionary);
- return encodedDictionary;
- }
-
- /// <summary>
- /// Encodes the names and values in a dictionary per OAuth 1.0 section 5.1.
- /// </summary>
- /// <param name="source">The dictionary with names and values to encode.</param>
- /// <param name="destination">The dictionary to add the encoded pairs to.</param>
- internal static void EncodeParameters(IDictionary<string, string> source, IDictionary<string, string> destination) {
- if (source == null) {
- throw new ArgumentNullException("source");
- }
- if (destination == null) {
- throw new ArgumentNullException("destination");
- }
-
- foreach (var pair in source) {
- var key = Uri.EscapeDataString(pair.Key);
- var value = Uri.EscapeDataString(pair.Value);
- destination.Add(key, value);
- }
- }
-
- /// <summary>
- /// Initializes a web request for sending by attaching a message to it.
- /// Use this method to prepare a protected resource request that you do NOT
- /// expect an OAuth message response to.
- /// </summary>
- /// <param name="request">The message to attach.</param>
- /// <returns>The initialized web request.</returns>
- internal HttpWebRequest InitializeRequest(IDirectedProtocolMessage request) {
- if (request == null) {
- throw new ArgumentNullException("request");
- }
-
- PrepareMessageForSending(request);
- return this.InitializeRequestInternal(request);
- }
-
- /// <summary>
- /// Searches an incoming HTTP request for data that could be used to assemble
- /// a protocol request message.
- /// </summary>
- /// <param name="request">The HTTP request to search.</param>
- /// <returns>A dictionary of data in the request. Should never be null, but may be empty.</returns>
- protected override IProtocolMessage ReadFromRequestInternal(HttpRequestInfo request) {
- if (request == null) {
- throw new ArgumentNullException("request");
- }
-
- // First search the Authorization header. Use it exclusively if it's present.
- string authorization = request.Headers[HttpRequestHeader.Authorization];
- if (authorization != null) {
- string[] authorizationSections = authorization.Split(';'); // TODO: is this the right delimiter?
- string oauthPrefix = Protocol.Default.AuthorizationHeaderScheme + " ";
-
- // The Authorization header may have multiple uses, and OAuth may be just one of them.
- // Go through each one looking for an OAuth one.
- foreach (string auth in authorizationSections) {
- string trimmedAuth = auth.Trim();
- if (trimmedAuth.StartsWith(oauthPrefix, StringComparison.Ordinal)) {
- // We found an Authorization: OAuth header.
- // Parse it according to the rules in section 5.4.1 of the V1.0 spec.
- var fields = new Dictionary<string, string>();
- foreach (string stringPair in trimmedAuth.Substring(oauthPrefix.Length).Split(',')) {
- string[] keyValueStringPair = stringPair.Trim().Split('=');
- string key = Uri.UnescapeDataString(keyValueStringPair[0]);
- string value = Uri.UnescapeDataString(keyValueStringPair[1].Trim('"'));
- fields.Add(key, value);
- }
-
- return this.Receive(fields, request.GetRecipient());
- }
- }
- }
-
- // We didn't find an OAuth authorization header. Revert to other payload methods.
- IProtocolMessage message = base.ReadFromRequestInternal(request);
-
- // Add receiving HTTP transport information required for signature generation.
- var signedMessage = message as ITamperResistantOAuthMessage;
- if (signedMessage != null) {
- signedMessage.Recipient = request.Url;
- signedMessage.HttpMethod = request.HttpMethod;
- }
-
- return message;
- }
-
- /// <summary>
- /// Gets the protocol message that may be in the given HTTP response stream.
- /// </summary>
- /// <param name="responseStream">The response that is anticipated to contain an OAuth message.</param>
- /// <returns>The deserialized message, if one is found. Null otherwise.</returns>
- protected override IProtocolMessage ReadFromResponseInternal(Stream responseStream) {
- if (responseStream == null) {
- throw new ArgumentNullException("responseStream");
- }
-
- using (StreamReader reader = new StreamReader(responseStream)) {
- string response = reader.ReadToEnd();
- var fields = HttpUtility.ParseQueryString(response).ToDictionary();
- return Receive(fields, null);
- }
- }
-
- /// <summary>
- /// Sends a direct message to a remote party and waits for the response.
- /// </summary>
- /// <param name="request">The message to send.</param>
- /// <returns>The remote party's response.</returns>
- protected override IProtocolMessage RequestInternal(IDirectedProtocolMessage request) {
- HttpWebRequest httpRequest = this.InitializeRequestInternal(request);
-
- Response response = this.webRequestHandler.GetResponse(httpRequest);
- if (response.ResponseStream == null) {
- return null;
- }
- var responseFields = HttpUtility.ParseQueryString(response.Body).ToDictionary();
- Type messageType = this.MessageTypeProvider.GetResponseMessageType(request, responseFields);
- if (messageType == null) {
- return null;
- }
- var responseSerialize = MessageSerializer.Get(messageType);
- var responseMessage = responseSerialize.Deserialize(responseFields, null);
-
- return responseMessage;
- }
-
- /// <summary>
- /// Queues a message for sending in the response stream where the fields
- /// are sent in the response stream in querystring style.
- /// </summary>
- /// <param name="response">The message to send as a response.</param>
- /// <returns>The pending user agent redirect based message to be sent as an HttpResponse.</returns>
- /// <remarks>
- /// This method implements spec V1.0 section 5.3.
- /// </remarks>
- protected override Response SendDirectMessageResponse(IProtocolMessage response) {
- if (response == null) {
- throw new ArgumentNullException("response");
- }
-
- MessageSerializer serializer = MessageSerializer.Get(response.GetType());
- var fields = serializer.Serialize(response);
- string responseBody = MessagingUtilities.CreateQueryString(fields);
-
- Response encodedResponse = new Response {
- Body = responseBody,
- OriginalMessage = response,
- Status = HttpStatusCode.OK,
- Headers = new System.Net.WebHeaderCollection(),
- };
- return encodedResponse;
- }
-
- /// <summary>
- /// Prepares to send a request to the Service Provider as the query string in a GET request.
- /// </summary>
- /// <param name="requestMessage">The message to be transmitted to the ServiceProvider.</param>
- /// <returns>The web request ready to send.</returns>
- /// <remarks>
- /// This method implements OAuth 1.0 section 5.2, item #3.
- /// </remarks>
- private static HttpWebRequest InitializeRequestAsGet(IDirectedProtocolMessage requestMessage) {
- var serializer = MessageSerializer.Get(requestMessage.GetType());
- var fields = serializer.Serialize(requestMessage);
-
- UriBuilder builder = new UriBuilder(requestMessage.Recipient);
- MessagingUtilities.AppendQueryArgs(builder, fields);
- HttpWebRequest httpRequest = (HttpWebRequest)WebRequest.Create(builder.Uri);
-
- return httpRequest;
- }
-
- /// <summary>
- /// Initializes a web request by attaching a message to it.
- /// </summary>
- /// <param name="request">The message to attach.</param>
- /// <returns>The initialized web request.</returns>
- private HttpWebRequest InitializeRequestInternal(IDirectedProtocolMessage request) {
- if (request == null) {
- throw new ArgumentNullException("request");
- }
- if (request.Recipient == null) {
- throw new ArgumentException(MessagingStrings.DirectedMessageMissingRecipient, "request");
- }
- IOAuthDirectedMessage oauthRequest = request as IOAuthDirectedMessage;
- if (oauthRequest == null) {
- throw new ArgumentException(
- string.Format(
- CultureInfo.CurrentCulture,
- MessagingStrings.UnexpectedType,
- typeof(IOAuthDirectedMessage),
- request.GetType()));
- }
-
- HttpWebRequest httpRequest;
-
- HttpDeliveryMethods transmissionMethod = oauthRequest.HttpMethods;
- if ((transmissionMethod & HttpDeliveryMethods.AuthorizationHeaderRequest) != 0) {
- httpRequest = this.InitializeRequestAsAuthHeader(request);
- } else if ((transmissionMethod & HttpDeliveryMethods.PostRequest) != 0) {
- httpRequest = this.InitializeRequestAsPost(request);
- } else if ((transmissionMethod & HttpDeliveryMethods.GetRequest) != 0) {
- httpRequest = InitializeRequestAsGet(request);
- } else {
- throw new NotSupportedException();
- }
- return httpRequest;
- }
-
- /// <summary>
- /// Prepares to send a request to the Service Provider via the Authorization header.
- /// </summary>
- /// <param name="requestMessage">The message to be transmitted to the ServiceProvider.</param>
- /// <returns>The web request ready to send.</returns>
- /// <remarks>
- /// This method implements OAuth 1.0 section 5.2, item #1 (described in section 5.4).
- /// </remarks>
- private HttpWebRequest InitializeRequestAsAuthHeader(IDirectedProtocolMessage requestMessage) {
- var protocol = Protocol.Lookup(requestMessage.ProtocolVersion);
- var dictionary = new MessageDictionary(requestMessage);
-
- // copy so as to not modify original
- var fields = new Dictionary<string, string>();
- foreach (string key in dictionary.DeclaredKeys) {
- fields.Add(key, dictionary[key]);
- }
- if (this.Realm != null) {
- fields.Add("realm", this.Realm.AbsoluteUri);
- }
-
- UriBuilder builder = new UriBuilder(requestMessage.Recipient);
- MessagingUtilities.AppendQueryArgs(builder, requestMessage.ExtraData);
- HttpWebRequest httpRequest = (HttpWebRequest)WebRequest.Create(builder.Uri);
-
- StringBuilder authorization = new StringBuilder();
- authorization.Append(protocol.AuthorizationHeaderScheme);
- authorization.Append(" ");
- foreach (var pair in fields) {
- string key = Uri.EscapeDataString(pair.Key);
- string value = Uri.EscapeDataString(pair.Value);
- authorization.Append(key);
- authorization.Append("=\"");
- authorization.Append(value);
- authorization.Append("\",");
- }
- authorization.Length--; // remove trailing comma
-
- httpRequest.Headers.Add(HttpRequestHeader.Authorization, authorization.ToString());
-
- return httpRequest;
- }
-
- /// <summary>
- /// Prepares to send a request to the Service Provider as the payload of a POST request.
- /// </summary>
- /// <param name="requestMessage">The message to be transmitted to the ServiceProvider.</param>
- /// <returns>The web request ready to send.</returns>
- /// <remarks>
- /// This method implements OAuth 1.0 section 5.2, item #2.
- /// </remarks>
- private HttpWebRequest InitializeRequestAsPost(IDirectedProtocolMessage requestMessage) {
- var serializer = MessageSerializer.Get(requestMessage.GetType());
- var fields = serializer.Serialize(requestMessage);
-
- HttpWebRequest httpRequest = (HttpWebRequest)WebRequest.Create(requestMessage.Recipient);
- httpRequest.Method = "POST";
- httpRequest.ContentType = "application/x-www-form-urlencoded";
- string requestBody = MessagingUtilities.CreateQueryString(fields);
- httpRequest.ContentLength = requestBody.Length;
- using (TextWriter writer = this.webRequestHandler.GetRequestStream(httpRequest)) {
- writer.Write(requestBody);
- }
-
- return httpRequest;
- }
-
- /// <summary>
- /// Fills out the secrets in a message so that signing/verification can be performed.
- /// </summary>
- /// <param name="message">The message about to be signed or whose signature is about to be verified.</param>
- private void SignatureCallback(ITamperResistantOAuthMessage message) {
- try {
- Logger.Debug("Applying secrets to message to prepare for signing or signature verification.");
- message.ConsumerSecret = this.TokenManager.GetConsumerSecret(message.ConsumerKey);
-
- var tokenMessage = message as ITokenContainingMessage;
- if (tokenMessage != null) {
- message.TokenSecret = this.TokenManager.GetTokenSecret(tokenMessage.Token);
- }
- } catch (KeyNotFoundException ex) {
- throw new ProtocolException(Strings.ConsumerOrTokenSecretNotFound, ex);
- }
- }
- }
-}
diff --git a/src/DotNetOAuth/OAuth/ChannelElements/OAuthConsumerMessageTypeProvider.cs b/src/DotNetOAuth/OAuth/ChannelElements/OAuthConsumerMessageTypeProvider.cs
deleted file mode 100644
index 123d657..0000000
--- a/src/DotNetOAuth/OAuth/ChannelElements/OAuthConsumerMessageTypeProvider.cs
+++ /dev/null
@@ -1,97 +0,0 @@
-//-----------------------------------------------------------------------
-// <copyright file="OAuthConsumerMessageTypeProvider.cs" company="Andrew Arnott">
-// Copyright (c) Andrew Arnott. All rights reserved.
-// </copyright>
-//-----------------------------------------------------------------------
-
-namespace DotNetOAuth.OAuth.ChannelElements {
- using System;
- using System.Collections.Generic;
- using DotNetOAuth.Messaging;
- using DotNetOAuth.OAuth.Messages;
-
- /// <summary>
- /// An OAuth-protocol specific implementation of the <see cref="IMessageTypeProvider"/>
- /// interface.
- /// </summary>
- public class OAuthConsumerMessageTypeProvider : IMessageTypeProvider {
- /// <summary>
- /// Initializes a new instance of the <see cref="OAuthConsumerMessageTypeProvider"/> class.
- /// </summary>
- protected internal OAuthConsumerMessageTypeProvider() {
- }
-
- #region IMessageTypeProvider Members
-
- /// <summary>
- /// Analyzes an incoming request message payload to discover what kind of
- /// message is embedded in it and returns the type, or null if no match is found.
- /// </summary>
- /// <param name="fields">The name/value pairs that make up the message payload.</param>
- /// <remarks>
- /// The request messages are:
- /// UserAuthorizationResponse
- /// </remarks>
- /// <returns>
- /// The <see cref="IProtocolMessage"/>-derived concrete class that this message can
- /// deserialize to. Null if the request isn't recognized as a valid protocol message.
- /// </returns>
- public virtual Type GetRequestMessageType(IDictionary<string, string> fields) {
- if (fields == null) {
- throw new ArgumentNullException("fields");
- }
-
- if (fields.ContainsKey("oauth_token")) {
- return typeof(UserAuthorizationResponse);
- }
-
- return null;
- }
-
- /// <summary>
- /// Analyzes an incoming request message payload to discover what kind of
- /// message is embedded in it and returns the type, or null if no match is found.
- /// </summary>
- /// <param name="request">
- /// The message that was sent as a request that resulted in the response.
- /// Null on a Consumer site that is receiving an indirect message from the Service Provider.
- /// </param>
- /// <param name="fields">The name/value pairs that make up the message payload.</param>
- /// <returns>
- /// The <see cref="IProtocolMessage"/>-derived concrete class that this message can
- /// deserialize to. Null if the request isn't recognized as a valid protocol message.
- /// </returns>
- /// <remarks>
- /// The response messages are:
- /// UnauthorizedTokenResponse
- /// AuthorizedTokenResponse
- /// </remarks>
- public virtual Type GetResponseMessageType(IProtocolMessage request, IDictionary<string, string> fields) {
- if (fields == null) {
- throw new ArgumentNullException("fields");
- }
-
- // All response messages have the oauth_token field.
- if (!fields.ContainsKey("oauth_token")) {
- return null;
- }
-
- // All direct message responses should have the oauth_token_secret field.
- if (!fields.ContainsKey("oauth_token_secret")) {
- Logger.Error("An OAuth message was expected to contain an oauth_token_secret but didn't.");
- return null;
- }
-
- if (request is UnauthorizedTokenRequest) {
- return typeof(UnauthorizedTokenResponse);
- } else if (request is AuthorizedTokenRequest) {
- return typeof(AuthorizedTokenResponse);
- } else {
- Logger.ErrorFormat("Unexpected response message given the request type {0}", request.GetType().Name);
- throw new ProtocolException(Strings.InvalidIncomingMessage);
- }
- }
-
- #endregion
- }
-}
diff --git a/src/DotNetOAuth/OAuth/ChannelElements/OAuthHttpMethodBindingElement.cs b/src/DotNetOAuth/OAuth/ChannelElements/OAuthHttpMethodBindingElement.cs
deleted file mode 100644
index e026c02..0000000
--- a/src/DotNetOAuth/OAuth/ChannelElements/OAuthHttpMethodBindingElement.cs
+++ /dev/null
@@ -1,73 +0,0 @@
-//-----------------------------------------------------------------------
-// <copyright file="OAuthHttpMethodBindingElement.cs" company="Andrew Arnott">
-// Copyright (c) Andrew Arnott. All rights reserved.
-// </copyright>
-//-----------------------------------------------------------------------
-
-namespace DotNetOAuth.OAuth.ChannelElements {
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using DotNetOAuth.Messaging;
-
- /// <summary>
- /// Sets the HTTP Method property on a signed message before the signing module gets to it.
- /// </summary>
- internal class OAuthHttpMethodBindingElement : IChannelBindingElement {
- #region IChannelBindingElement Members
-
- /// <summary>
- /// Gets the protection offered (if any) by this binding element.
- /// </summary>
- public MessageProtections Protection {
- get { return MessageProtections.None; }
- }
-
- /// <summary>
- /// Prepares a message for sending based on the rules of this channel binding element.
- /// </summary>
- /// <param name="message">The message to prepare for sending.</param>
- /// <returns>
- /// True if the <paramref name="message"/> applied to this binding element
- /// and the operation was successful. False otherwise.
- /// </returns>
- public bool PrepareMessageForSending(IProtocolMessage message) {
- var oauthMessage = message as ITamperResistantOAuthMessage;
-
- if (oauthMessage != null) {
- HttpDeliveryMethods transmissionMethod = oauthMessage.HttpMethods;
- if ((transmissionMethod & HttpDeliveryMethods.PostRequest) != 0) {
- oauthMessage.HttpMethod = "POST";
- } else if ((transmissionMethod & HttpDeliveryMethods.GetRequest) != 0) {
- oauthMessage.HttpMethod = "GET";
- } else {
- return false;
- }
-
- return true;
- } else {
- return false;
- }
- }
-
- /// <summary>
- /// Performs any transformation on an incoming message that may be necessary and/or
- /// validates an incoming message based on the rules of this channel binding element.
- /// </summary>
- /// <param name="message">The incoming message to process.</param>
- /// <returns>
- /// True if the <paramref name="message"/> applied to this binding element
- /// and the operation was successful. False if the operation did not apply to this message.
- /// </returns>
- /// <exception cref="ProtocolException">
- /// Thrown when the binding element rules indicate that this message is invalid and should
- /// NOT be processed.
- /// </exception>
- public bool PrepareMessageForReceiving(IProtocolMessage message) {
- return false;
- }
-
- #endregion
- }
-}
diff --git a/src/DotNetOAuth/OAuth/ChannelElements/OAuthServiceProviderMessageTypeProvider.cs b/src/DotNetOAuth/OAuth/ChannelElements/OAuthServiceProviderMessageTypeProvider.cs
deleted file mode 100644
index 570cdc1..0000000
--- a/src/DotNetOAuth/OAuth/ChannelElements/OAuthServiceProviderMessageTypeProvider.cs
+++ /dev/null
@@ -1,106 +0,0 @@
-//-----------------------------------------------------------------------
-// <copyright file="OAuthServiceProviderMessageTypeProvider.cs" company="Andrew Arnott">
-// Copyright (c) Andrew Arnott. All rights reserved.
-// </copyright>
-//-----------------------------------------------------------------------
-
-namespace DotNetOAuth.OAuth.ChannelElements {
- using System;
- using System.Collections.Generic;
- using DotNetOAuth.Messaging;
- using DotNetOAuth.OAuth.Messages;
-
- /// <summary>
- /// An OAuth-protocol specific implementation of the <see cref="IMessageTypeProvider"/>
- /// interface.
- /// </summary>
- public class OAuthServiceProviderMessageTypeProvider : IMessageTypeProvider {
- /// <summary>
- /// The token manager to use for discerning between request and access tokens.
- /// </summary>
- private ITokenManager tokenManager;
-
- /// <summary>
- /// Initializes a new instance of the <see cref="OAuthServiceProviderMessageTypeProvider"/> class.
- /// </summary>
- /// <param name="tokenManager">The token manager instance to use.</param>
- protected internal OAuthServiceProviderMessageTypeProvider(ITokenManager tokenManager) {
- if (tokenManager == null) {
- throw new ArgumentNullException("tokenManager");
- }
-
- this.tokenManager = tokenManager;
- }
-
- #region IMessageTypeProvider Members
-
- /// <summary>
- /// Analyzes an incoming request message payload to discover what kind of
- /// message is embedded in it and returns the type, or null if no match is found.
- /// </summary>
- /// <param name="fields">The name/value pairs that make up the message payload.</param>
- /// <remarks>
- /// The request messages are:
- /// UnauthorizedTokenRequest
- /// AuthorizedTokenRequest
- /// UserAuthorizationRequest
- /// AccessProtectedResourceRequest
- /// </remarks>
- /// <returns>
- /// The <see cref="IProtocolMessage"/>-derived concrete class that this message can
- /// deserialize to. Null if the request isn't recognized as a valid protocol message.
- /// </returns>
- public virtual Type GetRequestMessageType(IDictionary<string, string> fields) {
- if (fields == null) {
- throw new ArgumentNullException("fields");
- }
-
- if (fields.ContainsKey("oauth_consumer_key") &&
- !fields.ContainsKey("oauth_token")) {
- return typeof(UnauthorizedTokenRequest);
- }
-
- if (fields.ContainsKey("oauth_consumer_key") &&
- fields.ContainsKey("oauth_token")) {
- // Discern between RequestAccessToken and AccessProtectedResources,
- // which have all the same parameters, by figuring out what type of token
- // is in the token parameter.
- bool tokenTypeIsAccessToken = this.tokenManager.GetTokenType(fields["oauth_token"]) == TokenType.AccessToken;
-
- return tokenTypeIsAccessToken ? typeof(AccessProtectedResourceRequest) :
- typeof(AuthorizedTokenRequest);
- }
-
- // fail over to the message with no required fields at all.
- return typeof(UserAuthorizationRequest);
- }
-
- /// <summary>
- /// Analyzes an incoming request message payload to discover what kind of
- /// message is embedded in it and returns the type, or null if no match is found.
- /// </summary>
- /// <param name="request">
- /// The message that was sent as a request that resulted in the response.
- /// Null on a Consumer site that is receiving an indirect message from the Service Provider.
- /// </param>
- /// <param name="fields">The name/value pairs that make up the message payload.</param>
- /// <returns>
- /// The <see cref="IProtocolMessage"/>-derived concrete class that this message can
- /// deserialize to. Null if the request isn't recognized as a valid protocol message.
- /// </returns>
- /// <remarks>
- /// The response messages are:
- /// None.
- /// </remarks>
- public virtual Type GetResponseMessageType(IProtocolMessage request, IDictionary<string, string> fields) {
- if (fields == null) {
- throw new ArgumentNullException("fields");
- }
-
- Logger.Error("Service Providers are not expected to ever receive responses.");
- return null;
- }
-
- #endregion
- }
-}
diff --git a/src/DotNetOAuth/OAuth/ChannelElements/PlaintextSigningBindingElement.cs b/src/DotNetOAuth/OAuth/ChannelElements/PlaintextSigningBindingElement.cs
deleted file mode 100644
index e7d44d2..0000000
--- a/src/DotNetOAuth/OAuth/ChannelElements/PlaintextSigningBindingElement.cs
+++ /dev/null
@@ -1,55 +0,0 @@
-//-----------------------------------------------------------------------
-// <copyright file="PlaintextSigningBindingElement.cs" company="Andrew Arnott">
-// Copyright (c) Andrew Arnott. All rights reserved.
-// </copyright>
-//-----------------------------------------------------------------------
-
-namespace DotNetOAuth.OAuth.ChannelElements {
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using DotNetOAuth.Messaging;
- using DotNetOAuth.Messaging.Bindings;
-
- /// <summary>
- /// A binding element that signs outgoing messages and verifies the signature on incoming messages.
- /// </summary>
- public class PlaintextSigningBindingElement : SigningBindingElementBase {
- /// <summary>
- /// Initializes a new instance of the <see cref="PlaintextSigningBindingElement"/> class.
- /// </summary>
- public PlaintextSigningBindingElement()
- : base("PLAINTEXT") {
- }
-
- /// <summary>
- /// Calculates a signature for a given message.
- /// </summary>
- /// <param name="message">The message to sign.</param>
- /// <returns>The signature for the message.</returns>
- /// <remarks>
- /// This method signs the message according to OAuth 1.0 section 9.4.1.
- /// </remarks>
- protected override string GetSignature(ITamperResistantOAuthMessage message) {
- return GetConsumerAndTokenSecretString(message);
- }
-
- /// <summary>
- /// Checks whether this binding element applies to this message.
- /// </summary>
- /// <param name="message">The message that needs to be signed.</param>
- /// <returns>True if this binding element can be used to sign the message. False otherwise.</returns>
- protected override bool IsMessageApplicable(ITamperResistantOAuthMessage message) {
- return string.Equals(message.Recipient.Scheme, "https", StringComparison.OrdinalIgnoreCase);
- }
-
- /// <summary>
- /// Clones this instance.
- /// </summary>
- /// <returns>A new instance of the binding element.</returns>
- protected override ITamperProtectionChannelBindingElement Clone() {
- return new PlaintextSigningBindingElement();
- }
- }
-}
diff --git a/src/DotNetOAuth/OAuth/ChannelElements/RsaSha1SigningBindingElement.cs b/src/DotNetOAuth/OAuth/ChannelElements/RsaSha1SigningBindingElement.cs
deleted file mode 100644
index 07a72f3..0000000
--- a/src/DotNetOAuth/OAuth/ChannelElements/RsaSha1SigningBindingElement.cs
+++ /dev/null
@@ -1,48 +0,0 @@
-//-----------------------------------------------------------------------
-// <copyright file="RsaSha1SigningBindingElement.cs" company="Andrew Arnott">
-// Copyright (c) Andrew Arnott. All rights reserved.
-// </copyright>
-//-----------------------------------------------------------------------
-
-namespace DotNetOAuth.OAuth.ChannelElements {
- using System;
- using System.Security.Cryptography;
- using System.Text;
- using DotNetOAuth.Messaging;
-
- /// <summary>
- /// A binding element that signs outgoing messages and verifies the signature on incoming messages.
- /// </summary>
- public class RsaSha1SigningBindingElement : SigningBindingElementBase {
- /// <summary>
- /// Initializes a new instance of the <see cref="RsaSha1SigningBindingElement"/> class.
- /// </summary>
- internal RsaSha1SigningBindingElement()
- : base("RSA-SHA1") {
- }
-
- /// <summary>
- /// Calculates a signature for a given message.
- /// </summary>
- /// <param name="message">The message to sign.</param>
- /// <returns>The signature for the message.</returns>
- /// <remarks>
- /// This method signs the message per OAuth 1.0 section 9.3.
- /// </remarks>
- protected override string GetSignature(ITamperResistantOAuthMessage message) {
- AsymmetricAlgorithm provider = new RSACryptoServiceProvider();
- AsymmetricSignatureFormatter hasher = new RSAPKCS1SignatureFormatter(provider);
- hasher.SetHashAlgorithm("SHA1");
- byte[] digest = hasher.CreateSignature(Encoding.ASCII.GetBytes(ConstructSignatureBaseString(message)));
- return Convert.ToBase64String(digest);
- }
-
- /// <summary>
- /// Clones this instance.
- /// </summary>
- /// <returns>A new instance of the binding element.</returns>
- protected override ITamperProtectionChannelBindingElement Clone() {
- return new RsaSha1SigningBindingElement();
- }
- }
-}
diff --git a/src/DotNetOAuth/OAuth/ChannelElements/SigningBindingElementBase.cs b/src/DotNetOAuth/OAuth/ChannelElements/SigningBindingElementBase.cs
deleted file mode 100644
index fb3ca45..0000000
--- a/src/DotNetOAuth/OAuth/ChannelElements/SigningBindingElementBase.cs
+++ /dev/null
@@ -1,242 +0,0 @@
-//-----------------------------------------------------------------------
-// <copyright file="SigningBindingElementBase.cs" company="Andrew Arnott">
-// Copyright (c) Andrew Arnott. All rights reserved.
-// </copyright>
-//-----------------------------------------------------------------------
-
-namespace DotNetOAuth.OAuth.ChannelElements {
- using System;
- using System.Collections.Generic;
- using System.Globalization;
- using System.Text;
- using DotNetOAuth.Messaging;
- using DotNetOAuth.Messaging.Bindings;
-
- /// <summary>
- /// A binding element that signs outgoing messages and verifies the signature on incoming messages.
- /// </summary>
- public abstract class SigningBindingElementBase : ITamperProtectionChannelBindingElement {
- /// <summary>
- /// The signature method this binding element uses.
- /// </summary>
- private string signatureMethod;
-
- /// <summary>
- /// Initializes a new instance of the <see cref="SigningBindingElementBase"/> class.
- /// </summary>
- /// <param name="signatureMethod">The OAuth signature method that the binding element uses.</param>
- internal SigningBindingElementBase(string signatureMethod) {
- this.signatureMethod = signatureMethod;
- }
-
- #region IChannelBindingElement Properties
-
- /// <summary>
- /// Gets the message protection provided by this binding element.
- /// </summary>
- public MessageProtections Protection {
- get { return MessageProtections.TamperProtection; }
- }
-
- #endregion
-
- #region ITamperProtectionChannelBindingElement members
-
- /// <summary>
- /// Gets or sets the delegate that will initialize the non-serialized properties necessary on a signed
- /// message so that its signature can be correctly calculated for verification.
- /// </summary>
- public Action<ITamperResistantOAuthMessage> SignatureCallback { get; set; }
-
- /// <summary>
- /// Creates a new object that is a copy of the current instance.
- /// </summary>
- /// <returns>
- /// A new object that is a copy of this instance.
- /// </returns>
- ITamperProtectionChannelBindingElement ITamperProtectionChannelBindingElement.Clone() {
- ITamperProtectionChannelBindingElement clone = this.Clone();
- clone.SignatureCallback = this.SignatureCallback;
- return clone;
- }
-
- #endregion
-
- #region IChannelBindingElement Methods
-
- /// <summary>
- /// Signs the outgoing message.
- /// </summary>
- /// <param name="message">The message to sign.</param>
- /// <returns>True if the message was signed. False otherwise.</returns>
- public bool PrepareMessageForSending(IProtocolMessage message) {
- var signedMessage = message as ITamperResistantOAuthMessage;
- if (signedMessage != null && this.IsMessageApplicable(signedMessage)) {
- if (this.SignatureCallback != null) {
- this.SignatureCallback(signedMessage);
- } else {
- Logger.Warn("Signing required, but callback delegate was not provided to provide additional data for signing.");
- }
-
- signedMessage.SignatureMethod = this.signatureMethod;
- Logger.DebugFormat("Signing {0} message using {1}.", message.GetType().Name, this.signatureMethod);
- signedMessage.Signature = this.GetSignature(signedMessage);
- return true;
- }
-
- return false;
- }
-
- /// <summary>
- /// Verifies the signature on an incoming message.
- /// </summary>
- /// <param name="message">The message whose signature should be verified.</param>
- /// <returns>True if the signature was verified. False if the message had no signature.</returns>
- /// <exception cref="InvalidSignatureException">Thrown if the signature is invalid.</exception>
- public bool PrepareMessageForReceiving(IProtocolMessage message) {
- var signedMessage = message as ITamperResistantOAuthMessage;
- if (signedMessage != null && this.IsMessageApplicable(signedMessage)) {
- Logger.DebugFormat("Verifying incoming {0} message signature of: {1}", message.GetType().Name, signedMessage.Signature);
-
- if (!string.Equals(signedMessage.SignatureMethod, this.signatureMethod, StringComparison.Ordinal)) {
- Logger.WarnFormat("Expected signature method '{0}' but received message with a signature method of '{1}'.", this.signatureMethod, signedMessage.SignatureMethod);
- return false;
- }
-
- if (this.SignatureCallback != null) {
- this.SignatureCallback(signedMessage);
- } else {
- Logger.Warn("Signature verification required, but callback delegate was not provided to provide additional data for signing.");
- }
-
- string signature = this.GetSignature(signedMessage);
- if (signedMessage.Signature != signature) {
- Logger.Error("Signature verification failed.");
- throw new InvalidSignatureException(message);
- }
-
- return true;
- }
-
- return false;
- }
-
- #endregion
-
- /// <summary>
- /// Constructs the OAuth Signature Base String and returns the result.
- /// </summary>
- /// <param name="message">The message to derive the signature base string from.</param>
- /// <returns>The signature base string.</returns>
- /// <remarks>
- /// This method implements OAuth 1.0 section 9.1.
- /// </remarks>
- protected static string ConstructSignatureBaseString(ITamperResistantOAuthMessage message) {
- if (String.IsNullOrEmpty(message.HttpMethod)) {
- throw new ArgumentException(
- string.Format(
- CultureInfo.CurrentCulture,
- MessagingStrings.ArgumentPropertyMissing,
- typeof(ITamperResistantOAuthMessage).Name,
- "HttpMethod"),
- "message");
- }
-
- List<string> signatureBaseStringElements = new List<string>(3);
-
- signatureBaseStringElements.Add(message.HttpMethod.ToUpperInvariant());
-
- UriBuilder endpoint = new UriBuilder(message.Recipient);
- endpoint.Query = null;
- endpoint.Fragment = null;
- signatureBaseStringElements.Add(endpoint.Uri.AbsoluteUri);
-
- var encodedDictionary = OAuthChannel.GetEncodedParameters(message);
- encodedDictionary.Remove("oauth_signature");
- var sortedKeyValueList = new List<KeyValuePair<string, string>>(encodedDictionary);
- sortedKeyValueList.Sort(SignatureBaseStringParameterComparer);
- StringBuilder paramBuilder = new StringBuilder();
- foreach (var pair in sortedKeyValueList) {
- if (paramBuilder.Length > 0) {
- paramBuilder.Append("&");
- }
-
- paramBuilder.Append(pair.Key);
- paramBuilder.Append('=');
- paramBuilder.Append(pair.Value);
- }
-
- signatureBaseStringElements.Add(paramBuilder.ToString());
-
- StringBuilder signatureBaseString = new StringBuilder();
- foreach (string element in signatureBaseStringElements) {
- if (signatureBaseString.Length > 0) {
- signatureBaseString.Append("&");
- }
-
- signatureBaseString.Append(Uri.EscapeDataString(element));
- }
-
- Logger.DebugFormat("Constructed signature base string: {0}", signatureBaseString);
- return signatureBaseString.ToString();
- }
-
- /// <summary>
- /// Gets the ConsumerSecret&amp;TokenSecret" string, allowing either property to be empty or null.
- /// </summary>
- /// <param name="message">The message to extract the secrets from.</param>
- /// <returns>The concatenated string.</returns>
- protected static string GetConsumerAndTokenSecretString(ITamperResistantOAuthMessage message) {
- StringBuilder builder = new StringBuilder();
- if (!string.IsNullOrEmpty(message.ConsumerSecret)) {
- builder.Append(Uri.EscapeDataString(message.ConsumerSecret));
- }
- builder.Append("&");
- if (!string.IsNullOrEmpty(message.TokenSecret)) {
- builder.Append(Uri.EscapeDataString(message.TokenSecret));
- }
- return builder.ToString();
- }
-
- /// <summary>
- /// Clones this instance.
- /// </summary>
- /// <returns>A new instance of the binding element.</returns>
- /// <remarks>
- /// Implementations of this method need not clone the SignatureVerificationCallback member, as the
- /// <see cref="SigningBindingElementBase"/> class does this.
- /// </remarks>
- protected abstract ITamperProtectionChannelBindingElement Clone();
-
- /// <summary>
- /// Calculates a signature for a given message.
- /// </summary>
- /// <param name="message">The message to sign.</param>
- /// <returns>The signature for the message.</returns>
- protected abstract string GetSignature(ITamperResistantOAuthMessage message);
-
- /// <summary>
- /// Checks whether this binding element applies to this message.
- /// </summary>
- /// <param name="message">The message that needs to be signed.</param>
- /// <returns>True if this binding element can be used to sign the message. False otherwise.</returns>
- protected virtual bool IsMessageApplicable(ITamperResistantOAuthMessage message) {
- return string.IsNullOrEmpty(message.SignatureMethod) || message.SignatureMethod == this.signatureMethod;
- }
-
- /// <summary>
- /// Sorts parameters according to OAuth signature base string rules.
- /// </summary>
- /// <param name="left">The first parameter to compare.</param>
- /// <param name="right">The second parameter to compare.</param>
- /// <returns>Negative, zero or positive.</returns>
- private static int SignatureBaseStringParameterComparer(KeyValuePair<string, string> left, KeyValuePair<string, string> right) {
- int result = string.CompareOrdinal(left.Key, right.Key);
- if (result != 0) {
- return result;
- }
-
- return string.CompareOrdinal(left.Value, right.Value);
- }
- }
-}
diff --git a/src/DotNetOAuth/OAuth/ChannelElements/SigningBindingElementChain.cs b/src/DotNetOAuth/OAuth/ChannelElements/SigningBindingElementChain.cs
deleted file mode 100644
index 88119f1..0000000
--- a/src/DotNetOAuth/OAuth/ChannelElements/SigningBindingElementChain.cs
+++ /dev/null
@@ -1,132 +0,0 @@
-//-----------------------------------------------------------------------
-// <copyright file="SigningBindingElementChain.cs" company="Andrew Arnott">
-// Copyright (c) Andrew Arnott. All rights reserved.
-// </copyright>
-//-----------------------------------------------------------------------
-
-namespace DotNetOAuth.OAuth.ChannelElements {
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using DotNetOAuth.Messaging;
-
- /// <summary>
- /// A tamper protection applying binding element that can use any of several given
- /// binding elements to apply the protection.
- /// </summary>
- internal class SigningBindingElementChain : ITamperProtectionChannelBindingElement {
- /// <summary>
- /// The various signing binding elements that may be applicable to a message in preferred use order.
- /// </summary>
- private ITamperProtectionChannelBindingElement[] signers;
-
- /// <summary>
- /// Initializes a new instance of the <see cref="SigningBindingElementChain"/> class.
- /// </summary>
- /// <param name="signers">
- /// The signing binding elements that may be used for some outgoing message,
- /// in preferred use order.
- /// </param>
- internal SigningBindingElementChain(ITamperProtectionChannelBindingElement[] signers) {
- if (signers == null) {
- throw new ArgumentNullException("signers");
- }
- if (signers.Length == 0) {
- throw new ArgumentException(MessagingStrings.SequenceContainsNoElements, "signers");
- }
- if (signers.Contains(null)) {
- throw new ArgumentException(MessagingStrings.SequenceContainsNullElement, "signers");
- }
- MessageProtections protection = signers[0].Protection;
- if (signers.Any(element => element.Protection != protection)) {
- throw new ArgumentException(Strings.SigningElementsMustShareSameProtection, "signers");
- }
-
- this.signers = signers;
- }
-
- #region ITamperProtectionChannelBindingElement Properties
-
- /// <summary>
- /// Gets or sets the delegate that will initialize the non-serialized properties necessary on a signed
- /// message so that its signature can be correctly calculated for verification.
- /// May be null for Consumers (who never have to verify signatures).
- /// </summary>
- public Action<ITamperResistantOAuthMessage> SignatureCallback {
- get {
- return this.signers[0].SignatureCallback;
- }
-
- set {
- foreach (ITamperProtectionChannelBindingElement signer in this.signers) {
- signer.SignatureCallback = value;
- }
- }
- }
-
- #endregion
-
- #region IChannelBindingElement Members
-
- /// <summary>
- /// Gets the protection offered (if any) by this binding element.
- /// </summary>
- public MessageProtections Protection {
- get { return this.signers[0].Protection; }
- }
-
- /// <summary>
- /// Prepares a message for sending based on the rules of this channel binding element.
- /// </summary>
- /// <param name="message">The message to prepare for sending.</param>
- /// <returns>
- /// True if the <paramref name="message"/> applied to this binding element
- /// and the operation was successful. False otherwise.
- /// </returns>
- public bool PrepareMessageForSending(IProtocolMessage message) {
- foreach (IChannelBindingElement signer in this.signers) {
- if (signer.PrepareMessageForSending(message)) {
- return true;
- }
- }
-
- return false;
- }
-
- /// <summary>
- /// Performs any transformation on an incoming message that may be necessary and/or
- /// validates an incoming message based on the rules of this channel binding element.
- /// </summary>
- /// <param name="message">The incoming message to process.</param>
- /// <returns>
- /// True if the <paramref name="message"/> applied to this binding element
- /// and the operation was successful. False if the operation did not apply to this message.
- /// </returns>
- public bool PrepareMessageForReceiving(IProtocolMessage message) {
- foreach (IChannelBindingElement signer in this.signers) {
- if (signer.PrepareMessageForReceiving(message)) {
- return true;
- }
- }
-
- return false;
- }
-
- #endregion
-
- #region ITamperProtectionChannelBindingElement Methods
-
- /// <summary>
- /// Creates a new object that is a copy of the current instance.
- /// </summary>
- /// <returns>
- /// A new object that is a copy of this instance.
- /// </returns>
- ITamperProtectionChannelBindingElement ITamperProtectionChannelBindingElement.Clone() {
- return new SigningBindingElementChain(this.signers.Select(el => (ITamperProtectionChannelBindingElement)el.Clone()).ToArray());
- }
-
- #endregion
- }
-}
diff --git a/src/DotNetOAuth/OAuth/ChannelElements/StandardTokenGenerator.cs b/src/DotNetOAuth/OAuth/ChannelElements/StandardTokenGenerator.cs
deleted file mode 100644
index a1bc36a..0000000
--- a/src/DotNetOAuth/OAuth/ChannelElements/StandardTokenGenerator.cs
+++ /dev/null
@@ -1,68 +0,0 @@
-//-----------------------------------------------------------------------
-// <copyright file="StandardTokenGenerator.cs" company="Andrew Arnott">
-// Copyright (c) Andrew Arnott. All rights reserved.
-// </copyright>
-//-----------------------------------------------------------------------
-
-namespace DotNetOAuth.OAuth.ChannelElements {
- using System;
- using System.Security.Cryptography;
-
- /// <summary>
- /// A cryptographically strong random string generator for tokens and secrets.
- /// </summary>
- internal class StandardTokenGenerator : ITokenGenerator {
- /// <summary>
- /// The cryptographically strong random string generator for tokens and secrets.
- /// </summary>
- private RandomNumberGenerator cryptoProvider = new RNGCryptoServiceProvider();
-
- #region ITokenGenerator Members
-
- /// <summary>
- /// Generates a new token to represent a not-yet-authorized request to access protected resources.
- /// </summary>
- /// <param name="consumerKey">The consumer that requested this token.</param>
- /// <returns>The newly generated token.</returns>
- /// <remarks>
- /// This method should not store the newly generated token in any persistent store.
- /// This will be done in <see cref="ITokenManager.StoreNewRequestToken"/>.
- /// </remarks>
- public string GenerateRequestToken(string consumerKey) {
- return this.GenerateCryptographicallyStrongString();
- }
-
- /// <summary>
- /// Generates a new token to represent an authorized request to access protected resources.
- /// </summary>
- /// <param name="consumerKey">The consumer that requested this token.</param>
- /// <returns>The newly generated token.</returns>
- /// <remarks>
- /// This method should not store the newly generated token in any persistent store.
- /// This will be done in <see cref="ITokenManager.ExpireRequestTokenAndStoreNewAccessToken"/>.
- /// </remarks>
- public string GenerateAccessToken(string consumerKey) {
- return this.GenerateCryptographicallyStrongString();
- }
-
- /// <summary>
- /// Returns a cryptographically strong random string for use as a token secret.
- /// </summary>
- /// <returns>The generated string.</returns>
- public string GenerateSecret() {
- return this.GenerateCryptographicallyStrongString();
- }
-
- #endregion
-
- /// <summary>
- /// Returns a new random string.
- /// </summary>
- /// <returns>The new random string.</returns>
- private string GenerateCryptographicallyStrongString() {
- byte[] buffer = new byte[20];
- this.cryptoProvider.GetBytes(buffer);
- return Convert.ToBase64String(buffer);
- }
- }
-}
diff --git a/src/DotNetOAuth/OAuth/ChannelElements/StandardWebRequestHandler.cs b/src/DotNetOAuth/OAuth/ChannelElements/StandardWebRequestHandler.cs
deleted file mode 100644
index 12fcd28..0000000
--- a/src/DotNetOAuth/OAuth/ChannelElements/StandardWebRequestHandler.cs
+++ /dev/null
@@ -1,70 +0,0 @@
-//-----------------------------------------------------------------------
-// <copyright file="StandardWebRequestHandler.cs" company="Andrew Arnott">
-// Copyright (c) Andrew Arnott. All rights reserved.
-// </copyright>
-//-----------------------------------------------------------------------
-
-namespace DotNetOAuth.OAuth.ChannelElements {
- using System;
- using System.IO;
- using System.Net;
- using DotNetOAuth.Messaging;
-
- /// <summary>
- /// The default handler for transmitting <see cref="HttpWebRequest"/> instances
- /// and returning the responses.
- /// </summary>
- internal class StandardWebRequestHandler : IWebRequestHandler {
- #region IWebRequestHandler Members
-
- /// <summary>
- /// Prepares a POST <see cref="HttpWebRequest"/> and returns the request stream
- /// for writing out the POST entity data.
- /// </summary>
- /// <param name="request">The <see cref="HttpWebRequest"/> that should contain the entity.</param>
- /// <returns>The stream the caller should write out the entity data to.</returns>
- public TextWriter GetRequestStream(HttpWebRequest request) {
- if (request == null) {
- throw new ArgumentNullException("request");
- }
-
- try {
- return new StreamWriter(request.GetRequestStream());
- } catch (WebException ex) {
- throw new ProtocolException(MessagingStrings.ErrorInRequestReplyMessage, ex);
- }
- }
-
- /// <summary>
- /// Processes an <see cref="HttpWebRequest"/> and converts the
- /// <see cref="HttpWebResponse"/> to a <see cref="Response"/> instance.
- /// </summary>
- /// <param name="request">The <see cref="HttpWebRequest"/> to handle.</param>
- /// <returns>An instance of <see cref="Response"/> describing the response.</returns>
- public Response GetResponse(HttpWebRequest request) {
- if (request == null) {
- throw new ArgumentNullException("request");
- }
-
- try {
- Logger.DebugFormat("HTTP {0} {1}", request.Method, request.RequestUri);
- using (HttpWebResponse response = (HttpWebResponse)request.GetResponse()) {
- return new Response(response);
- }
- } catch (WebException ex) {
- if (Logger.IsErrorEnabled) {
- if (ex.Response != null) {
- using (var reader = new StreamReader(ex.Response.GetResponseStream())) {
- Logger.ErrorFormat("WebException from {0}: {1}", ex.Response.ResponseUri, reader.ReadToEnd());
- }
- } else {
- Logger.ErrorFormat("WebException {1} from {0}, no response available.", request.RequestUri, ex.Status);
- }
- }
- throw new ProtocolException(MessagingStrings.ErrorInRequestReplyMessage, ex);
- }
- }
-
- #endregion
- }
-}
diff --git a/src/DotNetOAuth/OAuth/ChannelElements/TokenType.cs b/src/DotNetOAuth/OAuth/ChannelElements/TokenType.cs
deleted file mode 100644
index bebdca2..0000000
--- a/src/DotNetOAuth/OAuth/ChannelElements/TokenType.cs
+++ /dev/null
@@ -1,30 +0,0 @@
-//-----------------------------------------------------------------------
-// <copyright file="TokenType.cs" company="Andrew Arnott">
-// Copyright (c) Andrew Arnott. All rights reserved.
-// </copyright>
-//-----------------------------------------------------------------------
-
-namespace DotNetOAuth.OAuth.ChannelElements {
- /// <summary>
- /// The two types of tokens that exist in the OAuth protocol.
- /// </summary>
- public enum TokenType {
- /// <summary>
- /// A token that is freely issued to any known Consumer.
- /// It does not grant any authorization to access protected resources,
- /// but is used as a step in obtaining that access.
- /// </summary>
- RequestToken,
-
- /// <summary>
- /// A token only obtained after the owner of some protected resource(s)
- /// has approved a Consumer's access to said resource(s).
- /// </summary>
- AccessToken,
-
- /// <summary>
- /// An unrecognized, expired or invalid token.
- /// </summary>
- InvalidToken,
- }
-}