summaryrefslogtreecommitdiffstats
path: root/src/DotNetOpenAuth.OAuth.ServiceProvider
diff options
context:
space:
mode:
Diffstat (limited to 'src/DotNetOpenAuth.OAuth.ServiceProvider')
-rw-r--r--src/DotNetOpenAuth.OAuth.ServiceProvider/DotNetOpenAuth.OAuth.ServiceProvider.csproj16
-rw-r--r--src/DotNetOpenAuth.OAuth.ServiceProvider/OAuth/ChannelElements/IServiceProviderTokenManager.cs172
-rw-r--r--src/DotNetOpenAuth.OAuth.ServiceProvider/OAuth/ChannelElements/OAuth1Principal.cs33
-rw-r--r--src/DotNetOpenAuth.OAuth.ServiceProvider/OAuth/ChannelElements/OAuthServiceProviderChannel.cs12
-rw-r--r--src/DotNetOpenAuth.OAuth.ServiceProvider/OAuth/ChannelElements/OAuthServiceProviderMessageFactory.cs2
-rw-r--r--src/DotNetOpenAuth.OAuth.ServiceProvider/OAuth/ChannelElements/RsaSha1ServiceProviderSigningBindingElement.cs2
-rw-r--r--src/DotNetOpenAuth.OAuth.ServiceProvider/OAuth/ChannelElements/TokenHandlingBindingElement.cs20
-rw-r--r--src/DotNetOpenAuth.OAuth.ServiceProvider/OAuth/ServiceProvider.cs216
-rw-r--r--src/DotNetOpenAuth.OAuth.ServiceProvider/OAuth/ServiceProviderHostDescription.cs101
-rw-r--r--src/DotNetOpenAuth.OAuth.ServiceProvider/OAuthReporting.cs54
-rw-r--r--src/DotNetOpenAuth.OAuth.ServiceProvider/Properties/AssemblyInfo.cs3
-rw-r--r--src/DotNetOpenAuth.OAuth.ServiceProvider/packages.config5
12 files changed, 322 insertions, 314 deletions
diff --git a/src/DotNetOpenAuth.OAuth.ServiceProvider/DotNetOpenAuth.OAuth.ServiceProvider.csproj b/src/DotNetOpenAuth.OAuth.ServiceProvider/DotNetOpenAuth.OAuth.ServiceProvider.csproj
index 689d08a..8e87ad4 100644
--- a/src/DotNetOpenAuth.OAuth.ServiceProvider/DotNetOpenAuth.OAuth.ServiceProvider.csproj
+++ b/src/DotNetOpenAuth.OAuth.ServiceProvider/DotNetOpenAuth.OAuth.ServiceProvider.csproj
@@ -4,6 +4,7 @@
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\</SolutionDir>
</PropertyGroup>
<Import Project="$(ProjectRoot)tools\DotNetOpenAuth.props" />
<PropertyGroup>
@@ -18,18 +19,19 @@
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
</PropertyGroup>
<ItemGroup>
+ <Compile Include="OAuthReporting.cs" />
<Compile Include="OAuth\ChannelElements\IConsumerDescription.cs" />
<Compile Include="OAuth\ChannelElements\IServiceProviderAccessToken.cs" />
<Compile Include="OAuth\ChannelElements\IServiceProviderRequestToken.cs" />
<Compile Include="OAuth\ChannelElements\IServiceProviderTokenManager.cs" />
<Compile Include="OAuth\ChannelElements\ITokenGenerator.cs" />
- <Compile Include="OAuth\ChannelElements\OAuth1Principal.cs" />
<Compile Include="OAuth\ChannelElements\OAuthServiceProviderChannel.cs" />
<Compile Include="OAuth\ChannelElements\OAuthServiceProviderMessageFactory.cs" />
<Compile Include="OAuth\ChannelElements\RsaSha1ServiceProviderSigningBindingElement.cs" />
<Compile Include="OAuth\ChannelElements\StandardTokenGenerator.cs" />
<Compile Include="OAuth\ChannelElements\TokenHandlingBindingElement.cs" />
<Compile Include="OAuth\ServiceProvider.cs" />
+ <Compile Include="OAuth\ServiceProviderHostDescription.cs" />
<Compile Include="OAuth\VerificationCodeFormat.cs" />
<Compile Include="Properties\AssemblyInfo.cs">
<SubType>
@@ -50,7 +52,19 @@
<Name>DotNetOpenAuth.OAuth</Name>
</ProjectReference>
</ItemGroup>
+ <ItemGroup>
+ <Reference Include="System.Net.Http" />
+ <Reference Include="System.Net.Http.WebRequest" />
+ <Reference Include="Validation, Version=2.0.0.0, Culture=neutral, PublicKeyToken=2fc06f0d701809a7, processorArchitecture=MSIL">
+ <SpecificVersion>False</SpecificVersion>
+ <HintPath>..\packages\Validation.2.0.2.13022\lib\portable-windows8+net40+sl5+windowsphone8\Validation.dll</HintPath>
+ </Reference>
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="packages.config" />
+ </ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="$(ProjectRoot)tools\DotNetOpenAuth.targets" />
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildProjectDirectory), EnlistmentInfo.targets))\EnlistmentInfo.targets" Condition=" '$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildProjectDirectory), EnlistmentInfo.targets))' != '' " />
+ <Import Project="$(SolutionDir)\.nuget\nuget.targets" />
</Project> \ No newline at end of file
diff --git a/src/DotNetOpenAuth.OAuth.ServiceProvider/OAuth/ChannelElements/IServiceProviderTokenManager.cs b/src/DotNetOpenAuth.OAuth.ServiceProvider/OAuth/ChannelElements/IServiceProviderTokenManager.cs
index 2d47d00..1c413a3 100644
--- a/src/DotNetOpenAuth.OAuth.ServiceProvider/OAuth/ChannelElements/IServiceProviderTokenManager.cs
+++ b/src/DotNetOpenAuth.OAuth.ServiceProvider/OAuth/ChannelElements/IServiceProviderTokenManager.cs
@@ -7,15 +7,14 @@
namespace DotNetOpenAuth.OAuth.ChannelElements {
using System;
using System.Collections.Generic;
- using System.Diagnostics.Contracts;
using System.Linq;
using System.Text;
+ using Validation;
/// <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.
@@ -79,173 +78,4 @@ namespace DotNetOpenAuth.OAuth.ChannelElements {
/// </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) {
- Requires.NotNullOrEmpty(consumerKey, "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) {
- Requires.NotNullOrEmpty(requestToken, "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) {
- Requires.NotNullOrEmpty(token, "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) {
- Requires.NotNullOrEmpty(token, "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) {
- Requires.NotNull(token, "token");
- 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 WebConsumer.ProcessUserAuthorization or
- /// DesktopConsumer.ProcessUserAuthorization 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.ServiceProvider/OAuth/ChannelElements/OAuth1Principal.cs b/src/DotNetOpenAuth.OAuth.ServiceProvider/OAuth/ChannelElements/OAuth1Principal.cs
deleted file mode 100644
index 03f8030..0000000
--- a/src/DotNetOpenAuth.OAuth.ServiceProvider/OAuth/ChannelElements/OAuth1Principal.cs
+++ /dev/null
@@ -1,33 +0,0 @@
-//-----------------------------------------------------------------------
-// <copyright file="OAuth1Principal.cs" company="Outercurve Foundation">
-// Copyright (c) Outercurve Foundation. All rights reserved.
-// </copyright>
-//-----------------------------------------------------------------------
-
-namespace DotNetOpenAuth.OAuth.ChannelElements {
- using System;
- using System.Collections.Generic;
- using System.Diagnostics.CodeAnalysis;
- using System.Linq;
- using System.Runtime.InteropServices;
- using System.Text;
-
- /// <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)]
- internal class OAuth1Principal : OAuthPrincipal {
- /// <summary>
- /// Initializes a new instance of the <see cref="OAuth1Principal"/> class.
- /// </summary>
- /// <param name="token">The access token.</param>
- internal OAuth1Principal(IServiceProviderAccessToken token)
- : base(token.Username, token.Roles) {
- Requires.NotNull(token, "token");
-
- this.AccessToken = token.Token;
- }
- }
-}
diff --git a/src/DotNetOpenAuth.OAuth.ServiceProvider/OAuth/ChannelElements/OAuthServiceProviderChannel.cs b/src/DotNetOpenAuth.OAuth.ServiceProvider/OAuth/ChannelElements/OAuthServiceProviderChannel.cs
index 0d6450f..cb9a91b 100644
--- a/src/DotNetOpenAuth.OAuth.ServiceProvider/OAuth/ChannelElements/OAuthServiceProviderChannel.cs
+++ b/src/DotNetOpenAuth.OAuth.ServiceProvider/OAuth/ChannelElements/OAuthServiceProviderChannel.cs
@@ -8,32 +8,34 @@ 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.Messaging;
using DotNetOpenAuth.Messaging.Bindings;
+ using Validation;
/// <summary>
/// The messaging channel for OAuth 1.0(a) Service Providers.
/// </summary>
internal class OAuthServiceProviderChannel : OAuthChannel {
/// <summary>
- /// Initializes a new instance of the <see cref="OAuthServiceProviderChannel"/> class.
+ /// Initializes a new instance of the <see cref="OAuthServiceProviderChannel" /> 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>
/// <param name="messageTypeProvider">The message type provider.</param>
+ /// <param name="hostFactories">The host factories.</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 OAuthServiceProviderChannel(ITamperProtectionChannelBindingElement signingBindingElement, INonceStore store, IServiceProviderTokenManager tokenManager, ServiceProviderSecuritySettings securitySettings, IMessageFactory messageTypeProvider = null)
+ internal OAuthServiceProviderChannel(ITamperProtectionChannelBindingElement signingBindingElement, INonceStore store, IServiceProviderTokenManager tokenManager, ServiceProviderSecuritySettings securitySettings, IMessageFactory messageTypeProvider = null, IHostFactories hostFactories = null)
: base(
signingBindingElement,
tokenManager,
securitySettings,
messageTypeProvider ?? new OAuthServiceProviderMessageFactory(tokenManager),
- InitializeBindingElements(signingBindingElement, store, tokenManager, securitySettings)) {
+ InitializeBindingElements(signingBindingElement, store, tokenManager, securitySettings),
+ hostFactories) {
Requires.NotNull(tokenManager, "tokenManager");
Requires.NotNull(securitySettings, "securitySettings");
Requires.NotNull(signingBindingElement, "signingBindingElement");
@@ -59,7 +61,7 @@ namespace DotNetOpenAuth.OAuth.ChannelElements {
/// An array of binding elements used to initialize the channel.
/// </returns>
private static IChannelBindingElement[] InitializeBindingElements(ITamperProtectionChannelBindingElement signingBindingElement, INonceStore store, ITokenManager tokenManager, SecuritySettings securitySettings) {
- Contract.Requires(securitySettings != null);
+ Requires.NotNull(securitySettings, "securitySettings");
var bindingElements = OAuthChannel.InitializeBindingElements(signingBindingElement, store);
diff --git a/src/DotNetOpenAuth.OAuth.ServiceProvider/OAuth/ChannelElements/OAuthServiceProviderMessageFactory.cs b/src/DotNetOpenAuth.OAuth.ServiceProvider/OAuth/ChannelElements/OAuthServiceProviderMessageFactory.cs
index 3dcee04..38a1f56 100644
--- a/src/DotNetOpenAuth.OAuth.ServiceProvider/OAuth/ChannelElements/OAuthServiceProviderMessageFactory.cs
+++ b/src/DotNetOpenAuth.OAuth.ServiceProvider/OAuth/ChannelElements/OAuthServiceProviderMessageFactory.cs
@@ -7,9 +7,9 @@
namespace DotNetOpenAuth.OAuth.ChannelElements {
using System;
using System.Collections.Generic;
- using System.Diagnostics.Contracts;
using DotNetOpenAuth.Messaging;
using DotNetOpenAuth.OAuth.Messages;
+ using Validation;
/// <summary>
/// An OAuth-protocol specific implementation of the <see cref="IMessageFactory"/>
diff --git a/src/DotNetOpenAuth.OAuth.ServiceProvider/OAuth/ChannelElements/RsaSha1ServiceProviderSigningBindingElement.cs b/src/DotNetOpenAuth.OAuth.ServiceProvider/OAuth/ChannelElements/RsaSha1ServiceProviderSigningBindingElement.cs
index d1324d4..fd0d3ad 100644
--- a/src/DotNetOpenAuth.OAuth.ServiceProvider/OAuth/ChannelElements/RsaSha1ServiceProviderSigningBindingElement.cs
+++ b/src/DotNetOpenAuth.OAuth.ServiceProvider/OAuth/ChannelElements/RsaSha1ServiceProviderSigningBindingElement.cs
@@ -7,11 +7,11 @@
namespace DotNetOpenAuth.OAuth.ChannelElements {
using System;
using System.Diagnostics.CodeAnalysis;
- using System.Diagnostics.Contracts;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using DotNetOpenAuth.Messaging;
+ using Validation;
/// <summary>
/// A binding element that signs outgoing messages and verifies the signature on incoming messages.
diff --git a/src/DotNetOpenAuth.OAuth.ServiceProvider/OAuth/ChannelElements/TokenHandlingBindingElement.cs b/src/DotNetOpenAuth.OAuth.ServiceProvider/OAuth/ChannelElements/TokenHandlingBindingElement.cs
index e37cc2f..5875650 100644
--- a/src/DotNetOpenAuth.OAuth.ServiceProvider/OAuth/ChannelElements/TokenHandlingBindingElement.cs
+++ b/src/DotNetOpenAuth.OAuth.ServiceProvider/OAuth/ChannelElements/TokenHandlingBindingElement.cs
@@ -8,12 +8,14 @@ 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 System.Threading;
+ using System.Threading.Tasks;
using DotNetOpenAuth.Configuration;
using DotNetOpenAuth.Messaging;
using DotNetOpenAuth.OAuth.Messages;
+ using Validation;
/// <summary>
/// A binding element for Service Providers to manage the
@@ -68,6 +70,7 @@ namespace DotNetOpenAuth.OAuth.ChannelElements {
/// 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>
+ /// <param name="cancellationToken">The cancellation token.</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.
@@ -76,13 +79,13 @@ namespace DotNetOpenAuth.OAuth.ChannelElements {
/// Implementations that provide message protection must honor the
/// <see cref="MessagePartAttribute.RequiredProtection"/> properties where applicable.
/// </remarks>
- public MessageProtections? ProcessOutgoingMessage(IProtocolMessage message) {
+ public Task<MessageProtections?> ProcessOutgoingMessageAsync(IProtocolMessage message, CancellationToken cancellationToken) {
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;
+ return MessageProtectionTasks.None;
}
// Hook to store the token and secret on its way down to the Consumer.
@@ -98,10 +101,10 @@ namespace DotNetOpenAuth.OAuth.ChannelElements {
}
this.tokenManager.UpdateToken(requestToken);
- return MessageProtections.None;
+ return MessageProtectionTasks.None;
}
- return null;
+ return MessageProtectionTasks.Null;
}
/// <summary>
@@ -109,6 +112,7 @@ namespace DotNetOpenAuth.OAuth.ChannelElements {
/// validates an incoming message based on the rules of this channel binding element.
/// </summary>
/// <param name="message">The incoming message to process.</param>
+ /// <param name="cancellationToken">The cancellation token.</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.
@@ -121,13 +125,13 @@ namespace DotNetOpenAuth.OAuth.ChannelElements {
/// Implementations that provide message protection must honor the
/// <see cref="MessagePartAttribute.RequiredProtection"/> properties where applicable.
/// </remarks>
- public MessageProtections? ProcessIncomingMessage(IProtocolMessage message) {
+ public Task<MessageProtections?> ProcessIncomingMessageAsync(IProtocolMessage message, CancellationToken cancellationToken) {
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;
+ return MessageProtectionTasks.None;
}
this.VerifyThrowTokenTimeToLive(authorizedTokenRequest);
@@ -143,7 +147,7 @@ namespace DotNetOpenAuth.OAuth.ChannelElements {
this.VerifyThrowTokenNotExpired(accessResourceRequest);
}
- return null;
+ return MessageProtectionTasks.Null;
}
#endregion
diff --git a/src/DotNetOpenAuth.OAuth.ServiceProvider/OAuth/ServiceProvider.cs b/src/DotNetOpenAuth.OAuth.ServiceProvider/OAuth/ServiceProvider.cs
index ecfd191..b1deb74 100644
--- a/src/DotNetOpenAuth.OAuth.ServiceProvider/OAuth/ServiceProvider.cs
+++ b/src/DotNetOpenAuth.OAuth.ServiceProvider/OAuth/ServiceProvider.cs
@@ -9,16 +9,19 @@ namespace DotNetOpenAuth.OAuth {
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics.CodeAnalysis;
- using System.Diagnostics.Contracts;
using System.Globalization;
+ using System.Net.Http;
using System.Security.Principal;
using System.ServiceModel.Channels;
+ using System.Threading;
+ using System.Threading.Tasks;
using System.Web;
using DotNetOpenAuth.Configuration;
using DotNetOpenAuth.Messaging;
using DotNetOpenAuth.Messaging.Bindings;
using DotNetOpenAuth.OAuth.ChannelElements;
using DotNetOpenAuth.OAuth.Messages;
+ using Validation;
/// <summary>
/// A web application that allows access via OAuth.
@@ -34,7 +37,7 @@ namespace DotNetOpenAuth.OAuth {
public class ServiceProvider : IDisposable {
/// <summary>
/// The name of the key to use in the HttpApplication cache to store the
- /// instance of <see cref="NonceMemoryStore"/> to use.
+ /// instance of <see cref="MemoryNonceStore"/> to use.
/// </summary>
private const string ApplicationStoreKey = "DotNetOpenAuth.OAuth.ServiceProvider.HttpApplicationStore";
@@ -53,7 +56,7 @@ namespace DotNetOpenAuth.OAuth {
/// </summary>
/// <param name="serviceDescription">The endpoints and behavior on the Service Provider.</param>
/// <param name="tokenManager">The host's method of storing and recalling tokens and secrets.</param>
- public ServiceProvider(ServiceProviderDescription serviceDescription, IServiceProviderTokenManager tokenManager)
+ public ServiceProvider(ServiceProviderHostDescription serviceDescription, IServiceProviderTokenManager tokenManager)
: this(serviceDescription, tokenManager, new OAuthServiceProviderMessageFactory(tokenManager)) {
}
@@ -63,8 +66,8 @@ namespace DotNetOpenAuth.OAuth {
/// <param name="serviceDescription">The endpoints and behavior on the Service Provider.</param>
/// <param name="tokenManager">The host's method of storing and recalling tokens and secrets.</param>
/// <param name="messageTypeProvider">An object that can figure out what type of message is being received for deserialization.</param>
- public ServiceProvider(ServiceProviderDescription serviceDescription, IServiceProviderTokenManager tokenManager, OAuthServiceProviderMessageFactory messageTypeProvider)
- : this(serviceDescription, tokenManager, OAuthElement.Configuration.ServiceProvider.ApplicationStore.CreateInstance(HttpApplicationStore), messageTypeProvider) {
+ public ServiceProvider(ServiceProviderHostDescription serviceDescription, IServiceProviderTokenManager tokenManager, OAuthServiceProviderMessageFactory messageTypeProvider)
+ : this(serviceDescription, tokenManager, OAuthElement.Configuration.ServiceProvider.ApplicationStore.CreateInstance(GetHttpApplicationStore(), null), messageTypeProvider) {
Requires.NotNull(serviceDescription, "serviceDescription");
Requires.NotNull(tokenManager, "tokenManager");
Requires.NotNull(messageTypeProvider, "messageTypeProvider");
@@ -76,7 +79,7 @@ namespace DotNetOpenAuth.OAuth {
/// <param name="serviceDescription">The endpoints and behavior on the Service Provider.</param>
/// <param name="tokenManager">The host's method of storing and recalling tokens and secrets.</param>
/// <param name="nonceStore">The nonce store.</param>
- public ServiceProvider(ServiceProviderDescription serviceDescription, IServiceProviderTokenManager tokenManager, INonceStore nonceStore)
+ public ServiceProvider(ServiceProviderHostDescription serviceDescription, IServiceProviderTokenManager tokenManager, INonceStore nonceStore)
: this(serviceDescription, tokenManager, nonceStore, new OAuthServiceProviderMessageFactory(tokenManager)) {
}
@@ -87,7 +90,7 @@ namespace DotNetOpenAuth.OAuth {
/// <param name="tokenManager">The host's method of storing and recalling tokens and secrets.</param>
/// <param name="nonceStore">The nonce store.</param>
/// <param name="messageTypeProvider">An object that can figure out what type of message is being received for deserialization.</param>
- public ServiceProvider(ServiceProviderDescription serviceDescription, IServiceProviderTokenManager tokenManager, INonceStore nonceStore, OAuthServiceProviderMessageFactory messageTypeProvider) {
+ public ServiceProvider(ServiceProviderHostDescription serviceDescription, IServiceProviderTokenManager tokenManager, INonceStore nonceStore, OAuthServiceProviderMessageFactory messageTypeProvider) {
Requires.NotNull(serviceDescription, "serviceDescription");
Requires.NotNull(tokenManager, "tokenManager");
Requires.NotNull(nonceStore, "nonceStore");
@@ -103,36 +106,9 @@ namespace DotNetOpenAuth.OAuth {
}
/// <summary>
- /// Gets the standard state storage mechanism that uses ASP.NET's
- /// HttpApplication state dictionary to store associations and nonces.
- /// </summary>
- [EditorBrowsable(EditorBrowsableState.Advanced)]
- public static INonceStore HttpApplicationStore {
- get {
- Contract.Ensures(Contract.Result<INonceStore>() != null);
-
- HttpContext context = HttpContext.Current;
- ErrorUtilities.VerifyOperation(context != null, Strings.StoreRequiredWhenNoHttpContextAvailable, typeof(INonceStore).Name);
- var store = (INonceStore)context.Application[ApplicationStoreKey];
- if (store == null) {
- context.Application.Lock();
- try {
- if ((store = (INonceStore)context.Application[ApplicationStoreKey]) == null) {
- context.Application[ApplicationStoreKey] = store = new NonceMemoryStore(StandardExpirationBindingElement.MaximumMessageAge);
- }
- } finally {
- context.Application.UnLock();
- }
- }
-
- return store;
- }
- }
-
- /// <summary>
/// Gets the description of this Service Provider.
/// </summary>
- public ServiceProviderDescription ServiceDescription { get; private set; }
+ public ServiceProviderHostDescription ServiceDescription { get; private set; }
/// <summary>
/// Gets or sets the generator responsible for generating new tokens and secrets.
@@ -173,6 +149,33 @@ namespace DotNetOpenAuth.OAuth {
}
/// <summary>
+ /// Gets the standard state storage mechanism that uses ASP.NET's
+ /// HttpApplication state dictionary to store associations and nonces.
+ /// </summary>
+ /// <param name="context">The HTTP context. If <c>null</c>, this method must be called while <see cref="HttpContext.Current"/> is non-null.</param>
+ /// <returns>The nonce store.</returns>
+ public static INonceStore GetHttpApplicationStore(HttpContextBase context = null) {
+ if (context == null) {
+ ErrorUtilities.VerifyOperation(HttpContext.Current != null, Strings.StoreRequiredWhenNoHttpContextAvailable, typeof(INonceStore).Name);
+ context = new HttpContextWrapper(HttpContext.Current);
+ }
+
+ var store = (INonceStore)context.Application[ApplicationStoreKey];
+ if (store == null) {
+ context.Application.Lock();
+ try {
+ if ((store = (INonceStore)context.Application[ApplicationStoreKey]) == null) {
+ context.Application[ApplicationStoreKey] = store = new MemoryNonceStore(StandardExpirationBindingElement.MaximumMessageAge);
+ }
+ } finally {
+ context.Application.UnLock();
+ }
+ }
+
+ return store;
+ }
+
+ /// <summary>
/// Creates a cryptographically strong random verification code.
/// </summary>
/// <param name="format">The desired format of the verification code.</param>
@@ -182,7 +185,7 @@ namespace DotNetOpenAuth.OAuth {
/// length of the final string.</param>
/// <returns>The verification code.</returns>
public static string CreateVerificationCode(VerificationCodeFormat format, int length) {
- Requires.InRange(length >= 0, "length");
+ Requires.Range(length >= 0, "length");
switch (format) {
case VerificationCodeFormat.IncludedInCallback:
@@ -203,46 +206,65 @@ namespace DotNetOpenAuth.OAuth {
/// <summary>
/// Reads any incoming OAuth message.
/// </summary>
- /// <returns>The deserialized message.</returns>
+ /// <param name="request">The request.</param>
+ /// <param name="cancellationToken">The cancellation token.</param>
+ /// <returns>
+ /// The deserialized message.
+ /// </returns>
/// <remarks>
/// Requires HttpContext.Current.
/// </remarks>
- public IDirectedProtocolMessage ReadRequest() {
- return this.Channel.ReadFromRequest();
+ public Task<IDirectedProtocolMessage> ReadRequestAsync(HttpRequestBase request = null, CancellationToken cancellationToken = default(CancellationToken)) {
+ return this.ReadRequestAsync((request ?? this.Channel.GetRequestFromContext()).AsHttpRequestMessage(), cancellationToken);
}
/// <summary>
/// Reads any incoming OAuth message.
/// </summary>
- /// <param name="request">The HTTP request to read the message from.</param>
- /// <returns>The deserialized message.</returns>
- public IDirectedProtocolMessage ReadRequest(HttpRequestBase request) {
- return this.Channel.ReadFromRequest(request);
+ /// <param name="request">The request.</param>
+ /// <param name="cancellationToken">The cancellation token.</param>
+ /// <returns>
+ /// The deserialized message.
+ /// </returns>
+ /// <remarks>
+ /// Requires HttpContext.Current.
+ /// </remarks>
+ public Task<IDirectedProtocolMessage> ReadRequestAsync(HttpRequestMessage request, CancellationToken cancellationToken = default(CancellationToken)) {
+ Requires.NotNull(request, "request");
+ return this.Channel.ReadFromRequestAsync(request, cancellationToken);
}
/// <summary>
- /// Gets the incoming request for an unauthorized token, if any.
+ /// Reads a request for an unauthorized token from the incoming HTTP request.
/// </summary>
- /// <returns>The incoming request, or null if no OAuth message was attached.</returns>
+ /// <param name="request">The HTTP request to read from.</param>
+ /// <param name="cancellationToken">The cancellation token.</param>
+ /// <returns>
+ /// The incoming request, or null if no OAuth message was attached.
+ /// </returns>
/// <exception cref="ProtocolException">Thrown if an unexpected OAuth message is attached to the incoming request.</exception>
- /// <remarks>
- /// Requires HttpContext.Current.
- /// </remarks>
- public UnauthorizedTokenRequest ReadTokenRequest() {
- return this.ReadTokenRequest(this.Channel.GetRequestFromContext());
+ public Task<UnauthorizedTokenRequest> ReadTokenRequestAsync(
+ HttpRequestBase request = null, CancellationToken cancellationToken = default(CancellationToken)) {
+ return this.ReadTokenRequestAsync((request ?? this.channel.GetRequestFromContext()).AsHttpRequestMessage(), cancellationToken);
}
/// <summary>
/// Reads a request for an unauthorized token from the incoming HTTP request.
/// </summary>
/// <param name="request">The HTTP request to read from.</param>
- /// <returns>The incoming request, or null if no OAuth message was attached.</returns>
+ /// <param name="cancellationToken">The cancellation token.</param>
+ /// <returns>
+ /// The incoming request, or null if no OAuth message was attached.
+ /// </returns>
/// <exception cref="ProtocolException">Thrown if an unexpected OAuth message is attached to the incoming request.</exception>
- public UnauthorizedTokenRequest ReadTokenRequest(HttpRequestBase request) {
- UnauthorizedTokenRequest message;
- if (this.Channel.TryReadFromRequest(request, out message)) {
+ public async Task<UnauthorizedTokenRequest> ReadTokenRequestAsync(HttpRequestMessage request, CancellationToken cancellationToken = default(CancellationToken)) {
+ Requires.NotNull(request, "request");
+
+ var message = await this.Channel.TryReadFromRequestAsync<UnauthorizedTokenRequest>(request, cancellationToken);
+ if (message != null) {
ErrorUtilities.VerifyProtocol(message.Version >= Protocol.Lookup(this.SecuritySettings.MinimumRequiredOAuthVersion).Version, OAuthStrings.MinimumConsumerVersionRequirementNotMet, this.SecuritySettings.MinimumRequiredOAuthVersion, message.Version);
}
+
return message;
}
@@ -263,16 +285,18 @@ namespace DotNetOpenAuth.OAuth {
}
/// <summary>
- /// Gets the incoming request for the Service Provider to authorize a Consumer's
- /// access to some protected resources.
+ /// Reads in a Consumer's request for the Service Provider to obtain permission from
+ /// the user to authorize the Consumer's access of some protected resource(s).
/// </summary>
- /// <returns>The incoming request, or null if no OAuth message was attached.</returns>
+ /// <param name="request">The HTTP request to read from.</param>
+ /// <param name="cancellationToken">The cancellation token.</param>
+ /// <returns>
+ /// The incoming request, or null if no OAuth message was attached.
+ /// </returns>
/// <exception cref="ProtocolException">Thrown if an unexpected OAuth message is attached to the incoming request.</exception>
- /// <remarks>
- /// Requires HttpContext.Current.
- /// </remarks>
- public UserAuthorizationRequest ReadAuthorizationRequest() {
- return this.ReadAuthorizationRequest(this.Channel.GetRequestFromContext());
+ public Task<UserAuthorizationRequest> ReadAuthorizationRequestAsync(HttpRequestBase request = null, CancellationToken cancellationToken = default(CancellationToken)) {
+ request = request ?? this.channel.GetRequestFromContext();
+ return this.ReadAuthorizationRequestAsync(request.AsHttpRequestMessage(), cancellationToken);
}
/// <summary>
@@ -280,12 +304,14 @@ namespace DotNetOpenAuth.OAuth {
/// the user to authorize the Consumer's access of some protected resource(s).
/// </summary>
/// <param name="request">The HTTP request to read from.</param>
- /// <returns>The incoming request, or null if no OAuth message was attached.</returns>
+ /// <param name="cancellationToken">The cancellation token.</param>
+ /// <returns>
+ /// The incoming request, or null if no OAuth message was attached.
+ /// </returns>
/// <exception cref="ProtocolException">Thrown if an unexpected OAuth message is attached to the incoming request.</exception>
- public UserAuthorizationRequest ReadAuthorizationRequest(HttpRequestBase request) {
- UserAuthorizationRequest message;
- this.Channel.TryReadFromRequest(request, out message);
- return message;
+ public Task<UserAuthorizationRequest> ReadAuthorizationRequestAsync(HttpRequestMessage request, CancellationToken cancellationToken = default(CancellationToken)) {
+ Requires.NotNull(request, "request");
+ return this.Channel.TryReadFromRequestAsync<UserAuthorizationRequest>(request, cancellationToken);
}
/// <summary>
@@ -351,27 +377,31 @@ namespace DotNetOpenAuth.OAuth {
}
/// <summary>
- /// Gets the incoming request to exchange an authorized token for an access token.
+ /// Reads in a Consumer's request to exchange an authorized request token for an access token.
/// </summary>
- /// <returns>The incoming request, or null if no OAuth message was attached.</returns>
+ /// <param name="request">The HTTP request to read from.</param>
+ /// <param name="cancellationToken">The cancellation token.</param>
+ /// <returns>
+ /// The incoming request, or null if no OAuth message was attached.
+ /// </returns>
/// <exception cref="ProtocolException">Thrown if an unexpected OAuth message is attached to the incoming request.</exception>
- /// <remarks>
- /// Requires HttpContext.Current.
- /// </remarks>
- public AuthorizedTokenRequest ReadAccessTokenRequest() {
- return this.ReadAccessTokenRequest(this.Channel.GetRequestFromContext());
+ public Task<AuthorizedTokenRequest> ReadAccessTokenRequestAsync(HttpRequestBase request = null, CancellationToken cancellationToken = default(CancellationToken)) {
+ request = request ?? this.Channel.GetRequestFromContext();
+ return this.ReadAccessTokenRequestAsync(request.AsHttpRequestMessage(), cancellationToken);
}
/// <summary>
/// Reads in a Consumer's request to exchange an authorized request token for an access token.
/// </summary>
/// <param name="request">The HTTP request to read from.</param>
- /// <returns>The incoming request, or null if no OAuth message was attached.</returns>
+ /// <param name="cancellationToken">The cancellation token.</param>
+ /// <returns>
+ /// The incoming request, or null if no OAuth message was attached.
+ /// </returns>
/// <exception cref="ProtocolException">Thrown if an unexpected OAuth message is attached to the incoming request.</exception>
- public AuthorizedTokenRequest ReadAccessTokenRequest(HttpRequestBase request) {
- AuthorizedTokenRequest message;
- this.Channel.TryReadFromRequest(request, out message);
- return message;
+ public Task<AuthorizedTokenRequest> ReadAccessTokenRequestAsync(HttpRequestMessage request, CancellationToken cancellationToken = default(CancellationToken)) {
+ Requires.NotNull(request, "request");
+ return this.Channel.TryReadFromRequestAsync<AuthorizedTokenRequest>(request, cancellationToken);
}
/// <summary>
@@ -398,6 +428,9 @@ namespace DotNetOpenAuth.OAuth {
/// <summary>
/// Gets the authorization (access token) for accessing some protected resource.
/// </summary>
+ /// <param name="request">HTTP details from an incoming WCF message.</param>
+ /// <param name="requestUri">The URI of the WCF service endpoint.</param>
+ /// <param name="cancellationToken">The cancellation token.</param>
/// <returns>The authorization message sent by the Consumer, or null if no authorization message is attached.</returns>
/// <remarks>
/// This method verifies that the access token and token secret are valid.
@@ -405,15 +438,15 @@ namespace DotNetOpenAuth.OAuth {
/// to access the resources being requested.
/// </remarks>
/// <exception cref="ProtocolException">Thrown if an unexpected message is attached to the request.</exception>
- public AccessProtectedResourceRequest ReadProtectedResourceAuthorization() {
- return this.ReadProtectedResourceAuthorization(this.Channel.GetRequestFromContext());
+ public Task<AccessProtectedResourceRequest> ReadProtectedResourceAuthorizationAsync(HttpRequestMessageProperty request, Uri requestUri, CancellationToken cancellationToken = default(CancellationToken)) {
+ return this.ReadProtectedResourceAuthorizationAsync(new HttpRequestInfo(request, requestUri), cancellationToken);
}
/// <summary>
/// Gets the authorization (access token) for accessing some protected resource.
/// </summary>
- /// <param name="request">HTTP details from an incoming WCF message.</param>
- /// <param name="requestUri">The URI of the WCF service endpoint.</param>
+ /// <param name="request">The incoming HTTP request.</param>
+ /// <param name="cancellationToken">The cancellation token.</param>
/// <returns>The authorization message sent by the Consumer, or null if no authorization message is attached.</returns>
/// <remarks>
/// This method verifies that the access token and token secret are valid.
@@ -421,14 +454,16 @@ namespace DotNetOpenAuth.OAuth {
/// to access the resources being requested.
/// </remarks>
/// <exception cref="ProtocolException">Thrown if an unexpected message is attached to the request.</exception>
- public AccessProtectedResourceRequest ReadProtectedResourceAuthorization(HttpRequestMessageProperty request, Uri requestUri) {
- return this.ReadProtectedResourceAuthorization(new HttpRequestInfo(request, requestUri));
+ public Task<AccessProtectedResourceRequest> ReadProtectedResourceAuthorizationAsync(HttpRequestBase request = null, CancellationToken cancellationToken = default(CancellationToken)) {
+ request = request ?? this.channel.GetRequestFromContext();
+ return this.ReadProtectedResourceAuthorizationAsync(request.AsHttpRequestMessage(), cancellationToken);
}
/// <summary>
/// Gets the authorization (access token) for accessing some protected resource.
/// </summary>
/// <param name="request">The incoming HTTP request.</param>
+ /// <param name="cancellationToken">The cancellation token.</param>
/// <returns>The authorization message sent by the Consumer, or null if no authorization message is attached.</returns>
/// <remarks>
/// This method verifies that the access token and token secret are valid.
@@ -436,11 +471,10 @@ namespace DotNetOpenAuth.OAuth {
/// to access the resources being requested.
/// </remarks>
/// <exception cref="ProtocolException">Thrown if an unexpected message is attached to the request.</exception>
- public AccessProtectedResourceRequest ReadProtectedResourceAuthorization(HttpRequestBase request) {
+ public async Task<AccessProtectedResourceRequest> ReadProtectedResourceAuthorizationAsync(HttpRequestMessage request, CancellationToken cancellationToken = default(CancellationToken)) {
Requires.NotNull(request, "request");
-
- AccessProtectedResourceRequest accessMessage;
- if (this.Channel.TryReadFromRequest<AccessProtectedResourceRequest>(request, out accessMessage)) {
+ var accessMessage = await this.Channel.TryReadFromRequestAsync<AccessProtectedResourceRequest>(request, cancellationToken);
+ if (accessMessage != null) {
if (this.TokenManager.GetTokenType(accessMessage.AccessToken) != TokenType.AccessToken) {
throw new ProtocolException(
string.Format(
@@ -458,11 +492,11 @@ namespace DotNetOpenAuth.OAuth {
/// </summary>
/// <param name="request">The request.</param>
/// <returns>The <see cref="IPrincipal"/> instance that can be used for access control of resources.</returns>
- public OAuthPrincipal CreatePrincipal(AccessProtectedResourceRequest request) {
+ public IPrincipal CreatePrincipal(AccessProtectedResourceRequest request) {
Requires.NotNull(request, "request");
IServiceProviderAccessToken accessToken = this.TokenManager.GetAccessToken(request.AccessToken);
- return new OAuth1Principal(accessToken);
+ return OAuthPrincipal.CreatePrincipal(accessToken.Username, accessToken.Roles);
}
#region IDisposable Members
diff --git a/src/DotNetOpenAuth.OAuth.ServiceProvider/OAuth/ServiceProviderHostDescription.cs b/src/DotNetOpenAuth.OAuth.ServiceProvider/OAuth/ServiceProviderHostDescription.cs
new file mode 100644
index 0000000..33834eb
--- /dev/null
+++ b/src/DotNetOpenAuth.OAuth.ServiceProvider/OAuth/ServiceProviderHostDescription.cs
@@ -0,0 +1,101 @@
+//-----------------------------------------------------------------------
+// <copyright file="ServiceProviderHostDescription.cs" company="Outercurve Foundation">
+// Copyright (c) Outercurve Foundation. All rights reserved.
+// </copyright>
+//-----------------------------------------------------------------------
+
+namespace DotNetOpenAuth.OAuth {
+ using System;
+ using System.Diagnostics;
+ using System.Diagnostics.CodeAnalysis;
+ using System.Linq;
+ using DotNetOpenAuth.Messaging;
+ using DotNetOpenAuth.OAuth.ChannelElements;
+
+ /// <summary>
+ /// A description of the endpoints on a Service Provider.
+ /// </summary>
+ public class ServiceProviderHostDescription {
+ /// <summary>
+ /// The field used to store the value of the <see cref="RequestTokenEndpoint"/> property.
+ /// </summary>
+ [DebuggerBrowsable(DebuggerBrowsableState.Never)]
+ private MessageReceivingEndpoint requestTokenEndpoint;
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="ServiceProviderHostDescription"/> class.
+ /// </summary>
+ public ServiceProviderHostDescription() {
+ this.ProtocolVersion = Protocol.Default.ProtocolVersion;
+ }
+
+ /// <summary>
+ /// Gets or sets the OAuth version supported by the Service Provider.
+ /// </summary>
+ public ProtocolVersion ProtocolVersion { get; set; }
+
+ /// <summary>
+ /// Gets or sets the URL used to obtain an unauthorized Request Token,
+ /// described in Section 6.1 (Obtaining an Unauthorized Request Token).
+ /// </summary>
+ /// <remarks>
+ /// The request URL query MUST NOT contain any OAuth Protocol Parameters.
+ /// This is the URL that <see cref="OAuth.Messages.UnauthorizedTokenRequest"/> messages are directed to.
+ /// </remarks>
+ /// <exception cref="ArgumentException">Thrown if this property is set to a URI with OAuth protocol parameters.</exception>
+ public MessageReceivingEndpoint RequestTokenEndpoint {
+ get {
+ return this.requestTokenEndpoint;
+ }
+
+ set {
+ if (value != null && UriUtil.QueryStringContainPrefixedParameters(value.Location, OAuth.Protocol.ParameterPrefix)) {
+ throw new ArgumentException(OAuthStrings.RequestUrlMustNotHaveOAuthParameters);
+ }
+
+ this.requestTokenEndpoint = value;
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the URL used to obtain User authorization for Consumer access,
+ /// described in Section 6.2 (Obtaining User Authorization).
+ /// </summary>
+ /// <remarks>
+ /// This is the URL that <see cref="OAuth.Messages.UserAuthorizationRequest"/> messages are
+ /// indirectly (via the user agent) sent to.
+ /// </remarks>
+ public MessageReceivingEndpoint UserAuthorizationEndpoint { get; set; }
+
+ /// <summary>
+ /// Gets or sets the URL used to exchange the User-authorized Request Token
+ /// for an Access Token, described in Section 6.3 (Obtaining an Access Token).
+ /// </summary>
+ /// <remarks>
+ /// This is the URL that <see cref="OAuth.Messages.AuthorizedTokenRequest"/> messages are directed to.
+ /// </remarks>
+ public MessageReceivingEndpoint AccessTokenEndpoint { get; set; }
+
+ /// <summary>
+ /// Gets or sets the signing policies that apply to this Service Provider.
+ /// </summary>
+ [SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays", Justification = "Type initializers require this format.")]
+ public ITamperProtectionChannelBindingElement[] TamperProtectionElements { get; set; }
+
+ /// <summary>
+ /// Gets the OAuth version supported by the Service Provider.
+ /// </summary>
+ internal Version Version {
+ get { return Protocol.Lookup(this.ProtocolVersion).Version; }
+ }
+
+ /// <summary>
+ /// Creates a signing element that includes all the signing elements this service provider supports.
+ /// </summary>
+ /// <returns>The created signing element.</returns>
+ internal ITamperProtectionChannelBindingElement CreateTamperProtectionElement() {
+ RequiresEx.ValidState(this.TamperProtectionElements != null);
+ return new SigningBindingElementChain(this.TamperProtectionElements.Select(el => (ITamperProtectionChannelBindingElement)el.Clone()).ToArray());
+ }
+ }
+}
diff --git a/src/DotNetOpenAuth.OAuth.ServiceProvider/OAuthReporting.cs b/src/DotNetOpenAuth.OAuth.ServiceProvider/OAuthReporting.cs
new file mode 100644
index 0000000..5b00c1a
--- /dev/null
+++ b/src/DotNetOpenAuth.OAuth.ServiceProvider/OAuthReporting.cs
@@ -0,0 +1,54 @@
+//-----------------------------------------------------------------------
+// <copyright file="OAuthReporting.cs" company="Outercurve Foundation">
+// Copyright (c) Outercurve Foundation. All rights reserved.
+// </copyright>
+//-----------------------------------------------------------------------
+
+namespace DotNetOpenAuth {
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+ using System.Text;
+ using DotNetOpenAuth.Messaging.Bindings;
+ using DotNetOpenAuth.OAuth;
+ using DotNetOpenAuth.OAuth.ChannelElements;
+ using Validation;
+
+ /// <summary>
+ /// Utility methods specific to OAuth feature reporting.
+ /// </summary>
+ internal class OAuthReporting : Reporting {
+ /// <summary>
+ /// Records the feature and dependency use.
+ /// </summary>
+ /// <param name="value">The consumer or service provider.</param>
+ /// <param name="service">The service.</param>
+ /// <param name="tokenManager">The token manager.</param>
+ /// <param name="nonceStore">The nonce store.</param>
+ internal static void RecordFeatureAndDependencyUse(object value, ServiceProviderHostDescription service, ITokenManager tokenManager, INonceStore nonceStore) {
+ Requires.NotNull(value, "value");
+ Requires.NotNull(service, "service");
+ Requires.NotNull(tokenManager, "tokenManager");
+
+ // In release builds, just quietly return.
+ if (value == null || service == null || tokenManager == null) {
+ return;
+ }
+
+ if (Reporting.Enabled && Reporting.Configuration.IncludeFeatureUsage) {
+ StringBuilder builder = new StringBuilder();
+ builder.Append(value.GetType().Name);
+ builder.Append(" ");
+ builder.Append(tokenManager.GetType().Name);
+ if (nonceStore != null) {
+ builder.Append(" ");
+ builder.Append(nonceStore.GetType().Name);
+ }
+ builder.Append(" ");
+ builder.Append(service.UserAuthorizationEndpoint != null ? service.UserAuthorizationEndpoint.Location.AbsoluteUri : string.Empty);
+ Reporting.ObservedFeatures.Add(builder.ToString());
+ Reporting.Touch();
+ }
+ }
+ }
+}
diff --git a/src/DotNetOpenAuth.OAuth.ServiceProvider/Properties/AssemblyInfo.cs b/src/DotNetOpenAuth.OAuth.ServiceProvider/Properties/AssemblyInfo.cs
index aa99a01..63af312 100644
--- a/src/DotNetOpenAuth.OAuth.ServiceProvider/Properties/AssemblyInfo.cs
+++ b/src/DotNetOpenAuth.OAuth.ServiceProvider/Properties/AssemblyInfo.cs
@@ -7,7 +7,6 @@
// We DON'T put an AssemblyVersionAttribute in here because it is generated in the build.
using System;
-using System.Diagnostics.Contracts;
using System.Net;
using System.Reflection;
using System.Resources;
@@ -31,8 +30,6 @@ using System.Web.UI;
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("7d73990c-47c0-4256-9f20-a893add9e289")]
-[assembly: ContractVerification(true)]
-
#if StrongNameSigned
// See comment at top of this file. We need this so that strong-naming doesn't
// keep this assembly from being useful to shared host (medium trust) web sites.
diff --git a/src/DotNetOpenAuth.OAuth.ServiceProvider/packages.config b/src/DotNetOpenAuth.OAuth.ServiceProvider/packages.config
new file mode 100644
index 0000000..d32d62f
--- /dev/null
+++ b/src/DotNetOpenAuth.OAuth.ServiceProvider/packages.config
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<packages>
+ <package id="Microsoft.Net.Http" version="2.0.20710.0" targetFramework="net45" />
+ <package id="Validation" version="2.0.2.13022" targetFramework="net45" />
+</packages> \ No newline at end of file