summaryrefslogtreecommitdiffstats
path: root/src/DotNetOAuth
diff options
context:
space:
mode:
Diffstat (limited to 'src/DotNetOAuth')
-rw-r--r--src/DotNetOAuth/ChannelElements/ITokenManager.cs8
-rw-r--r--src/DotNetOAuth/ChannelElements/OAuthChannel.cs82
-rw-r--r--src/DotNetOAuth/ChannelElements/TokenType.cs30
-rw-r--r--src/DotNetOAuth/Consumer.cs56
-rw-r--r--src/DotNetOAuth/DotNetOAuth.csproj1
-rw-r--r--src/DotNetOAuth/Messaging/Channel.cs52
-rw-r--r--src/DotNetOAuth/ServiceProvider.cs13
-rw-r--r--src/DotNetOAuth/Strings.Designer.cs9
-rw-r--r--src/DotNetOAuth/Strings.resx3
9 files changed, 202 insertions, 52 deletions
diff --git a/src/DotNetOAuth/ChannelElements/ITokenManager.cs b/src/DotNetOAuth/ChannelElements/ITokenManager.cs
index 0ab108c..9c61bc4 100644
--- a/src/DotNetOAuth/ChannelElements/ITokenManager.cs
+++ b/src/DotNetOAuth/ChannelElements/ITokenManager.cs
@@ -26,6 +26,7 @@ namespace DotNetOAuth.ChannelElements {
/// </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>
@@ -63,5 +64,12 @@ namespace DotNetOAuth.ChannelElements {
/// 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/ChannelElements/OAuthChannel.cs b/src/DotNetOAuth/ChannelElements/OAuthChannel.cs
index acbb69b..5ba69e7 100644
--- a/src/DotNetOAuth/ChannelElements/OAuthChannel.cs
+++ b/src/DotNetOAuth/ChannelElements/OAuthChannel.cs
@@ -97,6 +97,22 @@ namespace DotNetOAuth.ChannelElements {
}
/// <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>
@@ -160,34 +176,7 @@ namespace DotNetOAuth.ChannelElements {
/// <param name="request">The message to send.</param>
/// <returns>The remote party's response.</returns>
protected override IProtocolMessage RequestInternal(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;
-
- HttpDeliveryMethod transmissionMethod = oauthRequest.HttpMethods;
- if ((transmissionMethod & HttpDeliveryMethod.AuthorizationHeaderRequest) != 0) {
- httpRequest = this.InitializeRequestAsAuthHeader(request);
- } else if ((transmissionMethod & HttpDeliveryMethod.PostRequest) != 0) {
- httpRequest = this.InitializeRequestAsPost(request);
- } else if ((transmissionMethod & HttpDeliveryMethod.GetRequest) != 0) {
- httpRequest = InitializeRequestAsGet(request);
- } else {
- throw new NotSupportedException();
- }
+ HttpWebRequest httpRequest = this.InitializeRequestInternal(request);
Response response = this.webRequestHandler.GetResponse(httpRequest);
if (response.Body == null) {
@@ -246,6 +235,43 @@ namespace DotNetOAuth.ChannelElements {
}
/// <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;
+
+ HttpDeliveryMethod transmissionMethod = oauthRequest.HttpMethods;
+ if ((transmissionMethod & HttpDeliveryMethod.AuthorizationHeaderRequest) != 0) {
+ httpRequest = this.InitializeRequestAsAuthHeader(request);
+ } else if ((transmissionMethod & HttpDeliveryMethod.PostRequest) != 0) {
+ httpRequest = this.InitializeRequestAsPost(request);
+ } else if ((transmissionMethod & HttpDeliveryMethod.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>
diff --git a/src/DotNetOAuth/ChannelElements/TokenType.cs b/src/DotNetOAuth/ChannelElements/TokenType.cs
new file mode 100644
index 0000000..7aac92f
--- /dev/null
+++ b/src/DotNetOAuth/ChannelElements/TokenType.cs
@@ -0,0 +1,30 @@
+//-----------------------------------------------------------------------
+// <copyright file="TokenType.cs" company="Andrew Arnott">
+// Copyright (c) Andrew Arnott. All rights reserved.
+// </copyright>
+//-----------------------------------------------------------------------
+
+namespace DotNetOAuth.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,
+ }
+}
diff --git a/src/DotNetOAuth/Consumer.cs b/src/DotNetOAuth/Consumer.cs
index 1a99f2e..ab3614a 100644
--- a/src/DotNetOAuth/Consumer.cs
+++ b/src/DotNetOAuth/Consumer.cs
@@ -106,7 +106,7 @@ namespace DotNetOAuth {
/// Processes an incoming authorization-granted message from an SP and obtains an access token.
/// </summary>
/// <returns>The access token.</returns>
- internal string ProcessUserAuthorization() {
+ public string ProcessUserAuthorization() {
var authorizationMessage = this.Channel.ReadFromRequest<DirectUserToConsumerMessage>();
// Exchange request token for access token.
@@ -121,5 +121,59 @@ namespace DotNetOAuth {
this.TokenManager.ExpireRequestTokenAndStoreNewAccessToken(this.ConsumerKey, authorizationMessage.RequestToken, grantAccess.AccessToken, grantAccess.TokenSecret);
return grantAccess.AccessToken;
}
+
+ /// <summary>
+ /// Creates a web request prepared with OAuth authorization
+ /// that may be further tailored by adding parameters by the caller.
+ /// </summary>
+ /// <param name="endpoint">The URL and method on the Service Provider to send the request to.</param>
+ /// <param name="accessToken">The access token that permits access to the protected resource.</param>
+ /// <returns>The initialized WebRequest object.</returns>
+ public WebRequest CreateAuthorizedRequest(ServiceProviderEndpoint endpoint, string accessToken) {
+ if (endpoint == null) {
+ throw new ArgumentNullException("endpoint");
+ }
+ if (String.IsNullOrEmpty(accessToken)) {
+ throw new ArgumentNullException("accessToken");
+ }
+
+ AccessProtectedResourcesMessage message = new AccessProtectedResourcesMessage(endpoint) {
+ AccessToken = accessToken,
+ TokenSecret = this.TokenManager.GetTokenSecret(accessToken),
+ ConsumerKey = this.ConsumerKey,
+ ConsumerSecret = this.ConsumerSecret,
+ };
+
+ WebRequest wr = this.Channel.InitializeRequest(message);
+ return wr;
+ }
+
+ /// <summary>
+ /// Creates a web request prepared with OAuth authorization
+ /// that may be further tailored by adding parameters by the caller.
+ /// </summary>
+ /// <param name="endpoint">The URL and method on the Service Provider to send the request to.</param>
+ /// <param name="accessToken">The access token that permits access to the protected resource.</param>
+ /// <returns>The initialized WebRequest object.</returns>
+ /// <exception cref="WebException">Thrown if the request fails for any reason after it is sent to the Service Provider.</exception>
+ public Response SendAuthorizedRequest(ServiceProviderEndpoint endpoint, string accessToken) {
+ if (endpoint == null) {
+ throw new ArgumentNullException("endpoint");
+ }
+ if (String.IsNullOrEmpty(accessToken)) {
+ throw new ArgumentNullException("accessToken");
+ }
+
+ AccessProtectedResourcesMessage message = new AccessProtectedResourcesMessage(endpoint) {
+ AccessToken = accessToken,
+ TokenSecret = this.TokenManager.GetTokenSecret(accessToken),
+ ConsumerKey = this.ConsumerKey,
+ ConsumerSecret = this.ConsumerSecret,
+ };
+
+ HttpWebRequest wr = this.Channel.InitializeRequest(message);
+ Response response = new Response((HttpWebResponse)wr.GetResponse());
+ return response;
+ }
}
}
diff --git a/src/DotNetOAuth/DotNetOAuth.csproj b/src/DotNetOAuth/DotNetOAuth.csproj
index 54a3957..dcefa1d 100644
--- a/src/DotNetOAuth/DotNetOAuth.csproj
+++ b/src/DotNetOAuth/DotNetOAuth.csproj
@@ -62,6 +62,7 @@
<Compile Include="ChannelElements\PlainTextSigningBindingElement.cs" />
<Compile Include="ChannelElements\HmacSha1SigningBindingElement.cs" />
<Compile Include="ChannelElements\StandardTokenGenerator.cs" />
+ <Compile Include="ChannelElements\TokenType.cs" />
<Compile Include="ServiceProviderEndpoints.cs" />
<Compile Include="Messages\ITokenContainingMessage.cs" />
<Compile Include="Messages\SignedMessageBase.cs" />
diff --git a/src/DotNetOAuth/Messaging/Channel.cs b/src/DotNetOAuth/Messaging/Channel.cs
index 1d398aa..fdca618 100644
--- a/src/DotNetOAuth/Messaging/Channel.cs
+++ b/src/DotNetOAuth/Messaging/Channel.cs
@@ -491,6 +491,35 @@ namespace DotNetOAuth.Messaging {
}
/// <summary>
+ /// Prepares a message for transmit by applying signatures, nonces, etc.
+ /// </summary>
+ /// <param name="message">The message to prepare for sending.</param>
+ /// <remarks>
+ /// This method should NOT be called by derived types
+ /// except when sending ONE WAY request messages.
+ /// </remarks>
+ protected void PrepareMessageForSending(IProtocolMessage message) {
+ if (message == null) {
+ throw new ArgumentNullException("message");
+ }
+
+ MessageProtection appliedProtection = MessageProtection.None;
+ foreach (IChannelBindingElement bindingElement in this.bindingElements) {
+ if (bindingElement.PrepareMessageForSending(message)) {
+ appliedProtection |= bindingElement.Protection;
+ }
+ }
+
+ // Ensure that the message's protection requirements have been satisfied.
+ if ((message.RequiredProtection & appliedProtection) != message.RequiredProtection) {
+ throw new UnprotectedMessageException(message, appliedProtection);
+ }
+
+ EnsureValidMessageParts(message);
+ message.EnsureValidMessage();
+ }
+
+ /// <summary>
/// Calculates a fairly accurate estimation on the size of a message that contains
/// a given set of fields.
/// </summary>
@@ -601,29 +630,6 @@ namespace DotNetOAuth.Messaging {
}
/// <summary>
- /// Prepares a message for transmit by applying signatures, nonces, etc.
- /// </summary>
- /// <param name="message">The message to prepare for sending.</param>
- private void PrepareMessageForSending(IProtocolMessage message) {
- Debug.Assert(message != null, "message == null");
-
- MessageProtection appliedProtection = MessageProtection.None;
- foreach (IChannelBindingElement bindingElement in this.bindingElements) {
- if (bindingElement.PrepareMessageForSending(message)) {
- appliedProtection |= bindingElement.Protection;
- }
- }
-
- // Ensure that the message's protection requirements have been satisfied.
- if ((message.RequiredProtection & appliedProtection) != message.RequiredProtection) {
- throw new UnprotectedMessageException(message, appliedProtection);
- }
-
- EnsureValidMessageParts(message);
- message.EnsureValidMessage();
- }
-
- /// <summary>
/// Verifies the integrity and applicability of an incoming message.
/// </summary>
/// <param name="message">The message just received.</param>
diff --git a/src/DotNetOAuth/ServiceProvider.cs b/src/DotNetOAuth/ServiceProvider.cs
index a6ed9e0..10b1673 100644
--- a/src/DotNetOAuth/ServiceProvider.cs
+++ b/src/DotNetOAuth/ServiceProvider.cs
@@ -147,6 +147,19 @@ namespace DotNetOAuth {
this.Channel.Send(grantAccess);
}
+ internal string GetAccessTokenInRequest() {
+ var accessMessage = this.Channel.ReadFromRequest<AccessProtectedResourcesMessage>();
+ if (this.TokenManager.GetTokenType(accessMessage.AccessToken) != TokenType.AccessToken) {
+ throw new ProtocolException(
+ string.Format(
+ CultureInfo.CurrentCulture,
+ Strings.BadAccessTokenInProtectedResourceRequest,
+ accessMessage.AccessToken));
+ }
+
+ return accessMessage.AccessToken;
+ }
+
private void TokenSignatureVerificationCallback(ITamperResistantOAuthMessage message) {
message.ConsumerSecret = this.TokenManager.GetConsumerSecret(message.ConsumerKey);
diff --git a/src/DotNetOAuth/Strings.Designer.cs b/src/DotNetOAuth/Strings.Designer.cs
index b5ba9c7..07d73d4 100644
--- a/src/DotNetOAuth/Strings.Designer.cs
+++ b/src/DotNetOAuth/Strings.Designer.cs
@@ -70,6 +70,15 @@ namespace DotNetOAuth {
}
/// <summary>
+ /// Looks up a localized string similar to The access token &apos;{0}&apos; is invalid or expired..
+ /// </summary>
+ internal static string BadAccessTokenInProtectedResourceRequest {
+ get {
+ return ResourceManager.GetString("BadAccessTokenInProtectedResourceRequest", resourceCulture);
+ }
+ }
+
+ /// <summary>
/// Looks up a localized string similar to HttpContext.Current is null. There must be an ASP.NET request in process for this operation to succeed..
/// </summary>
internal static string CurrentHttpContextRequired {
diff --git a/src/DotNetOAuth/Strings.resx b/src/DotNetOAuth/Strings.resx
index ffb73ea..98cb7fc 100644
--- a/src/DotNetOAuth/Strings.resx
+++ b/src/DotNetOAuth/Strings.resx
@@ -120,6 +120,9 @@
<data name="AccessTokenNotAuthorized" xml:space="preserve">
<value>Cannot send access token to Consumer for request token '{0}' before it has been authorized.</value>
</data>
+ <data name="BadAccessTokenInProtectedResourceRequest" xml:space="preserve">
+ <value>The access token '{0}' is invalid or expired.</value>
+ </data>
<data name="CurrentHttpContextRequired" xml:space="preserve">
<value>HttpContext.Current is null. There must be an ASP.NET request in process for this operation to succeed.</value>
</data>