diff options
Diffstat (limited to 'src/DotNetOpenAuth.AspNet/Clients/OAuth/LinkedInClient.cs')
-rw-r--r-- | src/DotNetOpenAuth.AspNet/Clients/OAuth/LinkedInClient.cs | 107 |
1 files changed, 42 insertions, 65 deletions
diff --git a/src/DotNetOpenAuth.AspNet/Clients/OAuth/LinkedInClient.cs b/src/DotNetOpenAuth.AspNet/Clients/OAuth/LinkedInClient.cs index 3c157f3..daf3441 100644 --- a/src/DotNetOpenAuth.AspNet/Clients/OAuth/LinkedInClient.cs +++ b/src/DotNetOpenAuth.AspNet/Clients/OAuth/LinkedInClient.cs @@ -10,11 +10,15 @@ 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; using DotNetOpenAuth.OAuth.ChannelElements; using DotNetOpenAuth.OAuth.Messages; + using System.Collections.Specialized; /// <summary> /// Represents LinkedIn authentication client. @@ -25,21 +29,10 @@ namespace DotNetOpenAuth.AspNet.Clients { /// <summary> /// Describes the OAuth service provider endpoints for LinkedIn. /// </summary> - public static readonly ServiceProviderDescription LinkedInServiceDescription = new ServiceProviderDescription { - RequestTokenEndpoint = - new MessageReceivingEndpoint( - "https://api.linkedin.com/uas/oauth/requestToken", - HttpDeliveryMethods.GetRequest | HttpDeliveryMethods.AuthorizationHeaderRequest), - UserAuthorizationEndpoint = - new MessageReceivingEndpoint( - "https://www.linkedin.com/uas/oauth/authenticate", - HttpDeliveryMethods.GetRequest | HttpDeliveryMethods.AuthorizationHeaderRequest), - AccessTokenEndpoint = - new MessageReceivingEndpoint( - "https://api.linkedin.com/uas/oauth/accessToken", - HttpDeliveryMethods.GetRequest | HttpDeliveryMethods.AuthorizationHeaderRequest), - TamperProtectionElements = new ITamperProtectionChannelBindingElement[] { new HmacSha1SigningBindingElement() }, - }; + public static readonly ServiceProviderDescription LinkedInServiceDescription = new ServiceProviderDescription( + "https://api.linkedin.com/uas/oauth/requestToken", + "https://www.linkedin.com/uas/oauth/authenticate", + "https://api.linkedin.com/uas/oauth/accessToken"); #endregion @@ -48,28 +41,10 @@ namespace DotNetOpenAuth.AspNet.Clients { /// <summary> /// Initializes a new instance of the <see cref="LinkedInClient"/> class. /// </summary> - /// <remarks> - /// Tokens exchanged during the OAuth handshake are stored in cookies. - /// </remarks> - /// <param name="consumerKey"> - /// The LinkedIn app's consumer key. - /// </param> - /// <param name="consumerSecret"> - /// The LinkedIn app's consumer secret. - /// </param> - [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", - Justification = "We can't dispose the object because we still need it through the app lifetime.")] - public LinkedInClient(string consumerKey, string consumerSecret) - : this(consumerKey, consumerSecret, new CookieOAuthTokenManager()) { } - - /// <summary> - /// Initializes a new instance of the <see cref="LinkedInClient"/> class. - /// </summary> /// <param name="consumerKey">The consumer key.</param> /// <param name="consumerSecret">The consumer secret.</param> - /// <param name="tokenManager">The token manager.</param> - public LinkedInClient(string consumerKey, string consumerSecret, IOAuthTokenManager tokenManager) - : base("linkedIn", LinkedInServiceDescription, new SimpleConsumerTokenManager(consumerKey, consumerSecret, tokenManager)) { + public LinkedInClient(string consumerKey, string consumerSecret) + : base("linkedIn", LinkedInServiceDescription, consumerKey, consumerSecret) { } #endregion @@ -79,46 +54,48 @@ namespace DotNetOpenAuth.AspNet.Clients { /// <summary> /// Check if authentication succeeded after user is redirected back from the service provider. /// </summary> - /// <param name="response"> - /// The response token returned from service provider - /// </param> + /// <param name="response">The response token returned from service provider</param> + /// <param name="cancellationToken">The cancellation token.</param> /// <returns> - /// Authentication result. + /// Authentication result. /// </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(AccessTokenResponse 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); - + var accessToken = response.AccessToken; + var authorizingHandler = this.WebWorker.CreateMessageHandler(accessToken); 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(authorizingHandler)) { + using (HttpResponseMessage profileResponse = await httpClient.GetAsync(ProfileRequestUrl, 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 NameValueCollection(); + extraData.Add("accesstoken", accessToken.Token); + extraData.Add("accesstokensecret", accessToken.Secret); + 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); + } } } - } - catch (Exception exception) { + } catch (Exception exception) { return new AuthenticationResult(exception); } } |