summaryrefslogtreecommitdiffstats
path: root/src/DotNetOpenAuth.OAuth/OAuth/ChannelElements
diff options
context:
space:
mode:
authorAndrew Arnott <andrewarnott@gmail.com>2011-07-31 23:14:49 -0600
committerAndrew Arnott <andrewarnott@gmail.com>2011-07-31 23:14:49 -0600
commit7d874b645d575ed4cf7f879e7919c277cd7bfae7 (patch)
tree5b95aa5f3b7345a894ab184b85a60349766ebe02 /src/DotNetOpenAuth.OAuth/OAuth/ChannelElements
parentcb2960f2af1c4148d8581c3543594355cccabe6f (diff)
downloadDotNetOpenAuth-7d874b645d575ed4cf7f879e7919c277cd7bfae7.zip
DotNetOpenAuth-7d874b645d575ed4cf7f879e7919c277cd7bfae7.tar.gz
DotNetOpenAuth-7d874b645d575ed4cf7f879e7919c277cd7bfae7.tar.bz2
Moved more OAuth code from the common library to the individual Consumer or SP ones.
Diffstat (limited to 'src/DotNetOpenAuth.OAuth/OAuth/ChannelElements')
-rw-r--r--src/DotNetOpenAuth.OAuth/OAuth/ChannelElements/IConsumerDescription.cs59
-rw-r--r--src/DotNetOpenAuth.OAuth/OAuth/ChannelElements/IServiceProviderAccessToken.cs48
-rw-r--r--src/DotNetOpenAuth.OAuth/OAuth/ChannelElements/IServiceProviderRequestToken.cs52
-rw-r--r--src/DotNetOpenAuth.OAuth/OAuth/ChannelElements/IServiceProviderTokenManager.cs251
-rw-r--r--src/DotNetOpenAuth.OAuth/OAuth/ChannelElements/OAuthChannel.cs74
-rw-r--r--src/DotNetOpenAuth.OAuth/OAuth/ChannelElements/OAuthConsumerMessageFactory.cs109
-rw-r--r--src/DotNetOpenAuth.OAuth/OAuth/ChannelElements/OAuthIdentity.cs64
-rw-r--r--src/DotNetOpenAuth.OAuth/OAuth/ChannelElements/OAuthPrincipal.cs91
-rw-r--r--src/DotNetOpenAuth.OAuth/OAuth/ChannelElements/OAuthServiceProviderMessageFactory.cs126
-rw-r--r--src/DotNetOpenAuth.OAuth/OAuth/ChannelElements/RsaSha1SigningBindingElement.cs92
-rw-r--r--src/DotNetOpenAuth.OAuth/OAuth/ChannelElements/TokenHandlingBindingElement.cs201
11 files changed, 11 insertions, 1156 deletions
diff --git a/src/DotNetOpenAuth.OAuth/OAuth/ChannelElements/IConsumerDescription.cs b/src/DotNetOpenAuth.OAuth/OAuth/ChannelElements/IConsumerDescription.cs
deleted file mode 100644
index db505d5..0000000
--- a/src/DotNetOpenAuth.OAuth/OAuth/ChannelElements/IConsumerDescription.cs
+++ /dev/null
@@ -1,59 +0,0 @@
-//-----------------------------------------------------------------------
-// <copyright file="IConsumerDescription.cs" company="Andrew Arnott">
-// Copyright (c) Andrew Arnott. All rights reserved.
-// </copyright>
-//-----------------------------------------------------------------------
-
-namespace DotNetOpenAuth.OAuth.ChannelElements {
- using System;
- using System.Security.Cryptography.X509Certificates;
-
- /// <summary>
- /// A description of a consumer from a Service Provider's point of view.
- /// </summary>
- public interface IConsumerDescription {
- /// <summary>
- /// Gets the Consumer key.
- /// </summary>
- string Key { get; }
-
- /// <summary>
- /// Gets the consumer secret.
- /// </summary>
- string Secret { get; }
-
- /// <summary>
- /// Gets the certificate that can be used to verify the signature of an incoming
- /// message from a Consumer.
- /// </summary>
- /// <returns>The public key from the Consumer's X.509 Certificate, if one can be found; otherwise <c>null</c>.</returns>
- /// <remarks>
- /// This property must be implemented only if the RSA-SHA1 algorithm is supported by the Service Provider.
- /// </remarks>
- X509Certificate2 Certificate { get; }
-
- /// <summary>
- /// Gets the callback URI that this consumer has pre-registered with the service provider, if any.
- /// </summary>
- /// <value>A URI that user authorization responses should be directed to; or <c>null</c> if no preregistered callback was arranged.</value>
- Uri Callback { get; }
-
- /// <summary>
- /// Gets the verification code format that is most appropriate for this consumer
- /// when a callback URI is not available.
- /// </summary>
- /// <value>A set of characters that can be easily keyed in by the user given the Consumer's
- /// application type and form factor.</value>
- /// <remarks>
- /// The value <see cref="OAuth.VerificationCodeFormat.IncludedInCallback"/> should NEVER be returned
- /// since this property is only used in no callback scenarios anyway.
- /// </remarks>
- VerificationCodeFormat VerificationCodeFormat { get; }
-
- /// <summary>
- /// Gets the length of the verification code to issue for this Consumer.
- /// </summary>
- /// <value>A positive number, generally at least 4.</value>
- int VerificationCodeLength { get; }
- }
-}
diff --git a/src/DotNetOpenAuth.OAuth/OAuth/ChannelElements/IServiceProviderAccessToken.cs b/src/DotNetOpenAuth.OAuth/OAuth/ChannelElements/IServiceProviderAccessToken.cs
deleted file mode 100644
index 35ba52d..0000000
--- a/src/DotNetOpenAuth.OAuth/OAuth/ChannelElements/IServiceProviderAccessToken.cs
+++ /dev/null
@@ -1,48 +0,0 @@
-//-----------------------------------------------------------------------
-// <copyright file="IServiceProviderAccessToken.cs" company="Andrew Arnott">
-// Copyright (c) Andrew Arnott. All rights reserved.
-// </copyright>
-//-----------------------------------------------------------------------
-
-namespace DotNetOpenAuth.OAuth.ChannelElements {
- using System;
- using System.Collections.Generic;
- using System.Diagnostics.CodeAnalysis;
- using System.Linq;
- using System.Text;
-
- /// <summary>
- /// A description of an access token and its metadata as required by a Service Provider.
- /// </summary>
- public interface IServiceProviderAccessToken {
- /// <summary>
- /// Gets the token itself.
- /// </summary>
- string Token { get; }
-
- /// <summary>
- /// Gets the expiration date (local time) for the access token.
- /// </summary>
- /// <value>The expiration date, or <c>null</c> if there is no expiration date.</value>
- DateTime? ExpirationDate { get; }
-
- /// <summary>
- /// Gets the username of the principal that will be impersonated by this access token.
- /// </summary>
- /// <value>
- /// The name of the user who authorized the OAuth request token originally.
- /// </value>
- [SuppressMessage("Microsoft.Naming", "CA1702:CompoundWordsShouldBeCasedCorrectly", MessageId = "Username", Justification = "Breaking change.")]
- string Username { get; }
-
- /// <summary>
- /// Gets the roles that the OAuth principal should belong to.
- /// </summary>
- /// <value>
- /// The roles that the user belongs to, or a subset of these according to the rights
- /// granted when the user authorized the request token.
- /// </value>
- [SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays", Justification = "By design.")]
- string[] Roles { get; }
- }
-}
diff --git a/src/DotNetOpenAuth.OAuth/OAuth/ChannelElements/IServiceProviderRequestToken.cs b/src/DotNetOpenAuth.OAuth/OAuth/ChannelElements/IServiceProviderRequestToken.cs
deleted file mode 100644
index 6dfa416..0000000
--- a/src/DotNetOpenAuth.OAuth/OAuth/ChannelElements/IServiceProviderRequestToken.cs
+++ /dev/null
@@ -1,52 +0,0 @@
-//-----------------------------------------------------------------------
-// <copyright file="IServiceProviderRequestToken.cs" company="Andrew Arnott">
-// Copyright (c) Andrew Arnott. All rights reserved.
-// </copyright>
-//-----------------------------------------------------------------------
-
-namespace DotNetOpenAuth.OAuth.ChannelElements {
- using System;
- using DotNetOpenAuth.OAuth.Messages;
-
- /// <summary>
- /// A description of a request token and its metadata as required by a Service Provider
- /// </summary>
- public interface IServiceProviderRequestToken {
- /// <summary>
- /// Gets the token itself.
- /// </summary>
- string Token { get; }
-
- /// <summary>
- /// Gets the consumer key that requested this token.
- /// </summary>
- string ConsumerKey { get; }
-
- /// <summary>
- /// Gets the (local) date that this request token was first created on.
- /// </summary>
- DateTime CreatedOn { get; }
-
- /// <summary>
- /// Gets or sets the callback associated specifically with this token, if any.
- /// </summary>
- /// <value>The callback URI; or <c>null</c> if no callback was specifically assigned to this token.</value>
- Uri Callback { get; set; }
-
- /// <summary>
- /// Gets or sets the verifier that the consumer must include in the <see cref="AuthorizedTokenRequest"/>
- /// message to exchange this request token for an access token.
- /// </summary>
- /// <value>The verifier code, or <c>null</c> if none has been assigned (yet).</value>
- string VerificationCode { get; set; }
-
- /// <summary>
- /// Gets or sets the version of the Consumer that requested this token.
- /// </summary>
- /// <remarks>
- /// This property is used to determine whether a <see cref="VerificationCode"/> must be
- /// generated when the user authorizes the Consumer or not.
- /// </remarks>
- Version ConsumerVersion { get; set; }
- }
-}
diff --git a/src/DotNetOpenAuth.OAuth/OAuth/ChannelElements/IServiceProviderTokenManager.cs b/src/DotNetOpenAuth.OAuth/OAuth/ChannelElements/IServiceProviderTokenManager.cs
deleted file mode 100644
index 7df67ce..0000000
--- a/src/DotNetOpenAuth.OAuth/OAuth/ChannelElements/IServiceProviderTokenManager.cs
+++ /dev/null
@@ -1,251 +0,0 @@
-//-----------------------------------------------------------------------
-// <copyright file="IServiceProviderTokenManager.cs" company="Andrew Arnott">
-// Copyright (c) Andrew Arnott. All rights reserved.
-// </copyright>
-//-----------------------------------------------------------------------
-
-namespace DotNetOpenAuth.OAuth.ChannelElements {
- using System;
- using System.Collections.Generic;
- using System.Diagnostics.Contracts;
- using System.Linq;
- using System.Text;
-
- /// <summary>
- /// A token manager for use by a web site in its role as a
- /// service provider.
- /// </summary>
- [ContractClass(typeof(IServiceProviderTokenManagerContract))]
- public interface IServiceProviderTokenManager : ITokenManager {
- /// <summary>
- /// Gets the Consumer description for a given a Consumer Key.
- /// </summary>
- /// <param name="consumerKey">The Consumer Key.</param>
- /// <returns>A description of the consumer. Never null.</returns>
- /// <exception cref="KeyNotFoundException">Thrown if the consumer key cannot be found.</exception>
- IConsumerDescription GetConsumer(string consumerKey);
-
- /// <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>
- /// Gets details on the named request token.
- /// </summary>
- /// <param name="token">The request token.</param>
- /// <returns>A description of the token. Never null.</returns>
- /// <exception cref="KeyNotFoundException">Thrown if the token cannot be found.</exception>
- /// <remarks>
- /// It is acceptable for implementations to find the token, see that it has expired,
- /// delete it from the database and then throw <see cref="KeyNotFoundException"/>,
- /// or alternatively it can return the expired token anyway and the OAuth channel will
- /// log and throw the appropriate error.
- /// </remarks>
- IServiceProviderRequestToken GetRequestToken(string token);
-
- /// <summary>
- /// Gets details on the named access token.
- /// </summary>
- /// <param name="token">The access token.</param>
- /// <returns>A description of the token. Never null.</returns>
- /// <exception cref="KeyNotFoundException">Thrown if the token cannot be found.</exception>
- /// <remarks>
- /// It is acceptable for implementations to find the token, see that it has expired,
- /// delete it from the database and then throw <see cref="KeyNotFoundException"/>,
- /// or alternatively it can return the expired token anyway and the OAuth channel will
- /// log and throw the appropriate error.
- /// </remarks>
- IServiceProviderAccessToken GetAccessToken(string token);
-
- /// <summary>
- /// Persists any changes made to the token.
- /// </summary>
- /// <param name="token">The token whose properties have been changed.</param>
- /// <remarks>
- /// This library will invoke this method after making a set
- /// of changes to the token as part of a web request to give the host
- /// the opportunity to persist those changes to a database.
- /// Depending on the object persistence framework the host site uses,
- /// this method MAY not need to do anything (if changes made to the token
- /// will automatically be saved without any extra handling).
- /// </remarks>
- void UpdateToken(IServiceProviderRequestToken token);
- }
-
- /// <summary>
- /// Code contract class for the <see cref="IServiceProviderTokenManager"/> interface.
- /// </summary>
- [ContractClassFor(typeof(IServiceProviderTokenManager))]
- internal abstract class IServiceProviderTokenManagerContract : IServiceProviderTokenManager {
- /// <summary>
- /// Prevents a default instance of the <see cref="IServiceProviderTokenManagerContract"/> class from being created.
- /// </summary>
- private IServiceProviderTokenManagerContract() {
- }
-
- #region IServiceProviderTokenManager Members
-
- /// <summary>
- /// Gets the Consumer description for a given a Consumer Key.
- /// </summary>
- /// <param name="consumerKey">The Consumer Key.</param>
- /// <returns>
- /// A description of the consumer. Never null.
- /// </returns>
- /// <exception cref="KeyNotFoundException">Thrown if the consumer key cannot be found.</exception>
- IConsumerDescription IServiceProviderTokenManager.GetConsumer(string consumerKey) {
- Contract.Requires<ArgumentException>(!String.IsNullOrEmpty(consumerKey));
- Contract.Ensures(Contract.Result<IConsumerDescription>() != null);
- throw new NotImplementedException();
- }
-
- /// <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 IServiceProviderTokenManager.IsRequestTokenAuthorized(string requestToken) {
- Contract.Requires<ArgumentException>(!String.IsNullOrEmpty(requestToken));
- throw new NotImplementedException();
- }
-
- /// <summary>
- /// Gets details on the named request token.
- /// </summary>
- /// <param name="token">The request token.</param>
- /// <returns>A description of the token. Never null.</returns>
- /// <exception cref="KeyNotFoundException">Thrown if the token cannot be found.</exception>
- /// <remarks>
- /// It is acceptable for implementations to find the token, see that it has expired,
- /// delete it from the database and then throw <see cref="KeyNotFoundException"/>,
- /// or alternatively it can return the expired token anyway and the OAuth channel will
- /// log and throw the appropriate error.
- /// </remarks>
- IServiceProviderRequestToken IServiceProviderTokenManager.GetRequestToken(string token) {
- Contract.Requires<ArgumentException>(!String.IsNullOrEmpty(token));
- Contract.Ensures(Contract.Result<IServiceProviderRequestToken>() != null);
- throw new NotImplementedException();
- }
-
- /// <summary>
- /// Gets details on the named access token.
- /// </summary>
- /// <param name="token">The access token.</param>
- /// <returns>A description of the token. Never null.</returns>
- /// <exception cref="KeyNotFoundException">Thrown if the token cannot be found.</exception>
- /// <remarks>
- /// It is acceptable for implementations to find the token, see that it has expired,
- /// delete it from the database and then throw <see cref="KeyNotFoundException"/>,
- /// or alternatively it can return the expired token anyway and the OAuth channel will
- /// log and throw the appropriate error.
- /// </remarks>
- IServiceProviderAccessToken IServiceProviderTokenManager.GetAccessToken(string token) {
- Contract.Requires<ArgumentException>(!String.IsNullOrEmpty(token));
- Contract.Ensures(Contract.Result<IServiceProviderAccessToken>() != null);
- throw new NotImplementedException();
- }
-
- /// <summary>
- /// Persists any changes made to the token.
- /// </summary>
- /// <param name="token">The token whose properties have been changed.</param>
- /// <remarks>
- /// This library will invoke this method after making a set
- /// of changes to the token as part of a web request to give the host
- /// the opportunity to persist those changes to a database.
- /// Depending on the object persistence framework the host site uses,
- /// this method MAY not need to do anything (if changes made to the token
- /// will automatically be saved without any extra handling).
- /// </remarks>
- void IServiceProviderTokenManager.UpdateToken(IServiceProviderRequestToken token) {
- Contract.Requires<ArgumentNullException>(token != null);
- throw new NotImplementedException();
- }
-
- #endregion
-
- #region ITokenManager Members
-
- /// <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 ITokenManager.GetTokenSecret(string token) {
- throw new NotImplementedException();
- }
-
- /// <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>
- /// <remarks>
- /// Request tokens stored by this method SHOULD NOT associate any user account with this token.
- /// It usually opens up security holes in your application to do so. Instead, you associate a user
- /// account with access tokens (not request tokens) in the <see cref="ITokenManager.ExpireRequestTokenAndStoreNewAccessToken"/>
- /// method.
- /// </remarks>
- void ITokenManager.StoreNewRequestToken(DotNetOpenAuth.OAuth.Messages.UnauthorizedTokenRequest request, DotNetOpenAuth.OAuth.Messages.ITokenSecretContainingMessage response) {
- throw new NotImplementedException();
- }
-
- /// <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>
- /// <para>
- /// Any scope of granted privileges associated with the request token from the
- /// original call to <see cref="ITokenManager.StoreNewRequestToken"/> should be carried over
- /// to the new Access Token.
- /// </para>
- /// <para>
- /// To associate a user account with the new access token,
- /// <see cref="System.Web.HttpContext.User">HttpContext.Current.User</see> may be
- /// useful in an ASP.NET web application within the implementation of this method.
- /// Alternatively you may store the access token here without associating with a user account,
- /// and wait until <see cref="WebConsumer.ProcessUserAuthorization()"/> or
- /// <see cref="DesktopConsumer.ProcessUserAuthorization(string, string)"/> return the access
- /// token to associate the access token with a user account at that point.
- /// </para>
- /// </remarks>
- void ITokenManager.ExpireRequestTokenAndStoreNewAccessToken(string consumerKey, string requestToken, string accessToken, string accessTokenSecret) {
- throw new NotImplementedException();
- }
-
- /// <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 ITokenManager.GetTokenType(string token) {
- throw new NotImplementedException();
- }
-
- #endregion
- }
-}
diff --git a/src/DotNetOpenAuth.OAuth/OAuth/ChannelElements/OAuthChannel.cs b/src/DotNetOpenAuth.OAuth/OAuth/ChannelElements/OAuthChannel.cs
index 76b5149..b6ad28d 100644
--- a/src/DotNetOpenAuth.OAuth/OAuth/ChannelElements/OAuthChannel.cs
+++ b/src/DotNetOpenAuth.OAuth/OAuth/ChannelElements/OAuthChannel.cs
@@ -25,49 +25,7 @@ namespace DotNetOpenAuth.OAuth.ChannelElements {
/// <summary>
/// An OAuth-specific implementation of the <see cref="Channel"/> class.
/// </summary>
- internal class OAuthChannel : Channel {
- /// <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="securitySettings">The security settings.</param>
- [SuppressMessage("Microsoft.Globalization", "CA1303:Do not pass literals as localized parameters", MessageId = "System.Diagnostics.Contracts.__ContractsRuntime.Requires<System.ArgumentNullException>(System.Boolean,System.String,System.String)", Justification = "Code contracts"), SuppressMessage("Microsoft.Naming", "CA2204:Literals should be spelled correctly", MessageId = "securitySettings", Justification = "Code contracts")]
- internal OAuthChannel(ITamperProtectionChannelBindingElement signingBindingElement, INonceStore store, IConsumerTokenManager tokenManager, ConsumerSecuritySettings securitySettings)
- : this(
- signingBindingElement,
- store,
- tokenManager,
- securitySettings,
- new OAuthConsumerMessageFactory()) {
- Contract.Requires<ArgumentNullException>(tokenManager != null);
- Contract.Requires<ArgumentNullException>(securitySettings != null);
- Contract.Requires<ArgumentNullException>(signingBindingElement != null);
- Contract.Requires<ArgumentException>(signingBindingElement.SignatureCallback == null, OAuthStrings.SigningElementAlreadyAssociatedWithChannel);
- }
-
- /// <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="securitySettings">The security settings.</param>
- [SuppressMessage("Microsoft.Globalization", "CA1303:Do not pass literals as localized parameters", MessageId = "System.Diagnostics.Contracts.__ContractsRuntime.Requires<System.ArgumentNullException>(System.Boolean,System.String,System.String)", Justification = "Code contracts"), SuppressMessage("Microsoft.Naming", "CA2204:Literals should be spelled correctly", MessageId = "securitySettings", Justification = "Code contracts")]
- internal OAuthChannel(ITamperProtectionChannelBindingElement signingBindingElement, INonceStore store, IServiceProviderTokenManager tokenManager, ServiceProviderSecuritySettings securitySettings)
- : this(
- signingBindingElement,
- store,
- tokenManager,
- securitySettings,
- new OAuthServiceProviderMessageFactory(tokenManager)) {
- Contract.Requires<ArgumentNullException>(tokenManager != null);
- Contract.Requires<ArgumentNullException>(securitySettings != null);
- Contract.Requires<ArgumentNullException>(signingBindingElement != null);
- Contract.Requires<ArgumentException>(signingBindingElement.SignatureCallback == null, OAuthStrings.SigningElementAlreadyAssociatedWithChannel);
- }
-
+ internal abstract class OAuthChannel : Channel {
/// <summary>
/// Initializes a new instance of the <see cref="OAuthChannel"/> class.
/// </summary>
@@ -79,12 +37,13 @@ namespace DotNetOpenAuth.OAuth.ChannelElements {
/// Except for mock testing, this should always be one of
/// <see cref="OAuthConsumerMessageFactory"/> or <see cref="OAuthServiceProviderMessageFactory"/>.</param>
[SuppressMessage("Microsoft.Globalization", "CA1303:Do not pass literals as localized parameters", MessageId = "System.Diagnostics.Contracts.__ContractsRuntime.Requires<System.ArgumentNullException>(System.Boolean,System.String,System.String)", Justification = "Code contracts"), SuppressMessage("Microsoft.Naming", "CA2204:Literals should be spelled correctly", MessageId = "securitySettings", Justification = "Code contracts")]
- internal OAuthChannel(ITamperProtectionChannelBindingElement signingBindingElement, INonceStore store, ITokenManager tokenManager, SecuritySettings securitySettings, IMessageFactory messageTypeProvider)
- : base(messageTypeProvider, InitializeBindingElements(signingBindingElement, store, tokenManager, securitySettings)) {
+ protected OAuthChannel(ITamperProtectionChannelBindingElement signingBindingElement, INonceStore store, ITokenManager tokenManager, SecuritySettings securitySettings, IMessageFactory messageTypeProvider, IChannelBindingElement[] bindingElements)
+ : base(messageTypeProvider, bindingElements) {
Contract.Requires<ArgumentNullException>(tokenManager != null);
Contract.Requires<ArgumentNullException>(securitySettings != null);
Contract.Requires<ArgumentNullException>(signingBindingElement != null);
Contract.Requires<ArgumentException>(signingBindingElement.SignatureCallback == null, OAuthStrings.SigningElementAlreadyAssociatedWithChannel);
+ Contract.Requires<ArgumentNullException>(bindingElements != null, "bindingElements");
this.TokenManager = tokenManager;
signingBindingElement.SignatureCallback = this.SignatureCallback;
@@ -263,7 +222,7 @@ namespace DotNetOpenAuth.OAuth.ChannelElements {
/// <returns>
/// An array of binding elements used to initialize the channel.
/// </returns>
- private static IChannelBindingElement[] InitializeBindingElements(ITamperProtectionChannelBindingElement signingBindingElement, INonceStore store, ITokenManager tokenManager, SecuritySettings securitySettings) {
+ protected static List<IChannelBindingElement> InitializeBindingElements(ITamperProtectionChannelBindingElement signingBindingElement, INonceStore store, ITokenManager tokenManager, SecuritySettings securitySettings) {
Contract.Requires(securitySettings != null);
var bindingElements = new List<IChannelBindingElement> {
@@ -273,13 +232,7 @@ namespace DotNetOpenAuth.OAuth.ChannelElements {
new StandardReplayProtectionBindingElement(store),
};
- var spTokenManager = tokenManager as IServiceProviderTokenManager;
- var serviceProviderSecuritySettings = securitySettings as ServiceProviderSecuritySettings;
- if (spTokenManager != null && serviceProviderSecuritySettings != null) {
- bindingElements.Insert(0, new TokenHandlingBindingElement(spTokenManager, serviceProviderSecuritySettings));
- }
-
- return bindingElements.ToArray();
+ return bindingElements;
}
/// <summary>
@@ -392,19 +345,6 @@ namespace DotNetOpenAuth.OAuth.ChannelElements {
}
}
- /// <summary>
- /// Gets the consumer secret for a given consumer key.
- /// </summary>
- /// <param name="consumerKey">The consumer key.</param>
- /// <returns>The consumer secret.</returns>
- private string GetConsumerSecret(string consumerKey) {
- var consumerTokenManager = this.TokenManager as IConsumerTokenManager;
- if (consumerTokenManager != null) {
- ErrorUtilities.VerifyInternal(consumerKey == consumerTokenManager.ConsumerKey, "The token manager consumer key and the consumer key set earlier do not match!");
- return consumerTokenManager.ConsumerSecret;
- } else {
- return ((IServiceProviderTokenManager)this.TokenManager).GetConsumer(consumerKey).Secret;
- }
- }
+ protected abstract string GetConsumerSecret(string consumerKey);
}
}
diff --git a/src/DotNetOpenAuth.OAuth/OAuth/ChannelElements/OAuthConsumerMessageFactory.cs b/src/DotNetOpenAuth.OAuth/OAuth/ChannelElements/OAuthConsumerMessageFactory.cs
deleted file mode 100644
index 327b923..0000000
--- a/src/DotNetOpenAuth.OAuth/OAuth/ChannelElements/OAuthConsumerMessageFactory.cs
+++ /dev/null
@@ -1,109 +0,0 @@
-//-----------------------------------------------------------------------
-// <copyright file="OAuthConsumerMessageFactory.cs" company="Andrew Arnott">
-// Copyright (c) Andrew Arnott. All rights reserved.
-// </copyright>
-//-----------------------------------------------------------------------
-
-namespace DotNetOpenAuth.OAuth.ChannelElements {
- using System;
- using System.Collections.Generic;
- using System.Diagnostics.Contracts;
- using DotNetOpenAuth.Messaging;
- using DotNetOpenAuth.OAuth.Messages;
-
- /// <summary>
- /// An OAuth-protocol specific implementation of the <see cref="IMessageFactory"/>
- /// interface.
- /// </summary>
- public class OAuthConsumerMessageFactory : IMessageFactory {
- /// <summary>
- /// Initializes a new instance of the <see cref="OAuthConsumerMessageFactory"/> class.
- /// </summary>
- protected internal OAuthConsumerMessageFactory() {
- }
-
- #region IMessageFactory 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="recipient">The intended or actual recipient of the request message.</param>
- /// <param name="fields">The name/value pairs that make up the message payload.</param>
- /// <returns>
- /// A newly instantiated <see cref="IProtocolMessage"/>-derived object that this message can
- /// deserialize to. Null if the request isn't recognized as a valid protocol message.
- /// </returns>
- /// <remarks>
- /// The request messages are:
- /// UserAuthorizationResponse
- /// </remarks>
- public virtual IDirectedProtocolMessage GetNewRequestMessage(MessageReceivingEndpoint recipient, IDictionary<string, string> fields) {
- MessageBase message = null;
-
- if (fields.ContainsKey("oauth_token")) {
- Protocol protocol = fields.ContainsKey("oauth_verifier") ? Protocol.V10a : Protocol.V10;
- message = new UserAuthorizationResponse(recipient.Location, protocol.Version);
- }
-
- if (message != null) {
- message.SetAsIncoming();
- }
-
- return message;
- }
-
- /// <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>
- /// A newly instantiated <see cref="IProtocolMessage"/>-derived object 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 IDirectResponseProtocolMessage GetNewResponseMessage(IDirectedProtocolMessage request, IDictionary<string, string> fields) {
- MessageBase message = null;
-
- // 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.OAuth.Error("An OAuth message was expected to contain an oauth_token_secret but didn't.");
- return null;
- }
-
- var unauthorizedTokenRequest = request as UnauthorizedTokenRequest;
- var authorizedTokenRequest = request as AuthorizedTokenRequest;
- if (unauthorizedTokenRequest != null) {
- Protocol protocol = fields.ContainsKey("oauth_callback_confirmed") ? Protocol.V10a : Protocol.V10;
- message = new UnauthorizedTokenResponse(unauthorizedTokenRequest, protocol.Version);
- } else if (authorizedTokenRequest != null) {
- message = new AuthorizedTokenResponse(authorizedTokenRequest);
- } else {
- Logger.OAuth.ErrorFormat("Unexpected response message given the request type {0}", request.GetType().Name);
- throw new ProtocolException(OAuthStrings.InvalidIncomingMessage);
- }
-
- if (message != null) {
- message.SetAsIncoming();
- }
-
- return message;
- }
-
- #endregion
- }
-}
diff --git a/src/DotNetOpenAuth.OAuth/OAuth/ChannelElements/OAuthIdentity.cs b/src/DotNetOpenAuth.OAuth/OAuth/ChannelElements/OAuthIdentity.cs
deleted file mode 100644
index 65bde20..0000000
--- a/src/DotNetOpenAuth.OAuth/OAuth/ChannelElements/OAuthIdentity.cs
+++ /dev/null
@@ -1,64 +0,0 @@
-//-----------------------------------------------------------------------
-// <copyright file="OAuthIdentity.cs" company="Andrew Arnott">
-// Copyright (c) Andrew Arnott. All rights reserved.
-// </copyright>
-//-----------------------------------------------------------------------
-
-namespace DotNetOpenAuth.OAuth.ChannelElements {
- using System;
- using System.Diagnostics.CodeAnalysis;
- using System.Diagnostics.Contracts;
- using System.Runtime.InteropServices;
- using System.Security.Principal;
- using DotNetOpenAuth.Messaging;
-
- /// <summary>
- /// Represents an OAuth consumer that is impersonating a known user on the system.
- /// </summary>
- [SuppressMessage("Microsoft.Interoperability", "CA1409:ComVisibleTypesShouldBeCreatable", Justification = "Not cocreatable.")]
- [Serializable]
- [ComVisible(true)]
- public class OAuthIdentity : IIdentity {
- /// <summary>
- /// Initializes a new instance of the <see cref="OAuthIdentity"/> class.
- /// </summary>
- /// <param name="username">The username.</param>
- internal OAuthIdentity(string username) {
- Contract.Requires<ArgumentException>(!String.IsNullOrEmpty(username));
- this.Name = username;
- }
-
- #region IIdentity Members
-
- /// <summary>
- /// Gets the type of authentication used.
- /// </summary>
- /// <value>The constant "OAuth"</value>
- /// <returns>
- /// The type of authentication used to identify the user.
- /// </returns>
- public string AuthenticationType {
- get { return "OAuth"; }
- }
-
- /// <summary>
- /// Gets a value indicating whether the user has been authenticated.
- /// </summary>
- /// <value>The value <c>true</c></value>
- /// <returns>true if the user was authenticated; otherwise, false.
- /// </returns>
- public bool IsAuthenticated {
- get { return true; }
- }
-
- /// <summary>
- /// Gets the name of the user who authorized the OAuth token the consumer is using for authorization.
- /// </summary>
- /// <returns>
- /// The name of the user on whose behalf the code is running.
- /// </returns>
- public string Name { get; private set; }
-
- #endregion
- }
-}
diff --git a/src/DotNetOpenAuth.OAuth/OAuth/ChannelElements/OAuthPrincipal.cs b/src/DotNetOpenAuth.OAuth/OAuth/ChannelElements/OAuthPrincipal.cs
deleted file mode 100644
index 82ecb0a..0000000
--- a/src/DotNetOpenAuth.OAuth/OAuth/ChannelElements/OAuthPrincipal.cs
+++ /dev/null
@@ -1,91 +0,0 @@
-//-----------------------------------------------------------------------
-// <copyright file="OAuthPrincipal.cs" company="Andrew Arnott">
-// Copyright (c) Andrew Arnott. All rights reserved.
-// </copyright>
-//-----------------------------------------------------------------------
-
-namespace DotNetOpenAuth.OAuth.ChannelElements {
- using System;
- using System.Collections.Generic;
- using System.Diagnostics.CodeAnalysis;
- using System.Diagnostics.Contracts;
- using System.Linq;
- using System.Runtime.InteropServices;
- using System.Security.Principal;
-
- /// <summary>
- /// Represents an OAuth consumer that is impersonating a known user on the system.
- /// </summary>
- [SuppressMessage("Microsoft.Interoperability", "CA1409:ComVisibleTypesShouldBeCreatable", Justification = "Not cocreatable.")]
- [Serializable]
- [ComVisible(true)]
- public class OAuthPrincipal : IPrincipal {
- /// <summary>
- /// The roles this user belongs to.
- /// </summary>
- private ICollection<string> roles;
-
- /// <summary>
- /// Initializes a new instance of the <see cref="OAuthPrincipal"/> class.
- /// </summary>
- /// <param name="userName">The username.</param>
- /// <param name="roles">The roles this user belongs to.</param>
- public OAuthPrincipal(string userName, string[] roles)
- : this(new OAuthIdentity(userName), roles) {
- }
-
- /// <summary>
- /// Initializes a new instance of the <see cref="OAuthPrincipal"/> class.
- /// </summary>
- /// <param name="token">The access token.</param>
- internal OAuthPrincipal(IServiceProviderAccessToken token)
- : this(token.Username, token.Roles) {
- Contract.Requires<ArgumentNullException>(token != null);
-
- this.AccessToken = token.Token;
- }
-
- /// <summary>
- /// Initializes a new instance of the <see cref="OAuthPrincipal"/> class.
- /// </summary>
- /// <param name="identity">The identity.</param>
- /// <param name="roles">The roles this user belongs to.</param>
- internal OAuthPrincipal(OAuthIdentity identity, string[] roles) {
- this.Identity = identity;
- this.roles = roles;
- }
-
- /// <summary>
- /// Gets the access token used to create this principal.
- /// </summary>
- /// <value>A non-empty string.</value>
- public string AccessToken { get; private set; }
-
- #region IPrincipal Members
-
- /// <summary>
- /// Gets the identity of the current principal.
- /// </summary>
- /// <value></value>
- /// <returns>
- /// The <see cref="T:System.Security.Principal.IIdentity"/> object associated with the current principal.
- /// </returns>
- public IIdentity Identity { get; private set; }
-
- /// <summary>
- /// Determines whether the current principal belongs to the specified role.
- /// </summary>
- /// <param name="role">The name of the role for which to check membership.</param>
- /// <returns>
- /// true if the current principal is a member of the specified role; otherwise, false.
- /// </returns>
- /// <remarks>
- /// The role membership check uses <see cref="StringComparer.OrdinalIgnoreCase"/>.
- /// </remarks>
- public bool IsInRole(string role) {
- return this.roles.Contains(role, StringComparer.OrdinalIgnoreCase);
- }
-
- #endregion
- }
-}
diff --git a/src/DotNetOpenAuth.OAuth/OAuth/ChannelElements/OAuthServiceProviderMessageFactory.cs b/src/DotNetOpenAuth.OAuth/OAuth/ChannelElements/OAuthServiceProviderMessageFactory.cs
deleted file mode 100644
index 5b3c918..0000000
--- a/src/DotNetOpenAuth.OAuth/OAuth/ChannelElements/OAuthServiceProviderMessageFactory.cs
+++ /dev/null
@@ -1,126 +0,0 @@
-//-----------------------------------------------------------------------
-// <copyright file="OAuthServiceProviderMessageFactory.cs" company="Andrew Arnott">
-// Copyright (c) Andrew Arnott. All rights reserved.
-// </copyright>
-//-----------------------------------------------------------------------
-
-namespace DotNetOpenAuth.OAuth.ChannelElements {
- using System;
- using System.Collections.Generic;
- using System.Diagnostics.Contracts;
- using DotNetOpenAuth.Messaging;
- using DotNetOpenAuth.OAuth.Messages;
-
- /// <summary>
- /// An OAuth-protocol specific implementation of the <see cref="IMessageFactory"/>
- /// interface.
- /// </summary>
- public class OAuthServiceProviderMessageFactory : IMessageFactory {
- /// <summary>
- /// The token manager to use for discerning between request and access tokens.
- /// </summary>
- private IServiceProviderTokenManager tokenManager;
-
- /// <summary>
- /// Initializes a new instance of the <see cref="OAuthServiceProviderMessageFactory"/> class.
- /// </summary>
- /// <param name="tokenManager">The token manager instance to use.</param>
- public OAuthServiceProviderMessageFactory(IServiceProviderTokenManager tokenManager) {
- Contract.Requires<ArgumentNullException>(tokenManager != null);
-
- this.tokenManager = tokenManager;
- }
-
- #region IMessageFactory 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="recipient">The intended or actual recipient of the request message.</param>
- /// <param name="fields">The name/value pairs that make up the message payload.</param>
- /// <returns>
- /// A newly instantiated <see cref="IProtocolMessage"/>-derived object that this message can
- /// deserialize to. Null if the request isn't recognized as a valid protocol message.
- /// </returns>
- /// <remarks>
- /// The request messages are:
- /// UnauthorizedTokenRequest
- /// AuthorizedTokenRequest
- /// UserAuthorizationRequest
- /// AccessProtectedResourceRequest
- /// </remarks>
- public virtual IDirectedProtocolMessage GetNewRequestMessage(MessageReceivingEndpoint recipient, IDictionary<string, string> fields) {
- MessageBase message = null;
- Protocol protocol = Protocol.V10; // default to assuming the less-secure 1.0 instead of 1.0a until we prove otherwise.
- string token;
- fields.TryGetValue("oauth_token", out token);
-
- try {
- if (fields.ContainsKey("oauth_consumer_key") && !fields.ContainsKey("oauth_token")) {
- protocol = fields.ContainsKey("oauth_callback") ? Protocol.V10a : Protocol.V10;
- message = new UnauthorizedTokenRequest(recipient, protocol.Version);
- } else 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(token) == TokenType.AccessToken;
-
- if (tokenTypeIsAccessToken) {
- message = (MessageBase)new AccessProtectedResourceRequest(recipient, protocol.Version);
- } else {
- // Discern between 1.0 and 1.0a requests by checking on the consumer version we stored
- // when the consumer first requested an unauthorized token.
- protocol = Protocol.Lookup(this.tokenManager.GetRequestToken(token).ConsumerVersion);
- message = new AuthorizedTokenRequest(recipient, protocol.Version);
- }
- } else {
- // fail over to the message with no required fields at all.
- if (token != null) {
- protocol = Protocol.Lookup(this.tokenManager.GetRequestToken(token).ConsumerVersion);
- }
-
- // If a callback parameter is included, that suggests either the consumer
- // is following OAuth 1.0 instead of 1.0a, or that a hijacker is trying
- // to attack. Either way, if the consumer started out as a 1.0a, keep it
- // that way, and we'll just ignore the oauth_callback included in this message
- // by virtue of the UserAuthorizationRequest message not including it in its
- // 1.0a payload.
- message = new UserAuthorizationRequest(recipient, protocol.Version);
- }
-
- if (message != null) {
- message.SetAsIncoming();
- }
-
- return message;
- } catch (KeyNotFoundException ex) {
- throw ErrorUtilities.Wrap(ex, OAuthStrings.TokenNotFound);
- }
- }
-
- /// <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 IDirectResponseProtocolMessage GetNewResponseMessage(IDirectedProtocolMessage request, IDictionary<string, string> fields) {
- Logger.OAuth.Error("Service Providers are not expected to ever receive responses.");
- return null;
- }
-
- #endregion
- }
-}
diff --git a/src/DotNetOpenAuth.OAuth/OAuth/ChannelElements/RsaSha1SigningBindingElement.cs b/src/DotNetOpenAuth.OAuth/OAuth/ChannelElements/RsaSha1SigningBindingElement.cs
index f7b8370..83be094 100644
--- a/src/DotNetOpenAuth.OAuth/OAuth/ChannelElements/RsaSha1SigningBindingElement.cs
+++ b/src/DotNetOpenAuth.OAuth/OAuth/ChannelElements/RsaSha1SigningBindingElement.cs
@@ -15,101 +15,17 @@ namespace DotNetOpenAuth.OAuth.ChannelElements {
/// <summary>
/// A binding element that signs outgoing messages and verifies the signature on incoming messages.
/// </summary>
- public class RsaSha1SigningBindingElement : SigningBindingElementBase {
+ public abstract class RsaSha1SigningBindingElement : SigningBindingElementBase {
/// <summary>
/// The name of the hash algorithm to use.
/// </summary>
- private const string HashAlgorithmName = "RSA-SHA1";
+ protected const string HashAlgorithmName = "RSA-SHA1";
/// <summary>
- /// The token manager for the service provider.
+ /// Initializes a new instance of the <see cref="RsaSha1SigningBindingElement"/> class.
/// </summary>
- private IServiceProviderTokenManager tokenManager;
-
- /// <summary>
- /// Initializes a new instance of the <see cref="RsaSha1SigningBindingElement"/> class
- /// for use by Consumers.
- /// </summary>
- /// <param name="signingCertificate">The certificate used to sign outgoing messages.</param>
- public RsaSha1SigningBindingElement(X509Certificate2 signingCertificate)
+ protected RsaSha1SigningBindingElement()
: base(HashAlgorithmName) {
- Contract.Requires<ArgumentNullException>(signingCertificate != null);
-
- this.SigningCertificate = signingCertificate;
- }
-
- /// <summary>
- /// Initializes a new instance of the <see cref="RsaSha1SigningBindingElement"/> class
- /// for use by Service Providers.
- /// </summary>
- /// <param name="tokenManager">The token manager.</param>
- public RsaSha1SigningBindingElement(IServiceProviderTokenManager tokenManager)
- : base(HashAlgorithmName) {
- Contract.Requires<ArgumentNullException>(tokenManager != null);
-
- this.tokenManager = tokenManager;
- }
-
- /// <summary>
- /// Gets or sets the certificate used to sign outgoing messages. Used only by Consumers.
- /// </summary>
- public X509Certificate2 SigningCertificate { get; set; }
-
- /// <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) {
- ErrorUtilities.VerifyOperation(this.SigningCertificate != null, OAuthStrings.X509CertificateNotProvidedForSigning);
-
- string signatureBaseString = ConstructSignatureBaseString(message, this.Channel.MessageDescriptions.GetAccessor(message));
- byte[] data = Encoding.ASCII.GetBytes(signatureBaseString);
- var provider = (RSACryptoServiceProvider)this.SigningCertificate.PrivateKey;
- byte[] binarySignature = provider.SignData(data, "SHA1");
- string base64Signature = Convert.ToBase64String(binarySignature);
- return base64Signature;
- }
-
- /// <summary>
- /// Determines whether the signature on some message is valid.
- /// </summary>
- /// <param name="message">The message to check the signature on.</param>
- /// <returns>
- /// <c>true</c> if the signature on the message is valid; otherwise, <c>false</c>.
- /// </returns>
- protected override bool IsSignatureValid(ITamperResistantOAuthMessage message) {
- ErrorUtilities.VerifyInternal(this.tokenManager != null, "No token manager available for fetching Consumer public certificates.");
-
- string signatureBaseString = ConstructSignatureBaseString(message, this.Channel.MessageDescriptions.GetAccessor(message));
- byte[] data = Encoding.ASCII.GetBytes(signatureBaseString);
-
- byte[] carriedSignature = Convert.FromBase64String(message.Signature);
-
- X509Certificate2 cert = this.tokenManager.GetConsumer(message.ConsumerKey).Certificate;
- if (cert == null) {
- Logger.Signatures.WarnFormat("Incoming message from consumer '{0}' could not be matched with an appropriate X.509 certificate for signature verification.", message.ConsumerKey);
- return false;
- }
-
- var provider = (RSACryptoServiceProvider)cert.PublicKey.Key;
- bool valid = provider.VerifyData(data, "SHA1", carriedSignature);
- return valid;
- }
-
- /// <summary>
- /// Clones this instance.
- /// </summary>
- /// <returns>A new instance of the binding element.</returns>
- protected override ITamperProtectionChannelBindingElement Clone() {
- if (this.tokenManager != null) {
- return new RsaSha1SigningBindingElement(this.tokenManager);
- } else {
- return new RsaSha1SigningBindingElement(this.SigningCertificate);
- }
}
}
}
diff --git a/src/DotNetOpenAuth.OAuth/OAuth/ChannelElements/TokenHandlingBindingElement.cs b/src/DotNetOpenAuth.OAuth/OAuth/ChannelElements/TokenHandlingBindingElement.cs
deleted file mode 100644
index f53aa1b..0000000
--- a/src/DotNetOpenAuth.OAuth/OAuth/ChannelElements/TokenHandlingBindingElement.cs
+++ /dev/null
@@ -1,201 +0,0 @@
-//-----------------------------------------------------------------------
-// <copyright file="TokenHandlingBindingElement.cs" company="Andrew Arnott">
-// Copyright (c) Andrew Arnott. All rights reserved.
-// </copyright>
-//-----------------------------------------------------------------------
-
-namespace DotNetOpenAuth.OAuth.ChannelElements {
- using System;
- using System.Collections.Generic;
- using System.Diagnostics.CodeAnalysis;
- using System.Diagnostics.Contracts;
- using System.Linq;
- using System.Text;
- using DotNetOpenAuth.Configuration;
- using DotNetOpenAuth.Messaging;
- using DotNetOpenAuth.OAuth.Messages;
-
- /// <summary>
- /// A binding element for Service Providers to manage the
- /// callbacks and verification codes on applicable messages.
- /// </summary>
- internal class TokenHandlingBindingElement : IChannelBindingElement {
- /// <summary>
- /// The token manager offered by the service provider.
- /// </summary>
- private IServiceProviderTokenManager tokenManager;
-
- /// <summary>
- /// The security settings for this service provider.
- /// </summary>
- private ServiceProviderSecuritySettings securitySettings;
-
- /// <summary>
- /// Initializes a new instance of the <see cref="TokenHandlingBindingElement"/> class.
- /// </summary>
- /// <param name="tokenManager">The token manager.</param>
- /// <param name="securitySettings">The security settings.</param>
- [SuppressMessage("Microsoft.Globalization", "CA1303:Do not pass literals as localized parameters", MessageId = "System.Diagnostics.Contracts.__ContractsRuntime.Requires<System.ArgumentNullException>(System.Boolean,System.String,System.String)", Justification = "Code contract"), SuppressMessage("Microsoft.Naming", "CA2204:Literals should be spelled correctly", MessageId = "securitySettings", Justification = "Code contracts")]
- internal TokenHandlingBindingElement(IServiceProviderTokenManager tokenManager, ServiceProviderSecuritySettings securitySettings) {
- Contract.Requires<ArgumentNullException>(tokenManager != null);
- Contract.Requires<ArgumentNullException>(securitySettings != null);
-
- this.tokenManager = tokenManager;
- this.securitySettings = securitySettings;
- }
-
- #region IChannelBindingElement Members
-
- /// <summary>
- /// Gets or sets the channel that this binding element belongs to.
- /// </summary>
- /// <remarks>
- /// This property is set by the channel when it is first constructed.
- /// </remarks>
- public Channel Channel { get; set; }
-
- /// <summary>
- /// Gets the protection commonly offered (if any) by this binding element.
- /// </summary>
- /// <remarks>
- /// This value is used to assist in sorting binding elements in the channel stack.
- /// </remarks>
- 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>
- /// The protections (if any) that this binding element applied to the message.
- /// Null if this binding element did not even apply to this binding element.
- /// </returns>
- /// <remarks>
- /// Implementations that provide message protection must honor the
- /// <see cref="MessagePartAttribute.RequiredProtection"/> properties where applicable.
- /// </remarks>
- public MessageProtections? ProcessOutgoingMessage(IProtocolMessage message) {
- var userAuthResponse = message as UserAuthorizationResponse;
- if (userAuthResponse != null && userAuthResponse.Version >= Protocol.V10a.Version) {
- var requestToken = this.tokenManager.GetRequestToken(userAuthResponse.RequestToken);
- requestToken.VerificationCode = userAuthResponse.VerificationCode;
- this.tokenManager.UpdateToken(requestToken);
- return MessageProtections.None;
- }
-
- // Hook to store the token and secret on its way down to the Consumer.
- var grantRequestTokenResponse = message as UnauthorizedTokenResponse;
- if (grantRequestTokenResponse != null) {
- this.tokenManager.StoreNewRequestToken(grantRequestTokenResponse.RequestMessage, grantRequestTokenResponse);
-
- // The host may have already set these properties, but just to make sure...
- var requestToken = this.tokenManager.GetRequestToken(grantRequestTokenResponse.RequestToken);
- requestToken.ConsumerVersion = grantRequestTokenResponse.Version;
- if (grantRequestTokenResponse.RequestMessage.Callback != null) {
- requestToken.Callback = grantRequestTokenResponse.RequestMessage.Callback;
- }
- this.tokenManager.UpdateToken(requestToken);
-
- return MessageProtections.None;
- }
-
- return null;
- }
-
- /// <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>
- /// The protections (if any) that this binding element applied to the message.
- /// Null if this binding element did not even apply to this binding element.
- /// </returns>
- /// <exception cref="ProtocolException">
- /// Thrown when the binding element rules indicate that this message is invalid and should
- /// NOT be processed.
- /// </exception>
- /// <remarks>
- /// Implementations that provide message protection must honor the
- /// <see cref="MessagePartAttribute.RequiredProtection"/> properties where applicable.
- /// </remarks>
- public MessageProtections? ProcessIncomingMessage(IProtocolMessage message) {
- var authorizedTokenRequest = message as AuthorizedTokenRequest;
- if (authorizedTokenRequest != null) {
- if (authorizedTokenRequest.Version >= Protocol.V10a.Version) {
- string expectedVerifier = this.tokenManager.GetRequestToken(authorizedTokenRequest.RequestToken).VerificationCode;
- ErrorUtilities.VerifyProtocol(string.Equals(authorizedTokenRequest.VerificationCode, expectedVerifier, StringComparison.Ordinal), OAuthStrings.IncorrectVerifier);
- return MessageProtections.None;
- }
-
- this.VerifyThrowTokenTimeToLive(authorizedTokenRequest);
- }
-
- var userAuthorizationRequest = message as UserAuthorizationRequest;
- if (userAuthorizationRequest != null) {
- this.VerifyThrowTokenTimeToLive(userAuthorizationRequest);
- }
-
- var accessResourceRequest = message as AccessProtectedResourceRequest;
- if (accessResourceRequest != null) {
- this.VerifyThrowTokenNotExpired(accessResourceRequest);
- }
-
- return null;
- }
-
- #endregion
-
- /// <summary>
- /// Ensures that access tokens have not yet expired.
- /// </summary>
- /// <param name="message">The incoming message carrying the access token.</param>
- private void VerifyThrowTokenNotExpired(AccessProtectedResourceRequest message) {
- Contract.Requires<ArgumentNullException>(message != null);
-
- try {
- IServiceProviderAccessToken token = this.tokenManager.GetAccessToken(message.AccessToken);
- if (token.ExpirationDate.HasValue && DateTime.Now >= token.ExpirationDate.Value.ToLocalTimeSafe()) {
- Logger.OAuth.ErrorFormat(
- "OAuth access token {0} rejected because it expired at {1}, and it is now {2}.",
- token.Token,
- token.ExpirationDate.Value,
- DateTime.Now);
- ErrorUtilities.ThrowProtocol(OAuthStrings.TokenNotFound);
- }
- } catch (KeyNotFoundException ex) {
- throw ErrorUtilities.Wrap(ex, OAuthStrings.TokenNotFound);
- }
- }
-
- /// <summary>
- /// Ensures that short-lived request tokens included in incoming messages have not expired.
- /// </summary>
- /// <param name="message">The incoming message.</param>
- /// <exception cref="ProtocolException">Thrown when the token in the message has expired.</exception>
- private void VerifyThrowTokenTimeToLive(ITokenContainingMessage message) {
- ErrorUtilities.VerifyInternal(!(message is AccessProtectedResourceRequest), "We shouldn't be verifying TTL on access tokens.");
- if (message == null || string.IsNullOrEmpty(message.Token)) {
- return;
- }
-
- try {
- IServiceProviderRequestToken token = this.tokenManager.GetRequestToken(message.Token);
- TimeSpan ttl = this.securitySettings.MaximumRequestTokenTimeToLive;
- if (DateTime.Now >= token.CreatedOn.ToLocalTimeSafe() + ttl) {
- Logger.OAuth.ErrorFormat(
- "OAuth request token {0} rejected because it was originally issued at {1}, expired at {2}, and it is now {3}.",
- token.Token,
- token.CreatedOn,
- token.CreatedOn + ttl,
- DateTime.Now);
- ErrorUtilities.ThrowProtocol(OAuthStrings.TokenNotFound);
- }
- } catch (KeyNotFoundException ex) {
- throw ErrorUtilities.Wrap(ex, OAuthStrings.TokenNotFound);
- }
- }
- }
-}