summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAndrew Arnott <andrewarnott@gmail.com>2008-10-08 09:52:48 -0700
committerAndrew <andrewarnott@gmail.com>2008-10-08 09:52:48 -0700
commit2276413c733f6a26e9b366214bdfb5677e711c75 (patch)
tree0047f172fa2a7f115baf243c0a8cf5a3e5fb4e92 /src
parent29d897769f3e7a9568fa668836807d9a31b5fabc (diff)
downloadDotNetOpenAuth-2276413c733f6a26e9b366214bdfb5677e711c75.zip
DotNetOpenAuth-2276413c733f6a26e9b366214bdfb5677e711c75.tar.gz
DotNetOpenAuth-2276413c733f6a26e9b366214bdfb5677e711c75.tar.bz2
Moved SigningVerificationCallback handling to the OAuthChannel.
Diffstat (limited to 'src')
-rw-r--r--src/DotNetOAuth.Test/ChannelElements/OAuthChannelTests.cs17
-rw-r--r--src/DotNetOAuth.Test/Scenarios/AppendixScenarios.cs10
-rw-r--r--src/DotNetOAuth.Test/Scenarios/CoordinatingOAuthChannel.cs15
-rw-r--r--src/DotNetOAuth.Test/Scenarios/Coordinator.cs15
-rw-r--r--src/DotNetOAuth/ChannelElements/HmacSha1SigningBindingElement.cs8
-rw-r--r--src/DotNetOAuth/ChannelElements/OAuthChannel.cs36
-rw-r--r--src/DotNetOAuth/ChannelElements/PlainTextSigningBindingElement.cs8
-rw-r--r--src/DotNetOAuth/ChannelElements/RsaSha1SigningBindingElement.cs8
-rw-r--r--src/DotNetOAuth/ChannelElements/SigningBindingElementBase.cs40
-rw-r--r--src/DotNetOAuth/ChannelElements/SigningBindingElementChain.cs16
-rw-r--r--src/DotNetOAuth/ClassDiagram.cd6
-rw-r--r--src/DotNetOAuth/Consumer.cs7
-rw-r--r--src/DotNetOAuth/Messaging/ITamperProtectionChannelBindingElement.cs2
-rw-r--r--src/DotNetOAuth/ServiceProvider.cs32
-rw-r--r--src/DotNetOAuth/ServiceProviderDescription.cs3
-rw-r--r--src/DotNetOAuth/Strings.Designer.cs18
-rw-r--r--src/DotNetOAuth/Strings.resx6
17 files changed, 191 insertions, 56 deletions
diff --git a/src/DotNetOAuth.Test/ChannelElements/OAuthChannelTests.cs b/src/DotNetOAuth.Test/ChannelElements/OAuthChannelTests.cs
index a5eebf2..d847726 100644
--- a/src/DotNetOAuth.Test/ChannelElements/OAuthChannelTests.cs
+++ b/src/DotNetOAuth.Test/ChannelElements/OAuthChannelTests.cs
@@ -33,32 +33,37 @@ namespace DotNetOAuth.Test.ChannelElements {
this.webRequestHandler = new TestWebRequestHandler();
this.signingElement = new RsaSha1SigningBindingElement();
this.nonceStore = new NonceMemoryStore(StandardExpirationBindingElement.DefaultMaximumMessageAge);
- this.channel = new OAuthChannel(this.signingElement, this.nonceStore, new TestMessageTypeProvider(), this.webRequestHandler);
+ this.channel = new OAuthChannel(this.signingElement, this.nonceStore, new InMemoryTokenManager(), new TestMessageTypeProvider(), this.webRequestHandler);
}
[TestMethod, ExpectedException(typeof(ArgumentNullException))]
public void CtorNullHandler() {
- new OAuthChannel(this.signingElement, this.nonceStore, new TestMessageTypeProvider(), null);
+ new OAuthChannel(new RsaSha1SigningBindingElement(), this.nonceStore, new InMemoryTokenManager(), new TestMessageTypeProvider(), null);
}
[TestMethod, ExpectedException(typeof(ArgumentException))]
public void CtorNullSigner() {
- new OAuthChannel(null, this.nonceStore, new TestMessageTypeProvider(), this.webRequestHandler);
+ new OAuthChannel(null, this.nonceStore, new InMemoryTokenManager(), new TestMessageTypeProvider(), this.webRequestHandler);
}
[TestMethod, ExpectedException(typeof(ArgumentNullException))]
public void CtorNullStore() {
- new OAuthChannel(this.signingElement, null, new TestMessageTypeProvider(), this.webRequestHandler);
+ new OAuthChannel(new RsaSha1SigningBindingElement(), null, new InMemoryTokenManager(), new TestMessageTypeProvider(), this.webRequestHandler);
+ }
+
+ [TestMethod, ExpectedException(typeof(ArgumentNullException))]
+ public void CtorNullTokenManager() {
+ new OAuthChannel(new RsaSha1SigningBindingElement(), this.nonceStore, null, new TestMessageTypeProvider(), this.webRequestHandler);
}
[TestMethod]
public void CtorSimpleConsumer() {
- new OAuthChannel(this.signingElement, this.nonceStore, new InMemoryTokenManager(), true);
+ new OAuthChannel(new RsaSha1SigningBindingElement(), this.nonceStore, new InMemoryTokenManager(), true);
}
[TestMethod]
public void CtorSimpleServiceProvider() {
- new OAuthChannel(this.signingElement, this.nonceStore, new InMemoryTokenManager(), false);
+ new OAuthChannel(new RsaSha1SigningBindingElement(), this.nonceStore, new InMemoryTokenManager(), false);
}
[TestMethod]
diff --git a/src/DotNetOAuth.Test/Scenarios/AppendixScenarios.cs b/src/DotNetOAuth.Test/Scenarios/AppendixScenarios.cs
index f6273da..debff53 100644
--- a/src/DotNetOAuth.Test/Scenarios/AppendixScenarios.cs
+++ b/src/DotNetOAuth.Test/Scenarios/AppendixScenarios.cs
@@ -29,8 +29,7 @@ namespace DotNetOAuth.Test {
},
};
MessageReceivingEndpoint accessPhotoEndpoint = new MessageReceivingEndpoint("http://photos.example.net/photos?file=vacation.jpg&size=original", HttpDeliveryMethod.AuthorizationHeaderRequest | HttpDeliveryMethod.GetRequest);
- var tokenManager = new InMemoryTokenManager();
- var sp = new ServiceProvider(serviceDescription, tokenManager);
+ var sp = new ServiceProvider(serviceDescription, new InMemoryTokenManager());
Consumer consumer = new Consumer(serviceDescription, new InMemoryTokenManager()) {
ConsumerKey = "dpf43f3p2l4k3l03",
ConsumerSecret = "kd94hf93k423kf44",
@@ -49,12 +48,12 @@ namespace DotNetOAuth.Test {
Assert.AreNotEqual(0, protectedPhoto.ResponseStream.Length);
},
channel => {
- tokenManager.AddConsumer(consumer.ConsumerKey, consumer.ConsumerSecret);
sp.Channel = channel;
+ ((InMemoryTokenManager)sp.TokenManager).AddConsumer(consumer.ConsumerKey, consumer.ConsumerSecret);
var requestTokenMessage = sp.ReadTokenRequest();
sp.SendUnauthorizedTokenResponse(requestTokenMessage, null);
var authRequest = sp.ReadAuthorizationRequest();
- tokenManager.AuthorizeRequestToken(authRequest.RequestToken);
+ ((InMemoryTokenManager)sp.TokenManager).AuthorizeRequestToken(authRequest.RequestToken);
sp.SendAuthorizationResponse(authRequest);
var accessRequest = sp.ReadAccessTokenRequest();
sp.SendAccessToken(accessRequest, null);
@@ -66,7 +65,8 @@ namespace DotNetOAuth.Test {
},
});
});
- coordinator.SigningElement = (ITamperProtectionChannelBindingElement)sp.Channel.BindingElements.Single(el => el is ITamperProtectionChannelBindingElement);
+
+ coordinator.SigningElement = (ITamperProtectionChannelBindingElement)consumer.Channel.BindingElements.Single(el => el is ITamperProtectionChannelBindingElement);
coordinator.Run();
}
}
diff --git a/src/DotNetOAuth.Test/Scenarios/CoordinatingOAuthChannel.cs b/src/DotNetOAuth.Test/Scenarios/CoordinatingOAuthChannel.cs
index c49d341..06cdf87 100644
--- a/src/DotNetOAuth.Test/Scenarios/CoordinatingOAuthChannel.cs
+++ b/src/DotNetOAuth.Test/Scenarios/CoordinatingOAuthChannel.cs
@@ -31,10 +31,23 @@ namespace DotNetOAuth.Test.Scenarios {
/// </param>
/// <param name="isConsumer">True if this channel is constructed for a Consumer.</param>
internal CoordinatingOAuthChannel(ITamperProtectionChannelBindingElement signingBindingElement, bool isConsumer)
+ : this(signingBindingElement, isConsumer, new InMemoryTokenManager()) {
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="CoordinatingOAuthChannel"/> class for Consumers.
+ /// </summary>
+ /// <param name="signingBindingElement">
+ /// The signing element for the Consumer to use. Null for the Service Provider.
+ /// </param>
+ /// <param name="isConsumer">True if this channel is constructed for a Consumer.</param>
+ /// <param name="tokenManager">The token manager to use.</param>
+ private CoordinatingOAuthChannel(ITamperProtectionChannelBindingElement signingBindingElement, bool isConsumer, ITokenManager tokenManager)
: base(
signingBindingElement,
new NonceMemoryStore(StandardExpirationBindingElement.DefaultMaximumMessageAge),
- isConsumer ? (IMessageTypeProvider)new OAuthConsumerMessageTypeProvider(new InMemoryTokenManager()) : new OAuthServiceProviderMessageTypeProvider(new InMemoryTokenManager()),
+ tokenManager,
+ isConsumer ? (IMessageTypeProvider)new OAuthConsumerMessageTypeProvider(tokenManager) : new OAuthServiceProviderMessageTypeProvider(tokenManager),
new TestWebRequestHandler()) {
}
diff --git a/src/DotNetOAuth.Test/Scenarios/Coordinator.cs b/src/DotNetOAuth.Test/Scenarios/Coordinator.cs
index ab270ce..f5e6adc 100644
--- a/src/DotNetOAuth.Test/Scenarios/Coordinator.cs
+++ b/src/DotNetOAuth.Test/Scenarios/Coordinator.cs
@@ -35,11 +35,8 @@ namespace DotNetOAuth.Test.Scenarios {
internal delegate void Actor(CoordinatingOAuthChannel channel);
/// <summary>
- /// Gets or sets the signing element the Consumer channel should use.
+ /// Gets or sets the signing element the channels should clone and use.
/// </summary>
- /// <remarks>
- /// The Service Provider never signs a message, so no property is necessary for that.
- /// </remarks>
internal ITamperProtectionChannelBindingElement SigningElement { get; set; }
/// <summary>
@@ -50,9 +47,15 @@ namespace DotNetOAuth.Test.Scenarios {
throw new InvalidOperationException("SigningElement must be set first.");
}
+ // Clone and reset the template signing binding element.
+ var consumerSigningElement = (ITamperProtectionChannelBindingElement)this.SigningElement.Clone();
+ var spSigningElement = (ITamperProtectionChannelBindingElement)this.SigningElement.Clone();
+ consumerSigningElement.SignatureVerificationCallback = null;
+ spSigningElement.SignatureVerificationCallback = null;
+
// Prepare channels that will pass messages directly back and forth.
- CoordinatingOAuthChannel consumerChannel = new CoordinatingOAuthChannel(this.SigningElement, true);
- CoordinatingOAuthChannel serviceProviderChannel = new CoordinatingOAuthChannel(this.SigningElement, false);
+ CoordinatingOAuthChannel consumerChannel = new CoordinatingOAuthChannel(consumerSigningElement, true);
+ CoordinatingOAuthChannel serviceProviderChannel = new CoordinatingOAuthChannel(spSigningElement, false);
consumerChannel.RemoteChannel = serviceProviderChannel;
serviceProviderChannel.RemoteChannel = consumerChannel;
diff --git a/src/DotNetOAuth/ChannelElements/HmacSha1SigningBindingElement.cs b/src/DotNetOAuth/ChannelElements/HmacSha1SigningBindingElement.cs
index 6a81d1b..6b41542 100644
--- a/src/DotNetOAuth/ChannelElements/HmacSha1SigningBindingElement.cs
+++ b/src/DotNetOAuth/ChannelElements/HmacSha1SigningBindingElement.cs
@@ -36,5 +36,13 @@ namespace DotNetOAuth.ChannelElements {
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 object Clone() {
+ return new HmacSha1SigningBindingElement();
+ }
}
}
diff --git a/src/DotNetOAuth/ChannelElements/OAuthChannel.cs b/src/DotNetOAuth/ChannelElements/OAuthChannel.cs
index ee6170c..8006dd9 100644
--- a/src/DotNetOAuth/ChannelElements/OAuthChannel.cs
+++ b/src/DotNetOAuth/ChannelElements/OAuthChannel.cs
@@ -12,6 +12,7 @@ namespace DotNetOAuth.ChannelElements {
using System.Net;
using System.Text;
using System.Web;
+ using DotNetOAuth.Messages;
using DotNetOAuth.Messaging;
using DotNetOAuth.Messaging.Bindings;
using DotNetOAuth.Messaging.Reflection;
@@ -37,6 +38,7 @@ namespace DotNetOAuth.ChannelElements {
: this(
signingBindingElement,
store,
+ tokenManager,
isConsumer ? (IMessageTypeProvider)new OAuthConsumerMessageTypeProvider(tokenManager) : new OAuthServiceProviderMessageTypeProvider(tokenManager),
new StandardWebRequestHandler()) {
}
@@ -46,6 +48,7 @@ namespace DotNetOAuth.ChannelElements {
/// </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
@@ -58,13 +61,22 @@ namespace DotNetOAuth.ChannelElements {
/// <remarks>
/// This overload for testing purposes only.
/// </remarks>
- internal OAuthChannel(ITamperProtectionChannelBindingElement signingBindingElement, INonceStore store, IMessageTypeProvider messageTypeProvider, IWebRequestHandler webRequestHandler)
+ 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.SignatureVerificationCallback != null) {
+ throw new ArgumentException(Strings.SigningElementAlreadyAssociatedWithChannel, "signingBindingElement");
+ }
+
+ signingBindingElement.SignatureVerificationCallback = this.TokenSignatureVerificationCallback;
}
/// <summary>
@@ -73,6 +85,11 @@ namespace DotNetOAuth.ChannelElements {
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>
@@ -354,5 +371,22 @@ namespace DotNetOAuth.ChannelElements {
return httpRequest;
}
+
+ /// <summary>
+ /// Fills out the secrets in an incoming message so that signature verification can be performed.
+ /// </summary>
+ /// <param name="message">The incoming message.</param>
+ private void TokenSignatureVerificationCallback(ITamperResistantOAuthMessage message) {
+ try {
+ 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/ChannelElements/PlainTextSigningBindingElement.cs b/src/DotNetOAuth/ChannelElements/PlainTextSigningBindingElement.cs
index cebdef9..9cb052e 100644
--- a/src/DotNetOAuth/ChannelElements/PlainTextSigningBindingElement.cs
+++ b/src/DotNetOAuth/ChannelElements/PlainTextSigningBindingElement.cs
@@ -43,5 +43,13 @@ namespace DotNetOAuth.ChannelElements {
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 object Clone() {
+ return new PlainTextSigningBindingElement();
+ }
}
}
diff --git a/src/DotNetOAuth/ChannelElements/RsaSha1SigningBindingElement.cs b/src/DotNetOAuth/ChannelElements/RsaSha1SigningBindingElement.cs
index 20ba93c..e15f4b6 100644
--- a/src/DotNetOAuth/ChannelElements/RsaSha1SigningBindingElement.cs
+++ b/src/DotNetOAuth/ChannelElements/RsaSha1SigningBindingElement.cs
@@ -35,5 +35,13 @@ namespace DotNetOAuth.ChannelElements {
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 object Clone() {
+ return new RsaSha1SigningBindingElement();
+ }
}
}
diff --git a/src/DotNetOAuth/ChannelElements/SigningBindingElementBase.cs b/src/DotNetOAuth/ChannelElements/SigningBindingElementBase.cs
index 7ddf7e8..aa6f19f 100644
--- a/src/DotNetOAuth/ChannelElements/SigningBindingElementBase.cs
+++ b/src/DotNetOAuth/ChannelElements/SigningBindingElementBase.cs
@@ -29,6 +29,17 @@ namespace DotNetOAuth.ChannelElements {
this.signatureMethod = signatureMethod;
}
+ #region IChannelBindingElement Properties
+
+ /// <summary>
+ /// Gets the message protection provided by this binding element.
+ /// </summary>
+ public MessageProtection Protection {
+ get { return MessageProtection.TamperProtection; }
+ }
+
+ #endregion
+
#region ITamperProtectionChannelBindingElement members
/// <summary>
@@ -37,17 +48,22 @@ namespace DotNetOAuth.ChannelElements {
/// </summary>
public Action<ITamperResistantOAuthMessage> SignatureVerificationCallback { get; set; }
- #endregion
-
- #region IChannelBindingElement Members
-
/// <summary>
- /// Gets the message protection provided by this binding element.
+ /// Creates a new object that is a copy of the current instance.
/// </summary>
- public MessageProtection Protection {
- get { return MessageProtection.TamperProtection; }
+ /// <returns>
+ /// A new object that is a copy of this instance.
+ /// </returns>
+ object ICloneable.Clone() {
+ var clone = (SigningBindingElementBase)this.Clone();
+ clone.SignatureVerificationCallback = this.SignatureVerificationCallback;
+ return clone;
}
+ #endregion
+
+ #region IChannelBindingElement Methods
+
/// <summary>
/// Signs the outgoing message.
/// </summary>
@@ -156,6 +172,16 @@ namespace DotNetOAuth.ChannelElements {
}
/// <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 object Clone();
+
+ /// <summary>
/// Calculates a signature for a given message.
/// </summary>
/// <param name="message">The message to sign.</param>
diff --git a/src/DotNetOAuth/ChannelElements/SigningBindingElementChain.cs b/src/DotNetOAuth/ChannelElements/SigningBindingElementChain.cs
index e3dbc3d..9655f2c 100644
--- a/src/DotNetOAuth/ChannelElements/SigningBindingElementChain.cs
+++ b/src/DotNetOAuth/ChannelElements/SigningBindingElementChain.cs
@@ -46,7 +46,7 @@ namespace DotNetOAuth.ChannelElements {
this.signers = signers;
}
- #region ITamperProtectionChannelBindingElement Members
+ #region ITamperProtectionChannelBindingElement Properties
/// <summary>
/// Gets or sets the delegate that will initialize the non-serialized properties necessary on a signed
@@ -114,5 +114,19 @@ namespace DotNetOAuth.ChannelElements {
}
#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>
+ object ICloneable.Clone() {
+ return new SigningBindingElementChain(this.signers.Select(el => (ITamperProtectionChannelBindingElement)el.Clone()).ToArray());
+ }
+
+ #endregion
}
}
diff --git a/src/DotNetOAuth/ClassDiagram.cd b/src/DotNetOAuth/ClassDiagram.cd
index f4db17c..722c7d3 100644
--- a/src/DotNetOAuth/ClassDiagram.cd
+++ b/src/DotNetOAuth/ClassDiagram.cd
@@ -1,14 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
-<ClassDiagram MajorVersion="1" MinorVersion="1">
+<ClassDiagram MajorVersion="1" MinorVersion="1" MembersFormat="NameAndType">
<Class Name="DotNetOAuth.ServiceProvider">
- <Position X="0.5" Y="0.5" Width="3.5" />
+ <Position X="0.5" Y="0.5" Width="5.75" />
<TypeIdentifier>
<HashCode>EAoAAAAgAAACAAABCAAEAAAAAAAIAAEAAQAIAAAAAQA=</HashCode>
<FileName>ServiceProvider.cs</FileName>
</TypeIdentifier>
</Class>
<Class Name="DotNetOAuth.Consumer">
- <Position X="4.25" Y="0.5" Width="3" />
+ <Position X="6.5" Y="0.5" Width="4.75" />
<TypeIdentifier>
<HashCode>AAAAAAAgAAABEAAAAIAABgAAACAIAAQAAYAAAAAAAAA=</HashCode>
<FileName>Consumer.cs</FileName>
diff --git a/src/DotNetOAuth/Consumer.cs b/src/DotNetOAuth/Consumer.cs
index 881eec8..0fc511a 100644
--- a/src/DotNetOAuth/Consumer.cs
+++ b/src/DotNetOAuth/Consumer.cs
@@ -38,9 +38,8 @@ namespace DotNetOAuth {
this.WebRequestHandler = new StandardWebRequestHandler();
ITamperProtectionChannelBindingElement signingElement = serviceDescription.CreateTamperProtectionElement();
INonceStore store = new NonceMemoryStore(StandardExpirationBindingElement.DefaultMaximumMessageAge);
- this.Channel = new OAuthChannel(signingElement, store, new OAuthConsumerMessageTypeProvider(tokenManager), this.WebRequestHandler);
+ this.Channel = new OAuthChannel(signingElement, store, tokenManager, new OAuthConsumerMessageTypeProvider(tokenManager), this.WebRequestHandler);
this.ServiceProvider = serviceDescription;
- this.TokenManager = tokenManager;
}
/// <summary>
@@ -61,7 +60,9 @@ namespace DotNetOAuth {
/// <summary>
/// Gets the persistence store for tokens and secrets.
/// </summary>
- public ITokenManager TokenManager { get; private set; }
+ public ITokenManager TokenManager {
+ get { return this.Channel.TokenManager; }
+ }
/// <summary>
/// Gets or sets the object that processes <see cref="HttpWebRequest"/>s.
diff --git a/src/DotNetOAuth/Messaging/ITamperProtectionChannelBindingElement.cs b/src/DotNetOAuth/Messaging/ITamperProtectionChannelBindingElement.cs
index de900db..cedd61c 100644
--- a/src/DotNetOAuth/Messaging/ITamperProtectionChannelBindingElement.cs
+++ b/src/DotNetOAuth/Messaging/ITamperProtectionChannelBindingElement.cs
@@ -12,7 +12,7 @@ namespace DotNetOAuth.Messaging {
/// An interface that must be implemented by message transforms/validators in order
/// to be included in the channel stack.
/// </summary>
- public interface ITamperProtectionChannelBindingElement : IChannelBindingElement {
+ public interface ITamperProtectionChannelBindingElement : IChannelBindingElement, ICloneable {
/// <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.
diff --git a/src/DotNetOAuth/ServiceProvider.cs b/src/DotNetOAuth/ServiceProvider.cs
index 135ecd0..77a6186 100644
--- a/src/DotNetOAuth/ServiceProvider.cs
+++ b/src/DotNetOAuth/ServiceProvider.cs
@@ -54,12 +54,10 @@ namespace DotNetOAuth {
}
var signingElement = serviceDescription.CreateTamperProtectionElement();
- signingElement.SignatureVerificationCallback = this.TokenSignatureVerificationCallback;
INonceStore store = new NonceMemoryStore(StandardExpirationBindingElement.DefaultMaximumMessageAge);
this.ServiceDescription = serviceDescription;
- this.Channel = new OAuthChannel(signingElement, store, messageTypeProvider, new StandardWebRequestHandler());
+ this.Channel = new OAuthChannel(signingElement, store, tokenManager, messageTypeProvider, new StandardWebRequestHandler());
this.TokenGenerator = new StandardTokenGenerator();
- this.TokenManager = tokenManager;
}
/// <summary>
@@ -75,7 +73,9 @@ namespace DotNetOAuth {
/// <summary>
/// Gets the persistence store for tokens and secrets.
/// </summary>
- public ITokenManager TokenManager { get; private set; }
+ public ITokenManager TokenManager {
+ get { return this.Channel.TokenManager; }
+ }
/// <summary>
/// Gets or sets the channel to use for sending/receiving messages.
@@ -86,8 +86,11 @@ namespace DotNetOAuth {
/// Reads any incoming OAuth message.
/// </summary>
/// <returns>The deserialized message.</returns>
- public IProtocolMessage ReadRequest() {
- return this.Channel.ReadFromRequest();
+ /// <remarks>
+ /// Requires HttpContext.Current.
+ /// </remarks>
+ public IOAuthDirectedMessage ReadRequest() {
+ return (IOAuthDirectedMessage)this.Channel.ReadFromRequest();
}
/// <summary>
@@ -95,8 +98,8 @@ namespace DotNetOAuth {
/// </summary>
/// <param name="request">The HTTP request to read the message from.</param>
/// <returns>The deserialized message.</returns>
- public IProtocolMessage ReadRequest(HttpRequest request) {
- return this.Channel.ReadFromRequest(new HttpRequestInfo(request));
+ public IOAuthDirectedMessage ReadRequest(HttpRequest request) {
+ return (IOAuthDirectedMessage)this.Channel.ReadFromRequest(new HttpRequestInfo(request));
}
/// <summary>
@@ -352,18 +355,5 @@ namespace DotNetOAuth {
return accessMessage;
}
-
- /// <summary>
- /// Fills out the secrets in an incoming message so that signature verification can be performed.
- /// </summary>
- /// <param name="message">The incoming message.</param>
- private void TokenSignatureVerificationCallback(ITamperResistantOAuthMessage message) {
- message.ConsumerSecret = this.TokenManager.GetConsumerSecret(message.ConsumerKey);
-
- var tokenMessage = message as ITokenContainingMessage;
- if (tokenMessage != null) {
- message.TokenSecret = this.TokenManager.GetTokenSecret(tokenMessage.Token);
- }
- }
}
}
diff --git a/src/DotNetOAuth/ServiceProviderDescription.cs b/src/DotNetOAuth/ServiceProviderDescription.cs
index 0ade8d4..56e5378 100644
--- a/src/DotNetOAuth/ServiceProviderDescription.cs
+++ b/src/DotNetOAuth/ServiceProviderDescription.cs
@@ -7,6 +7,7 @@
namespace DotNetOAuth {
using System;
using System.Diagnostics;
+ using System.Linq;
using DotNetOAuth.ChannelElements;
using DotNetOAuth.Messaging;
@@ -78,7 +79,7 @@ namespace DotNetOAuth {
/// </summary>
/// <returns>The created signing element.</returns>
internal ITamperProtectionChannelBindingElement CreateTamperProtectionElement() {
- return new SigningBindingElementChain(this.TamperProtectionElements);
+ return new SigningBindingElementChain(this.TamperProtectionElements.Select(el => (ITamperProtectionChannelBindingElement)el.Clone()).ToArray());
}
}
}
diff --git a/src/DotNetOAuth/Strings.Designer.cs b/src/DotNetOAuth/Strings.Designer.cs
index 75ae01c..54cdc9e 100644
--- a/src/DotNetOAuth/Strings.Designer.cs
+++ b/src/DotNetOAuth/Strings.Designer.cs
@@ -79,6 +79,15 @@ namespace DotNetOAuth {
}
/// <summary>
+ /// Looks up a localized string similar to Failure looking up secret for consumer or token..
+ /// </summary>
+ internal static string ConsumerOrTokenSecretNotFound {
+ get {
+ return ResourceManager.GetString("ConsumerOrTokenSecretNotFound", resourceCulture);
+ }
+ }
+
+ /// <summary>
/// Looks up a localized string similar to An invalid OAuth message received and discarded..
/// </summary>
internal static string InvalidIncomingMessage {
@@ -97,6 +106,15 @@ namespace DotNetOAuth {
}
/// <summary>
+ /// Looks up a localized string similar to The signing element already has been associated with a channel..
+ /// </summary>
+ internal static string SigningElementAlreadyAssociatedWithChannel {
+ get {
+ return ResourceManager.GetString("SigningElementAlreadyAssociatedWithChannel", resourceCulture);
+ }
+ }
+
+ /// <summary>
/// Looks up a localized string similar to All signing elements must offer the same message protection..
/// </summary>
internal static string SigningElementsMustShareSameProtection {
diff --git a/src/DotNetOAuth/Strings.resx b/src/DotNetOAuth/Strings.resx
index 3c6b5f6..b4f6bb7 100644
--- a/src/DotNetOAuth/Strings.resx
+++ b/src/DotNetOAuth/Strings.resx
@@ -123,12 +123,18 @@
<data name="BadAccessTokenInProtectedResourceRequest" xml:space="preserve">
<value>The access token '{0}' is invalid or expired.</value>
</data>
+ <data name="ConsumerOrTokenSecretNotFound" xml:space="preserve">
+ <value>Failure looking up secret for consumer or token.</value>
+ </data>
<data name="InvalidIncomingMessage" xml:space="preserve">
<value>An invalid OAuth message received and discarded.</value>
</data>
<data name="RequestUrlMustNotHaveOAuthParameters" xml:space="preserve">
<value>The request URL query MUST NOT contain any OAuth Protocol Parameters.</value>
</data>
+ <data name="SigningElementAlreadyAssociatedWithChannel" xml:space="preserve">
+ <value>The signing element already has been associated with a channel.</value>
+ </data>
<data name="SigningElementsMustShareSameProtection" xml:space="preserve">
<value>All signing elements must offer the same message protection.</value>
</data>