diff options
19 files changed, 144 insertions, 127 deletions
diff --git a/src/DotNetOpenAuth.AspNet/Clients/OAuth/DotNetOpenAuthWebConsumer.cs b/src/DotNetOpenAuth.AspNet/Clients/OAuth/DotNetOpenAuthWebConsumer.cs index e216906..2a67dab 100644 --- a/src/DotNetOpenAuth.AspNet/Clients/OAuth/DotNetOpenAuthWebConsumer.cs +++ b/src/DotNetOpenAuth.AspNet/Clients/OAuth/DotNetOpenAuthWebConsumer.cs @@ -8,6 +8,9 @@ namespace DotNetOpenAuth.AspNet.Clients { using System; using System.Collections.Generic; using System.Net; + using System.Net.Http; + using System.Threading; + using System.Threading.Tasks; using DotNetOpenAuth.Messaging; using DotNetOpenAuth.OAuth; using DotNetOpenAuth.OAuth.ChannelElements; @@ -59,16 +62,16 @@ namespace DotNetOpenAuth.AspNet.Clients { /// The access token. /// </param> /// <returns>An HTTP request.</returns> - public HttpWebRequest PrepareAuthorizedRequest(MessageReceivingEndpoint profileEndpoint, string accessToken) { - return this.webConsumer.PrepareAuthorizedRequest(profileEndpoint, accessToken); + public Task<HttpRequestMessage> PrepareAuthorizedRequestAsync(MessageReceivingEndpoint profileEndpoint, string accessToken, CancellationToken cancellationToken = default(CancellationToken)) { + return this.webConsumer.PrepareAuthorizedRequestAsync(profileEndpoint, accessToken, cancellationToken); } /// <summary> /// The process user authorization. /// </summary> /// <returns>The response message.</returns> - public AuthorizedTokenResponse ProcessUserAuthorization() { - return this.webConsumer.ProcessUserAuthorization(); + public Task<AuthorizedTokenResponse> ProcessUserAuthorizationAsync(CancellationToken cancellationToken = default(CancellationToken)) { + return this.webConsumer.ProcessUserAuthorizationAsync(cancellationToken: cancellationToken); } /// <summary> @@ -77,11 +80,12 @@ namespace DotNetOpenAuth.AspNet.Clients { /// <param name="callback"> /// The callback. /// </param> - public void RequestAuthentication(Uri callback) { + public async Task<HttpResponseMessage> RequestAuthenticationAsync(Uri callback, CancellationToken cancellationToken = default(CancellationToken)) { var redirectParameters = new Dictionary<string, string>(); - UserAuthorizationRequest request = this.webConsumer.PrepareRequestUserAuthorization( - callback, null, redirectParameters); - this.webConsumer.Channel.PrepareResponse(request).Send(); + UserAuthorizationRequest request = await this.webConsumer.PrepareRequestUserAuthorizationAsync( + callback, null, redirectParameters, cancellationToken); + var response = await this.webConsumer.Channel.PrepareResponseAsync(request, cancellationToken); + return response; } #endregion diff --git a/src/DotNetOpenAuth.AspNet/Clients/OAuth/IOAuthWebWorker.cs b/src/DotNetOpenAuth.AspNet/Clients/OAuth/IOAuthWebWorker.cs index a054a1c..9651f52 100644 --- a/src/DotNetOpenAuth.AspNet/Clients/OAuth/IOAuthWebWorker.cs +++ b/src/DotNetOpenAuth.AspNet/Clients/OAuth/IOAuthWebWorker.cs @@ -7,6 +7,9 @@ namespace DotNetOpenAuth.AspNet.Clients { using System; using System.Net; + using System.Net.Http; + using System.Threading; + using System.Threading.Tasks; using DotNetOpenAuth.Messaging; using DotNetOpenAuth.OAuth.Messages; @@ -26,13 +29,13 @@ namespace DotNetOpenAuth.AspNet.Clients { /// The access token. /// </param> /// <returns>An HTTP request.</returns> - HttpWebRequest PrepareAuthorizedRequest(MessageReceivingEndpoint profileEndpoint, string accessToken); + Task<HttpRequestMessage> PrepareAuthorizedRequestAsync(MessageReceivingEndpoint profileEndpoint, string accessToken, CancellationToken cancellationToken = default(CancellationToken)); /// <summary> /// The process user authorization. /// </summary> /// <returns>The response message.</returns> - AuthorizedTokenResponse ProcessUserAuthorization(); + Task<AuthorizedTokenResponse> ProcessUserAuthorizationAsync(CancellationToken cancellationToken = default(CancellationToken)); /// <summary> /// The request authentication. @@ -40,7 +43,7 @@ namespace DotNetOpenAuth.AspNet.Clients { /// <param name="callback"> /// The callback. /// </param> - void RequestAuthentication(Uri callback); + Task<HttpResponseMessage> RequestAuthenticationAsync(Uri callback, CancellationToken cancellationToken = default(CancellationToken)); #endregion } diff --git a/src/DotNetOpenAuth.AspNet/Clients/OAuth/LinkedInClient.cs b/src/DotNetOpenAuth.AspNet/Clients/OAuth/LinkedInClient.cs index 3c157f3..365b4c1 100644 --- a/src/DotNetOpenAuth.AspNet/Clients/OAuth/LinkedInClient.cs +++ b/src/DotNetOpenAuth.AspNet/Clients/OAuth/LinkedInClient.cs @@ -10,6 +10,9 @@ namespace DotNetOpenAuth.AspNet.Clients { using System.Diagnostics.CodeAnalysis; using System.IO; using System.Net; + using System.Net.Http; + using System.Threading; + using System.Threading.Tasks; using System.Xml.Linq; using DotNetOpenAuth.Messaging; using DotNetOpenAuth.OAuth; @@ -87,34 +90,40 @@ namespace DotNetOpenAuth.AspNet.Clients { /// </returns> [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "We don't care if the request fails.")] - protected override AuthenticationResult VerifyAuthenticationCore(AuthorizedTokenResponse response) { + protected override async Task<AuthenticationResult> VerifyAuthenticationCoreAsync(AuthorizedTokenResponse response, CancellationToken cancellationToken = default(CancellationToken)) { // See here for Field Selectors API http://developer.linkedin.com/docs/DOC-1014 const string ProfileRequestUrl = "https://api.linkedin.com/v1/people/~:(id,first-name,last-name,headline,industry,summary)"; string accessToken = response.AccessToken; var profileEndpoint = new MessageReceivingEndpoint(ProfileRequestUrl, HttpDeliveryMethods.GetRequest); - HttpWebRequest request = this.WebWorker.PrepareAuthorizedRequest(profileEndpoint, accessToken); + HttpRequestMessage request = await this.WebWorker.PrepareAuthorizedRequestAsync(profileEndpoint, accessToken, cancellationToken); try { - using (WebResponse profileResponse = request.GetResponse()) { - using (Stream responseStream = profileResponse.GetResponseStream()) { - XDocument document = LoadXDocumentFromStream(responseStream); - string userId = document.Root.Element("id").Value; - - string firstName = document.Root.Element("first-name").Value; - string lastName = document.Root.Element("last-name").Value; - string userName = firstName + " " + lastName; - - var extraData = new Dictionary<string, string>(); - extraData.Add("accesstoken", accessToken); - extraData.Add("name", userName); - extraData.AddDataIfNotEmpty(document, "headline"); - extraData.AddDataIfNotEmpty(document, "summary"); - extraData.AddDataIfNotEmpty(document, "industry"); - - return new AuthenticationResult( - isSuccessful: true, provider: this.ProviderName, providerUserId: userId, userName: userName, extraData: extraData); + using(var httpClient = new HttpClient()) { + using (HttpResponseMessage profileResponse = await httpClient.SendAsync(request, cancellationToken)) { + using (Stream responseStream = await profileResponse.Content.ReadAsStreamAsync()) { + XDocument document = LoadXDocumentFromStream(responseStream); + string userId = document.Root.Element("id").Value; + + string firstName = document.Root.Element("first-name").Value; + string lastName = document.Root.Element("last-name").Value; + string userName = firstName + " " + lastName; + + var extraData = new Dictionary<string, string>(); + extraData.Add("accesstoken", accessToken); + extraData.Add("name", userName); + extraData.AddDataIfNotEmpty(document, "headline"); + extraData.AddDataIfNotEmpty(document, "summary"); + extraData.AddDataIfNotEmpty(document, "industry"); + + return new AuthenticationResult( + isSuccessful: true, + provider: this.ProviderName, + providerUserId: userId, + userName: userName, + extraData: extraData); + } } } } diff --git a/src/DotNetOpenAuth.AspNet/Clients/OAuth/OAuthClient.cs b/src/DotNetOpenAuth.AspNet/Clients/OAuth/OAuthClient.cs index a0afeca..dd48bf6 100644 --- a/src/DotNetOpenAuth.AspNet/Clients/OAuth/OAuthClient.cs +++ b/src/DotNetOpenAuth.AspNet/Clients/OAuth/OAuthClient.cs @@ -9,6 +9,8 @@ namespace DotNetOpenAuth.AspNet.Clients { using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.IO; + using System.Threading; + using System.Threading.Tasks; using System.Web; using System.Xml; using System.Xml.Linq; @@ -109,12 +111,12 @@ namespace DotNetOpenAuth.AspNet.Clients { /// <param name="returnUrl"> /// The return url after users have completed authenticating against external website. /// </param> - public virtual void RequestAuthentication(HttpContextBase context, Uri returnUrl) { + public virtual Task RequestAuthenticationAsync(HttpContextBase context, Uri returnUrl, CancellationToken cancellationToken = default(CancellationToken)) { Requires.NotNull(returnUrl, "returnUrl"); Requires.NotNull(context, "context"); Uri callback = returnUrl.StripQueryArgumentsWithPrefix("oauth_"); - this.WebWorker.RequestAuthentication(callback); + return this.WebWorker.RequestAuthenticationAsync(callback, cancellationToken); } /// <summary> @@ -126,13 +128,13 @@ namespace DotNetOpenAuth.AspNet.Clients { /// <returns> /// An instance of <see cref="AuthenticationResult"/> containing authentication result. /// </returns> - public virtual AuthenticationResult VerifyAuthentication(HttpContextBase context) { - AuthorizedTokenResponse response = this.WebWorker.ProcessUserAuthorization(); + public virtual async Task<AuthenticationResult> VerifyAuthenticationAsync(HttpContextBase context, CancellationToken cancellationToken = default(CancellationToken)) { + AuthorizedTokenResponse response = await this.WebWorker.ProcessUserAuthorizationAsync(cancellationToken); if (response == null) { return AuthenticationResult.Failed; } - AuthenticationResult result = this.VerifyAuthenticationCore(response); + AuthenticationResult result = await this.VerifyAuthenticationCoreAsync(response, cancellationToken); if (result.IsSuccessful && result.ExtraData != null) { // add the access token to the user data dictionary just in case page developers want to use it var wrapExtraData = result.ExtraData.IsReadOnly @@ -179,7 +181,7 @@ namespace DotNetOpenAuth.AspNet.Clients { /// <returns> /// Authentication result /// </returns> - protected abstract AuthenticationResult VerifyAuthenticationCore(AuthorizedTokenResponse response); + protected abstract Task<AuthenticationResult> VerifyAuthenticationCoreAsync(AuthorizedTokenResponse response, CancellationToken cancellationToken); #endregion } } diff --git a/src/DotNetOpenAuth.AspNet/Clients/OAuth/TwitterClient.cs b/src/DotNetOpenAuth.AspNet/Clients/OAuth/TwitterClient.cs index 886917a..c2dcf95 100644 --- a/src/DotNetOpenAuth.AspNet/Clients/OAuth/TwitterClient.cs +++ b/src/DotNetOpenAuth.AspNet/Clients/OAuth/TwitterClient.cs @@ -10,6 +10,9 @@ namespace DotNetOpenAuth.AspNet.Clients { using System.Diagnostics.CodeAnalysis; using System.IO; using System.Net; + using System.Net.Http; + using System.Threading; + using System.Threading.Tasks; using System.Xml.Linq; using DotNetOpenAuth.Messaging; using DotNetOpenAuth.OAuth; @@ -87,7 +90,7 @@ namespace DotNetOpenAuth.AspNet.Clients { /// </returns> [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "We don't care if the request for additional data fails.")] - protected override AuthenticationResult VerifyAuthenticationCore(AuthorizedTokenResponse response) { + protected override async Task<AuthenticationResult> VerifyAuthenticationCoreAsync(AuthorizedTokenResponse response, CancellationToken cancellationToken) { string accessToken = response.AccessToken; string userId = response.ExtraData["user_id"]; string userName = response.ExtraData["screen_name"]; @@ -95,18 +98,20 @@ namespace DotNetOpenAuth.AspNet.Clients { var profileRequestUrl = new Uri("https://api.twitter.com/1/users/show.xml?user_id=" + MessagingUtilities.EscapeUriDataStringRfc3986(userId)); var profileEndpoint = new MessageReceivingEndpoint(profileRequestUrl, HttpDeliveryMethods.GetRequest); - HttpWebRequest request = this.WebWorker.PrepareAuthorizedRequest(profileEndpoint, accessToken); + HttpRequestMessage request = await this.WebWorker.PrepareAuthorizedRequestAsync(profileEndpoint, accessToken, cancellationToken); var extraData = new Dictionary<string, string>(); extraData.Add("accesstoken", accessToken); try { - using (WebResponse profileResponse = request.GetResponse()) { - using (Stream responseStream = profileResponse.GetResponseStream()) { - XDocument document = LoadXDocumentFromStream(responseStream); - extraData.AddDataIfNotEmpty(document, "name"); - extraData.AddDataIfNotEmpty(document, "location"); - extraData.AddDataIfNotEmpty(document, "description"); - extraData.AddDataIfNotEmpty(document, "url"); + using (var httpClient = new HttpClient()) { + using (HttpResponseMessage profileResponse = await httpClient.SendAsync(request)) { + using (Stream responseStream = await profileResponse.Content.ReadAsStreamAsync()) { + XDocument document = LoadXDocumentFromStream(responseStream); + extraData.AddDataIfNotEmpty(document, "name"); + extraData.AddDataIfNotEmpty(document, "location"); + extraData.AddDataIfNotEmpty(document, "description"); + extraData.AddDataIfNotEmpty(document, "url"); + } } } } diff --git a/src/DotNetOpenAuth.AspNet/Clients/OAuth2/OAuth2Client.cs b/src/DotNetOpenAuth.AspNet/Clients/OAuth2/OAuth2Client.cs index 014f459..60f6a5e 100644 --- a/src/DotNetOpenAuth.AspNet/Clients/OAuth2/OAuth2Client.cs +++ b/src/DotNetOpenAuth.AspNet/Clients/OAuth2/OAuth2Client.cs @@ -8,6 +8,8 @@ namespace DotNetOpenAuth.AspNet.Clients { using System; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; + using System.Threading; + using System.Threading.Tasks; using System.Web; using Validation; @@ -63,7 +65,7 @@ namespace DotNetOpenAuth.AspNet.Clients { /// <param name="returnUrl"> /// The return url after users have completed authenticating against external website. /// </param> - public virtual void RequestAuthentication(HttpContextBase context, Uri returnUrl) { + public virtual async Task RequestAuthenticationAsync(HttpContextBase context, Uri returnUrl, CancellationToken cancellationToken = default(CancellationToken)) { Requires.NotNull(context, "context"); Requires.NotNull(returnUrl, "returnUrl"); @@ -80,7 +82,7 @@ namespace DotNetOpenAuth.AspNet.Clients { /// <returns> /// An instance of <see cref="AuthenticationResult"/> containing authentication result. /// </returns> - public AuthenticationResult VerifyAuthentication(HttpContextBase context) { + public Task<AuthenticationResult> VerifyAuthenticationAsync(HttpContextBase context, CancellationToken cancellationToken = default(CancellationToken)) { throw new InvalidOperationException(WebResources.OAuthRequireReturnUrl); } @@ -92,7 +94,7 @@ namespace DotNetOpenAuth.AspNet.Clients { /// <returns> /// An instance of <see cref="AuthenticationResult"/> containing authentication result. /// </returns> - public virtual AuthenticationResult VerifyAuthentication(HttpContextBase context, Uri returnPageUrl) { + public virtual async Task<AuthenticationResult> VerifyAuthenticationAsync(HttpContextBase context, Uri returnPageUrl, CancellationToken cancellationToken = default(CancellationToken)) { Requires.NotNull(context, "context"); string code = context.Request.QueryString["code"]; diff --git a/src/DotNetOpenAuth.AspNet/Clients/OpenID/OpenIDClient.cs b/src/DotNetOpenAuth.AspNet/Clients/OpenID/OpenIDClient.cs index a41b504..741b51b 100644 --- a/src/DotNetOpenAuth.AspNet/Clients/OpenID/OpenIDClient.cs +++ b/src/DotNetOpenAuth.AspNet/Clients/OpenID/OpenIDClient.cs @@ -8,6 +8,8 @@ namespace DotNetOpenAuth.AspNet.Clients { using System; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; + using System.Threading; + using System.Threading.Tasks; using System.Web; using DotNetOpenAuth.Messaging; using DotNetOpenAuth.OpenId; @@ -87,16 +89,16 @@ namespace DotNetOpenAuth.AspNet.Clients { /// </param> [SuppressMessage("Microsoft.Usage", "CA2234:PassSystemUriObjectsInsteadOfStrings", Justification = "We don't have a Uri object handy.")] - public virtual void RequestAuthentication(HttpContextBase context, Uri returnUrl) { + public virtual async Task RequestAuthenticationAsync(HttpContextBase context, Uri returnUrl, CancellationToken cancellationToken = default(CancellationToken)) { Requires.NotNull(returnUrl, "returnUrl"); var realm = new Realm(returnUrl.GetComponents(UriComponents.SchemeAndServer, UriFormat.Unescaped)); - IAuthenticationRequest request = RelyingParty.CreateRequest(this.providerIdentifier, realm, returnUrl); + IAuthenticationRequest request = await RelyingParty.CreateRequestAsync(this.providerIdentifier, realm, returnUrl, cancellationToken); // give subclasses a chance to modify request message, e.g. add extension attributes, etc. this.OnBeforeSendingAuthenticationRequest(request); - request.RedirectToProvider(); + await request.RedirectToProviderAsync(context); } /// <summary> @@ -108,8 +110,8 @@ namespace DotNetOpenAuth.AspNet.Clients { /// <returns> /// An instance of <see cref="AuthenticationResult"/> containing authentication result. /// </returns> - public virtual AuthenticationResult VerifyAuthentication(HttpContextBase context) { - IAuthenticationResponse response = RelyingParty.GetResponse(); + public virtual async Task<AuthenticationResult> VerifyAuthenticationAsync(HttpContextBase context, CancellationToken cancellationToken = default(CancellationToken)) { + IAuthenticationResponse response = await RelyingParty.GetResponseAsync(context.Request, cancellationToken); if (response == null) { throw new InvalidOperationException(WebResources.OpenIDFailedToGetResponse); } diff --git a/src/DotNetOpenAuth.AspNet/DotNetOpenAuth.AspNet.csproj b/src/DotNetOpenAuth.AspNet/DotNetOpenAuth.AspNet.csproj index 16229c7..f7c8368 100644 --- a/src/DotNetOpenAuth.AspNet/DotNetOpenAuth.AspNet.csproj +++ b/src/DotNetOpenAuth.AspNet/DotNetOpenAuth.AspNet.csproj @@ -32,6 +32,8 @@ <ItemGroup> <Reference Include="System" /> <Reference Include="System.Core" /> + <Reference Include="System.Net.Http" /> + <Reference Include="System.Net.Http.WebRequest" /> <Reference Include="System.Runtime.Serialization" /> <Reference Include="System.Web" /> <Reference Include="System.Xml.Linq" /> diff --git a/src/DotNetOpenAuth.AspNet/IAuthenticationClient.cs b/src/DotNetOpenAuth.AspNet/IAuthenticationClient.cs index 4d9acde..bca32c6 100644 --- a/src/DotNetOpenAuth.AspNet/IAuthenticationClient.cs +++ b/src/DotNetOpenAuth.AspNet/IAuthenticationClient.cs @@ -6,6 +6,8 @@ namespace DotNetOpenAuth.AspNet { using System; + using System.Threading; + using System.Threading.Tasks; using System.Web; /// <summary> @@ -26,7 +28,7 @@ namespace DotNetOpenAuth.AspNet { /// <param name="returnUrl"> /// The return url after users have completed authenticating against external website. /// </param> - void RequestAuthentication(HttpContextBase context, Uri returnUrl); + Task RequestAuthenticationAsync(HttpContextBase context, Uri returnUrl, CancellationToken cancellationToken = default(CancellationToken)); /// <summary> /// Check if authentication succeeded after user is redirected back from the service provider. @@ -37,6 +39,6 @@ namespace DotNetOpenAuth.AspNet { /// <returns> /// An instance of <see cref="AuthenticationResult"/> containing authentication result. /// </returns> - AuthenticationResult VerifyAuthentication(HttpContextBase context); + Task<AuthenticationResult> VerifyAuthenticationAsync(HttpContextBase context, CancellationToken cancellationToken = default(CancellationToken)); } } diff --git a/src/DotNetOpenAuth.AspNet/OpenAuthSecurityManager.cs b/src/DotNetOpenAuth.AspNet/OpenAuthSecurityManager.cs index 6736205..794ba10 100644 --- a/src/DotNetOpenAuth.AspNet/OpenAuthSecurityManager.cs +++ b/src/DotNetOpenAuth.AspNet/OpenAuthSecurityManager.cs @@ -8,6 +8,8 @@ namespace DotNetOpenAuth.AspNet { using System; using System.Diagnostics.CodeAnalysis; using System.Text; + using System.Threading; + using System.Threading.Tasks; using System.Web; using System.Web.Security; using DotNetOpenAuth.AspNet.Clients; @@ -144,7 +146,7 @@ namespace DotNetOpenAuth.AspNet { /// <param name="returnUrl"> /// The return url after user is authenticated. /// </param> - public void RequestAuthentication(string returnUrl) { + public async Task RequestAuthenticationAsync(string returnUrl, CancellationToken cancellationToken = default(CancellationToken)) { // convert returnUrl to an absolute path Uri uri; if (!string.IsNullOrEmpty(returnUrl)) { @@ -176,7 +178,7 @@ namespace DotNetOpenAuth.AspNet { this.requestContext.Response.Cookies.Add(xsrfCookie); // issue the redirect to the external auth provider - this.authenticationProvider.RequestAuthentication(this.requestContext, uri); + await this.authenticationProvider.RequestAuthenticationAsync(this.requestContext, uri, cancellationToken); } /// <summary> @@ -189,7 +191,7 @@ namespace DotNetOpenAuth.AspNet { /// <returns> /// The result of the authentication. /// </returns> - public AuthenticationResult VerifyAuthentication(string returnUrl) { + public async Task<AuthenticationResult> VerifyAuthenticationAsync(string returnUrl, CancellationToken cancellationToken = default(CancellationToken)) { // check for XSRF attack string sessionId; bool successful = this.ValidateRequestAgainstXsrfAttack(out sessionId); @@ -223,7 +225,7 @@ namespace DotNetOpenAuth.AspNet { uri = uri.AttachQueryStringParameter(SessionIdQueryStringName, sessionId); try { - AuthenticationResult result = oauth2Client.VerifyAuthentication(this.requestContext, uri); + AuthenticationResult result = await oauth2Client.VerifyAuthenticationAsync(this.requestContext, uri, cancellationToken); if (!result.IsSuccessful) { // if the result is a Failed result, creates a new Failed response which has providerName info. result = new AuthenticationResult( @@ -241,7 +243,7 @@ namespace DotNetOpenAuth.AspNet { } } else { - return this.authenticationProvider.VerifyAuthentication(this.requestContext); + return await this.authenticationProvider.VerifyAuthenticationAsync(this.requestContext, cancellationToken); } } diff --git a/src/DotNetOpenAuth.AspNet/packages.config b/src/DotNetOpenAuth.AspNet/packages.config index 58890d8..1d93cf5 100644 --- a/src/DotNetOpenAuth.AspNet/packages.config +++ b/src/DotNetOpenAuth.AspNet/packages.config @@ -1,4 +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.1.12362" targetFramework="net45" /> </packages>
\ No newline at end of file diff --git a/src/DotNetOpenAuth.OAuth.Consumer/OAuth/ConsumerBase.cs b/src/DotNetOpenAuth.OAuth.Consumer/OAuth/ConsumerBase.cs index 0d2da87..b34d4f8 100644 --- a/src/DotNetOpenAuth.OAuth.Consumer/OAuth/ConsumerBase.cs +++ b/src/DotNetOpenAuth.OAuth.Consumer/OAuth/ConsumerBase.cs @@ -10,6 +10,9 @@ namespace DotNetOpenAuth.OAuth { using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Net; + using System.Net.Http; + using System.Threading; + using System.Threading.Tasks; using DotNetOpenAuth.Configuration; using DotNetOpenAuth.Messaging; using DotNetOpenAuth.Messaging.Bindings; @@ -83,7 +86,7 @@ namespace DotNetOpenAuth.OAuth { /// <remarks> /// The token secret is stored in the <see cref="TokenManager"/>. /// </remarks> - public string RequestNewClientAccount(IDictionary<string, string> requestParameters = null) { + public async Task<string> RequestNewClientAccountAsync(IDictionary<string, string> requestParameters = null, CancellationToken cancellationToken = default(CancellationToken)) { // Obtain an unauthorized request token. Force use of OAuth 1.0 (not 1.0a) so that // we are not expected to provide an oauth_verifier which doesn't apply in 2-legged OAuth. var token = new UnauthorizedTokenRequest(this.ServiceProvider.RequestTokenEndpoint, Protocol.V10.Version) { @@ -91,14 +94,14 @@ namespace DotNetOpenAuth.OAuth { }; var tokenAccessor = this.Channel.MessageDescriptions.GetAccessor(token); tokenAccessor.AddExtraParameters(requestParameters); - var requestTokenResponse = this.Channel.Request<UnauthorizedTokenResponse>(token); + var requestTokenResponse = await this.Channel.RequestAsync<UnauthorizedTokenResponse>(token, cancellationToken); this.TokenManager.StoreNewRequestToken(token, requestTokenResponse); var requestAccess = new AuthorizedTokenRequest(this.ServiceProvider.AccessTokenEndpoint, Protocol.V10.Version) { RequestToken = requestTokenResponse.RequestToken, ConsumerKey = this.ConsumerKey, }; - var grantAccess = this.Channel.Request<AuthorizedTokenResponse>(requestAccess); + var grantAccess = await this.Channel.RequestAsync<AuthorizedTokenResponse>(requestAccess, cancellationToken); this.TokenManager.ExpireRequestTokenAndStoreNewAccessToken(this.ConsumerKey, requestTokenResponse.RequestToken, grantAccess.AccessToken, grantAccess.TokenSecret); return grantAccess.AccessToken; } @@ -110,11 +113,11 @@ namespace DotNetOpenAuth.OAuth { /// <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 HttpWebRequest PrepareAuthorizedRequest(MessageReceivingEndpoint endpoint, string accessToken) { + public Task<HttpRequestMessage> PrepareAuthorizedRequestAsync(MessageReceivingEndpoint endpoint, string accessToken, CancellationToken cancellationToken = default(CancellationToken)) { Requires.NotNull(endpoint, "endpoint"); Requires.NotNullOrEmpty(accessToken, "accessToken"); - return this.PrepareAuthorizedRequest(endpoint, accessToken, EmptyDictionary<string, string>.Instance); + return this.PrepareAuthorizedRequestAsync(endpoint, accessToken, EmptyDictionary<string, string>.Instance, cancellationToken); } /// <summary> @@ -125,7 +128,7 @@ namespace DotNetOpenAuth.OAuth { /// <param name="accessToken">The access token that permits access to the protected resource.</param> /// <param name="extraData">Extra parameters to include in the message. Must not be null, but may be empty.</param> /// <returns>The initialized WebRequest object.</returns> - public HttpWebRequest PrepareAuthorizedRequest(MessageReceivingEndpoint endpoint, string accessToken, IDictionary<string, string> extraData) { + public Task<HttpRequestMessage> PrepareAuthorizedRequestAsync(MessageReceivingEndpoint endpoint, string accessToken, IDictionary<string, string> extraData, CancellationToken cancellationToken = default(CancellationToken)) { Requires.NotNull(endpoint, "endpoint"); Requires.NotNullOrEmpty(accessToken, "accessToken"); Requires.NotNull(extraData, "extraData"); @@ -135,8 +138,7 @@ namespace DotNetOpenAuth.OAuth { message.ExtraData.Add(pair); } - HttpWebRequest wr = this.OAuthChannel.InitializeRequest(message); - return wr; + return this.OAuthChannel.InitializeRequestAsync(message, cancellationToken); } /// <summary> @@ -146,18 +148,17 @@ namespace DotNetOpenAuth.OAuth { /// <param name="accessToken">The access token that permits access to the protected resource.</param> /// <param name="binaryData">Extra parameters to include in the message. Must not be null, but may be empty.</param> /// <returns>The initialized WebRequest object.</returns> - public HttpWebRequest PrepareAuthorizedRequest(MessageReceivingEndpoint endpoint, string accessToken, IEnumerable<MultipartPostPart> binaryData) { + public Task<HttpRequestMessage> PrepareAuthorizedRequestAsync(MessageReceivingEndpoint endpoint, string accessToken, IDictionary<string, HttpContent> binaryData, CancellationToken cancellationToken = default(CancellationToken)) { Requires.NotNull(endpoint, "endpoint"); Requires.NotNullOrEmpty(accessToken, "accessToken"); Requires.NotNull(binaryData, "binaryData"); AccessProtectedResourceRequest message = this.CreateAuthorizingMessage(endpoint, accessToken); - foreach (MultipartPostPart part in binaryData) { + foreach (var part in binaryData) { message.BinaryData.Add(part); } - HttpWebRequest wr = this.OAuthChannel.InitializeRequest(message); - return wr; + return this.OAuthChannel.InitializeRequestAsync(message, cancellationToken); } /// <summary> @@ -176,23 +177,9 @@ namespace DotNetOpenAuth.OAuth { /// if and only if the <see cref="IMessage.ExtraData"/> dictionary is non-empty. /// </remarks> [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters", Justification = "Type of parameter forces the method to apply only to specific scenario.")] - public HttpWebRequest PrepareAuthorizedRequest(AccessProtectedResourceRequest message) { + public Task<HttpRequestMessage> PrepareAuthorizedRequestAsync(AccessProtectedResourceRequest message, CancellationToken cancellationToken = default(CancellationToken)) { Requires.NotNull(message, "message"); - return this.OAuthChannel.InitializeRequest(message); - } - - /// <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 IncomingWebResponse PrepareAuthorizedRequestAndSend(MessageReceivingEndpoint endpoint, string accessToken) { - IDirectedProtocolMessage message = this.CreateAuthorizingMessage(endpoint, accessToken); - HttpWebRequest wr = this.OAuthChannel.InitializeRequest(message); - return this.Channel.WebRequestHandler.GetResponse(wr); + return this.OAuthChannel.InitializeRequestAsync(message, cancellationToken); } #region IDisposable Members @@ -239,7 +226,7 @@ namespace DotNetOpenAuth.OAuth { /// <param name="requestToken">The request token that must be exchanged for an access token after the user has provided authorization.</param> /// <returns>The pending user agent redirect based message to be sent as an HttpResponse.</returns> [SuppressMessage("Microsoft.Design", "CA1021:AvoidOutParameters", MessageId = "3#", Justification = "Two results")] - protected internal UserAuthorizationRequest PrepareRequestUserAuthorization(Uri callback, IDictionary<string, string> requestParameters, IDictionary<string, string> redirectParameters, out string requestToken) { + protected internal async Task<UserAuthorizationRequest> PrepareRequestUserAuthorizationAsync(Uri callback, IDictionary<string, string> requestParameters, IDictionary<string, string> redirectParameters, CancellationToken cancellationToken = default(CancellationToken)) { // Obtain an unauthorized request token. Assume the OAuth version given in the service description. var token = new UnauthorizedTokenRequest(this.ServiceProvider.RequestTokenEndpoint, this.ServiceProvider.Version) { ConsumerKey = this.ConsumerKey, @@ -247,7 +234,7 @@ namespace DotNetOpenAuth.OAuth { }; var tokenAccessor = this.Channel.MessageDescriptions.GetAccessor(token); tokenAccessor.AddExtraParameters(requestParameters); - var requestTokenResponse = this.Channel.Request<UnauthorizedTokenResponse>(token); + var requestTokenResponse = await this.Channel.RequestAsync<UnauthorizedTokenResponse>(token, cancellationToken); this.TokenManager.StoreNewRequestToken(token, requestTokenResponse); // Fine-tune our understanding of the SP's supported OAuth version if it's wrong. @@ -264,7 +251,6 @@ namespace DotNetOpenAuth.OAuth { }; var requestAuthorizationAccessor = this.Channel.MessageDescriptions.GetAccessor(requestAuthorization); requestAuthorizationAccessor.AddExtraParameters(redirectParameters); - requestToken = requestAuthorization.RequestToken; return requestAuthorization; } @@ -276,7 +262,7 @@ namespace DotNetOpenAuth.OAuth { /// <returns> /// The access token assigned by the Service Provider. /// </returns> - protected AuthorizedTokenResponse ProcessUserAuthorization(string requestToken, string verifier) { + protected async Task<AuthorizedTokenResponse> ProcessUserAuthorizationAsync(string requestToken, string verifier, CancellationToken cancellationToken = default(CancellationToken)) { Requires.NotNullOrEmpty(requestToken, "requestToken"); var requestAccess = new AuthorizedTokenRequest(this.ServiceProvider.AccessTokenEndpoint, this.ServiceProvider.Version) { @@ -284,7 +270,7 @@ namespace DotNetOpenAuth.OAuth { VerificationCode = verifier, ConsumerKey = this.ConsumerKey, }; - var grantAccess = this.Channel.Request<AuthorizedTokenResponse>(requestAccess); + var grantAccess = await this.Channel.RequestAsync<AuthorizedTokenResponse>(requestAccess, cancellationToken); this.TokenManager.ExpireRequestTokenAndStoreNewAccessToken(this.ConsumerKey, requestToken, grantAccess.AccessToken, grantAccess.TokenSecret); return grantAccess; } diff --git a/src/DotNetOpenAuth.OAuth.Consumer/OAuth/DesktopConsumer.cs b/src/DotNetOpenAuth.OAuth.Consumer/OAuth/DesktopConsumer.cs index fe6020e..4627d23 100644 --- a/src/DotNetOpenAuth.OAuth.Consumer/OAuth/DesktopConsumer.cs +++ b/src/DotNetOpenAuth.OAuth.Consumer/OAuth/DesktopConsumer.cs @@ -8,6 +8,8 @@ namespace DotNetOpenAuth.OAuth { using System; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; + using System.Threading; + using System.Threading.Tasks; using DotNetOpenAuth.Messaging; using DotNetOpenAuth.OAuth; using DotNetOpenAuth.OAuth.ChannelElements; @@ -38,10 +40,10 @@ namespace DotNetOpenAuth.OAuth { /// <param name="requestToken">The request token that must be exchanged for an access token after the user has provided authorization.</param> /// <returns>The URL to open a browser window to allow the user to provide authorization.</returns> [SuppressMessage("Microsoft.Design", "CA1021:AvoidOutParameters", MessageId = "2#", Justification = "Two results")] - public Uri RequestUserAuthorization(IDictionary<string, string> requestParameters, IDictionary<string, string> redirectParameters, out string requestToken) { - var message = this.PrepareRequestUserAuthorization(null, requestParameters, redirectParameters, out requestToken); - OutgoingWebResponse response = this.Channel.PrepareResponse(message); - return response.GetDirectUriRequest(this.Channel); + public async Task<Tuple<Uri, string>> RequestUserAuthorizationAsync(IDictionary<string, string> requestParameters, IDictionary<string, string> redirectParameters, CancellationToken cancellationToken = default(CancellationToken)) { + var message = await this.PrepareRequestUserAuthorizationAsync(null, requestParameters, redirectParameters, cancellationToken); + var response = await this.Channel.PrepareResponseAsync(message, cancellationToken); + return Tuple.Create(response.GetDirectUriRequest(), message.RequestToken); } /// <summary> @@ -50,8 +52,8 @@ namespace DotNetOpenAuth.OAuth { /// <param name="requestToken">The request token that the user has authorized.</param> /// <returns>The access token assigned by the Service Provider.</returns> [Obsolete("Use the ProcessUserAuthorization method that takes a verifier parameter instead.")] - public AuthorizedTokenResponse ProcessUserAuthorization(string requestToken) { - return this.ProcessUserAuthorization(requestToken, null); + public Task<AuthorizedTokenResponse> ProcessUserAuthorizationAsync(string requestToken, CancellationToken cancellationToken = default(CancellationToken)) { + return this.ProcessUserAuthorizationAsync(requestToken, null, cancellationToken); } /// <summary> @@ -62,12 +64,12 @@ namespace DotNetOpenAuth.OAuth { /// <returns> /// The access token assigned by the Service Provider. /// </returns> - public new AuthorizedTokenResponse ProcessUserAuthorization(string requestToken, string verifier) { + public new Task<AuthorizedTokenResponse> ProcessUserAuthorizationAsync(string requestToken, string verifier, CancellationToken cancellationToken = default(CancellationToken)) { if (this.ServiceProvider.Version >= Protocol.V10a.Version) { ErrorUtilities.VerifyNonZeroLength(verifier, "verifier"); } - return base.ProcessUserAuthorization(requestToken, verifier); + return base.ProcessUserAuthorizationAsync(requestToken, verifier, cancellationToken); } } } diff --git a/src/DotNetOpenAuth.OAuth.Consumer/OAuth/WebConsumer.cs b/src/DotNetOpenAuth.OAuth.Consumer/OAuth/WebConsumer.cs index 4d4e67c..da395b0 100644 --- a/src/DotNetOpenAuth.OAuth.Consumer/OAuth/WebConsumer.cs +++ b/src/DotNetOpenAuth.OAuth.Consumer/OAuth/WebConsumer.cs @@ -7,6 +7,8 @@ namespace DotNetOpenAuth.OAuth { using System; using System.Collections.Generic; + using System.Threading; + using System.Threading.Tasks; using System.Web; using DotNetOpenAuth.Messaging; using DotNetOpenAuth.OAuth.ChannelElements; @@ -39,9 +41,9 @@ namespace DotNetOpenAuth.OAuth { /// <remarks> /// Requires HttpContext.Current. /// </remarks> - public UserAuthorizationRequest PrepareRequestUserAuthorization() { + public Task<UserAuthorizationRequest> PrepareRequestUserAuthorizationAsync(CancellationToken cancellationToken = default(CancellationToken)) { Uri callback = this.Channel.GetRequestFromContext().GetPublicFacingUrl().StripQueryArgumentsWithPrefix(Protocol.ParameterPrefix); - return this.PrepareRequestUserAuthorization(callback, null, null); + return this.PrepareRequestUserAuthorizationAsync(callback, null, null, cancellationToken); } /// <summary> @@ -55,20 +57,8 @@ namespace DotNetOpenAuth.OAuth { /// <param name="requestParameters">Extra parameters to add to the request token message. Optional.</param> /// <param name="redirectParameters">Extra parameters to add to the redirect to Service Provider message. Optional.</param> /// <returns>The pending user agent redirect based message to be sent as an HttpResponse.</returns> - public UserAuthorizationRequest PrepareRequestUserAuthorization(Uri callback, IDictionary<string, string> requestParameters, IDictionary<string, string> redirectParameters) { - string token; - return this.PrepareRequestUserAuthorization(callback, requestParameters, redirectParameters, out token); - } - - /// <summary> - /// Processes an incoming authorization-granted message from an SP and obtains an access token. - /// </summary> - /// <returns>The access token, or null if no incoming authorization message was recognized.</returns> - /// <remarks> - /// Requires HttpContext.Current. - /// </remarks> - public AuthorizedTokenResponse ProcessUserAuthorization() { - return this.ProcessUserAuthorization(this.Channel.GetRequestFromContext()); + public Task<UserAuthorizationRequest> PrepareRequestUserAuthorizationAsync(Uri callback, IDictionary<string, string> requestParameters, IDictionary<string, string> redirectParameters, CancellationToken cancellationToken = default(CancellationToken)) { + return this.PrepareRequestUserAuthorizationAsync(callback, requestParameters, redirectParameters, cancellationToken); } /// <summary> @@ -76,14 +66,14 @@ namespace DotNetOpenAuth.OAuth { /// </summary> /// <param name="request">The incoming HTTP request.</param> /// <returns>The access token, or null if no incoming authorization message was recognized.</returns> - public AuthorizedTokenResponse ProcessUserAuthorization(HttpRequestBase request) { - Requires.NotNull(request, "request"); + public async Task<AuthorizedTokenResponse> ProcessUserAuthorizationAsync(HttpRequestBase request = null, CancellationToken cancellationToken = default(CancellationToken)) { + request = request ?? this.Channel.GetRequestFromContext(); - UserAuthorizationResponse authorizationMessage; - if (this.Channel.TryReadFromRequest<UserAuthorizationResponse>(request, out authorizationMessage)) { + var authorizationMessage = await this.Channel.TryReadFromRequestAsync<UserAuthorizationResponse>(cancellationToken, request); + if (authorizationMessage != null) { string requestToken = authorizationMessage.RequestToken; string verifier = authorizationMessage.VerificationCode; - return this.ProcessUserAuthorization(requestToken, verifier); + return await this.ProcessUserAuthorizationAsync(requestToken, verifier, cancellationToken); } else { return null; } diff --git a/src/DotNetOpenAuth.OAuth/OAuth/ChannelElements/OAuthChannel.cs b/src/DotNetOpenAuth.OAuth/OAuth/ChannelElements/OAuthChannel.cs index e69815d..f3c5897 100644 --- a/src/DotNetOpenAuth.OAuth/OAuth/ChannelElements/OAuthChannel.cs +++ b/src/DotNetOpenAuth.OAuth/OAuth/ChannelElements/OAuthChannel.cs @@ -302,7 +302,7 @@ namespace DotNetOpenAuth.OAuth.ChannelElements { var httpRequest = new HttpRequestMessage(GetHttpMethod(requestMessage), recipientBuilder.Uri); this.PrepareHttpWebRequest(httpRequest); - httpRequest.Headers.Authorization = new AuthenticationHeaderValue(MessagingUtilities.AssembleAuthorizationHeader(Protocol.AuthorizationHeaderScheme, fields)); + httpRequest.Headers.Authorization = new AuthenticationHeaderValue(Protocol.AuthorizationHeaderScheme, MessagingUtilities.AssembleAuthorizationHeader(fields)); if (hasEntity) { var requestMessageWithBinaryData = requestMessage as IMessageWithBinaryData; diff --git a/src/DotNetOpenAuth.OAuth/OAuth/Messages/UserAuthorizationRequest.cs b/src/DotNetOpenAuth.OAuth/OAuth/Messages/UserAuthorizationRequest.cs index 4f98622..357220b 100644 --- a/src/DotNetOpenAuth.OAuth/OAuth/Messages/UserAuthorizationRequest.cs +++ b/src/DotNetOpenAuth.OAuth/OAuth/Messages/UserAuthorizationRequest.cs @@ -70,7 +70,7 @@ namespace DotNetOpenAuth.OAuth.Messages { /// case it will prompt the User to enter it manually. /// </remarks> [MessagePart("oauth_token", IsRequired = false)] - internal string RequestToken { get; set; } + public string RequestToken { get; internal set; } /// <summary> /// Gets or sets a URL the Service Provider will use to redirect the User back diff --git a/src/DotNetOpenAuth.OpenIdInfoCard.UI/DotNetOpenAuth.OpenIdInfoCard.UI.csproj b/src/DotNetOpenAuth.OpenIdInfoCard.UI/DotNetOpenAuth.OpenIdInfoCard.UI.csproj index ed05c2d..f12a2eb 100644 --- a/src/DotNetOpenAuth.OpenIdInfoCard.UI/DotNetOpenAuth.OpenIdInfoCard.UI.csproj +++ b/src/DotNetOpenAuth.OpenIdInfoCard.UI/DotNetOpenAuth.OpenIdInfoCard.UI.csproj @@ -64,6 +64,8 @@ </ProjectReference> </ItemGroup> <ItemGroup> + <Reference Include="System.Net.Http" /> + <Reference Include="System.Net.Http.WebRequest" /> <Reference Include="Validation"> <HintPath>..\packages\Validation.2.0.1.12362\lib\portable-windows8+net40+sl5+windowsphone8\Validation.dll</HintPath> <Private>True</Private> diff --git a/src/DotNetOpenAuth.OpenIdInfoCard.UI/packages.config b/src/DotNetOpenAuth.OpenIdInfoCard.UI/packages.config index 58890d8..1d93cf5 100644 --- a/src/DotNetOpenAuth.OpenIdInfoCard.UI/packages.config +++ b/src/DotNetOpenAuth.OpenIdInfoCard.UI/packages.config @@ -1,4 +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.1.12362" targetFramework="net45" /> </packages>
\ No newline at end of file diff --git a/src/DotNetOpenAuth.OpenIdOAuth/OAuth/WebConsumerOpenIdRelyingParty.cs b/src/DotNetOpenAuth.OpenIdOAuth/OAuth/WebConsumerOpenIdRelyingParty.cs index 7c77e4f..97ee9ab 100644 --- a/src/DotNetOpenAuth.OpenIdOAuth/OAuth/WebConsumerOpenIdRelyingParty.cs +++ b/src/DotNetOpenAuth.OpenIdOAuth/OAuth/WebConsumerOpenIdRelyingParty.cs @@ -9,6 +9,8 @@ namespace DotNetOpenAuth.OAuth { using System.Collections.Generic; using System.Linq; using System.Text; + using System.Threading; + using System.Threading.Tasks; using DotNetOpenAuth.Messaging; using DotNetOpenAuth.OAuth.ChannelElements; using DotNetOpenAuth.OAuth.Messages; @@ -61,7 +63,7 @@ namespace DotNetOpenAuth.OAuth { /// The access token, if granted, is automatically stored in the <see cref="ConsumerBase.TokenManager"/>. /// The token manager instance must implement <see cref="IOpenIdOAuthTokenManager"/>. /// </remarks> - public AuthorizedTokenResponse ProcessUserAuthorization(IAuthenticationResponse openIdAuthenticationResponse) { + public async Task<AuthorizedTokenResponse> ProcessUserAuthorizationAsync(IAuthenticationResponse openIdAuthenticationResponse, CancellationToken cancellationToken = default(CancellationToken)) { Requires.NotNull(openIdAuthenticationResponse, "openIdAuthenticationResponse"); RequiresEx.ValidState(this.TokenManager is IOpenIdOAuthTokenManager); var openidTokenManager = this.TokenManager as IOpenIdOAuthTokenManager; @@ -87,7 +89,7 @@ namespace DotNetOpenAuth.OAuth { // Retrieve the access token and store it in the token manager. openidTokenManager.StoreOpenIdAuthorizedRequestToken(this.ConsumerKey, positiveAuthorization); - var grantAccess = this.Channel.Request<AuthorizedTokenResponse>(requestAccess); + var grantAccess = await this.Channel.RequestAsync<AuthorizedTokenResponse>(requestAccess, cancellationToken); this.TokenManager.ExpireRequestTokenAndStoreNewAccessToken(this.ConsumerKey, positiveAuthorization.RequestToken, grantAccess.AccessToken, grantAccess.TokenSecret); // Provide the caller with the access token so it may be associated with the user |