//----------------------------------------------------------------------- // // Copyright (c) Andrew Arnott. All rights reserved. // //----------------------------------------------------------------------- namespace DotNetOAuth { using System; using System.Collections.Generic; using System.Net; using System.Web; using DotNetOAuth.ChannelElements; using DotNetOAuth.Messages; using DotNetOAuth.Messaging; using DotNetOAuth.Messaging.Bindings; /// /// Base class for and types. /// public class ConsumerBase { /// /// Initializes a new instance of the class. /// /// The endpoints and behavior of the Service Provider. /// The host's method of storing and recalling tokens and secrets. protected ConsumerBase(ServiceProviderDescription serviceDescription, ITokenManager tokenManager) { if (serviceDescription == null) { throw new ArgumentNullException("serviceDescription"); } if (tokenManager == null) { throw new ArgumentNullException("tokenManager"); } this.WebRequestHandler = new StandardWebRequestHandler(); ITamperProtectionChannelBindingElement signingElement = serviceDescription.CreateTamperProtectionElement(); INonceStore store = new NonceMemoryStore(StandardExpirationBindingElement.DefaultMaximumMessageAge); this.Channel = new OAuthChannel(signingElement, store, tokenManager, new OAuthConsumerMessageTypeProvider(tokenManager), this.WebRequestHandler); this.ServiceProvider = serviceDescription; } /// /// Gets or sets the Consumer Key used to communicate with the Service Provider. /// public string ConsumerKey { get; set; } /// /// Gets the Service Provider that will be accessed. /// public ServiceProviderDescription ServiceProvider { get; private set; } /// /// Gets the persistence store for tokens and secrets. /// public ITokenManager TokenManager { get { return this.Channel.TokenManager; } } /// /// Gets or sets the object that processes s. /// /// /// This defaults to a straightforward implementation, but can be set /// to a mock object for testing purposes. /// internal IWebRequestHandler WebRequestHandler { get; set; } /// /// Gets or sets the channel to use for sending/receiving messages. /// internal OAuthChannel Channel { get; set; } /// /// Creates a web request prepared with OAuth authorization /// that may be further tailored by adding parameters by the caller. /// /// The URL and method on the Service Provider to send the request to. /// The access token that permits access to the protected resource. /// The initialized WebRequest object. public WebRequest PrepareAuthorizedRequest(MessageReceivingEndpoint endpoint, string accessToken) { IDirectedProtocolMessage message = this.CreateAuthorizingMessage(endpoint, accessToken); HttpWebRequest wr = this.Channel.InitializeRequest(message); return wr; } /// /// Creates a web request prepared with OAuth authorization /// that may be further tailored by adding parameters by the caller. /// /// The URL and method on the Service Provider to send the request to. /// The access token that permits access to the protected resource. /// The initialized WebRequest object. /// Thrown if the request fails for any reason after it is sent to the Service Provider. public Response PrepareAuthorizedRequestAndSend(MessageReceivingEndpoint endpoint, string accessToken) { IDirectedProtocolMessage message = this.CreateAuthorizingMessage(endpoint, accessToken); HttpWebRequest wr = this.Channel.InitializeRequest(message); return this.WebRequestHandler.GetResponse(wr); } /// /// Begins an OAuth authorization request and redirects the user to the Service Provider /// to provide that authorization. /// /// /// An optional Consumer URL that the Service Provider should redirect the /// User Agent to upon successful authorization. /// /// Extra parameters to add to the request token message. Optional. /// Extra parameters to add to the redirect to Service Provider message. Optional. /// The request token that must be exchanged for an access token after the user has provided authorization. /// The pending user agent redirect based message to be sent as an HttpResponse. protected internal Response RequestUserAuthorization(Uri callback, IDictionary requestParameters, IDictionary redirectParameters, out string token) { // Obtain an unauthorized request token. var requestToken = new GetRequestTokenMessage(this.ServiceProvider.RequestTokenEndpoint) { ConsumerKey = this.ConsumerKey, }; requestToken.AddNonOAuthParameters(requestParameters); var requestTokenResponse = this.Channel.Request(requestToken); this.TokenManager.StoreNewRequestToken(requestToken, requestTokenResponse); // Request user authorization. var requestAuthorization = new DirectUserToServiceProviderMessage(this.ServiceProvider.UserAuthorizationEndpoint) { Callback = callback, RequestToken = requestTokenResponse.RequestToken, }; requestAuthorization.AddNonOAuthParameters(redirectParameters); token = requestAuthorization.RequestToken; return this.Channel.Send(requestAuthorization); } /// /// Creates a web request prepared with OAuth authorization /// that may be further tailored by adding parameters by the caller. /// /// The URL and method on the Service Provider to send the request to. /// The access token that permits access to the protected resource. /// The initialized WebRequest object. protected internal AccessProtectedResourceMessage CreateAuthorizingMessage(MessageReceivingEndpoint endpoint, string accessToken) { if (endpoint == null) { throw new ArgumentNullException("endpoint"); } if (String.IsNullOrEmpty(accessToken)) { throw new ArgumentNullException("accessToken"); } AccessProtectedResourceMessage message = new AccessProtectedResourceMessage(endpoint) { AccessToken = accessToken, ConsumerKey = this.ConsumerKey, }; return message; } /// /// Exchanges a given request token for access token. /// /// The request token that the user has authorized. /// The access token assigned by the Service Provider. protected GrantAccessTokenMessage ProcessUserAuthorization(string requestToken) { var requestAccess = new GetAccessTokenMessage(this.ServiceProvider.AccessTokenEndpoint) { RequestToken = requestToken, ConsumerKey = this.ConsumerKey, }; var grantAccess = this.Channel.Request(requestAccess); this.TokenManager.ExpireRequestTokenAndStoreNewAccessToken(this.ConsumerKey, requestToken, grantAccess.AccessToken, grantAccess.TokenSecret); return grantAccess; } } }