//----------------------------------------------------------------------- // // Copyright (c) Andrew Arnott. All rights reserved. // //----------------------------------------------------------------------- namespace DotNetOAuth { using System; using System.Collections.Generic; using System.Net; using DotNetOAuth.ChannelElements; using DotNetOAuth.Messages; using DotNetOAuth.Messaging; using DotNetOAuth.Messaging.Bindings; /// /// A website or application that uses OAuth to access the Service Provider on behalf of the User. /// public class Consumer { /// /// 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. public Consumer(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, new OAuthMessageTypeProvider(tokenManager), this.WebRequestHandler); this.ServiceProvider = serviceDescription; this.TokenManager = tokenManager; } /// /// Gets or sets the Consumer Key used to communicate with the Service Provider. /// public string ConsumerKey { get; set; } /// /// Gets or sets the Consumer Secret used to communicate with the Service Provider. /// public string ConsumerSecret { 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; private set; } /// /// 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; } /// /// 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. /// The pending user agent redirect based message to be sent as an HttpResponse. public Response RequestUserAuthorization(Uri callback, IDictionary extraParameters) { // Obtain an unauthorized request token. var requestToken = new RequestTokenMessage(this.ServiceProvider.RequestTokenEndpoint) { ConsumerKey = this.ConsumerKey, ConsumerSecret = this.ConsumerSecret, }; requestToken.AddNonOAuthParameters(extraParameters); var requestTokenResponse = this.Channel.Request(requestToken); this.TokenManager.StoreNewRequestToken(this.ConsumerKey, requestTokenResponse.RequestToken, requestTokenResponse.TokenSecret, null/*TODO*/); // Request user authorization. var requestAuthorization = new DirectUserToServiceProviderMessage(this.ServiceProvider.UserAuthorizationEndpoint) { Callback = callback, RequestToken = requestTokenResponse.RequestToken, }; return this.Channel.Send(requestAuthorization); } /// /// Processes an incoming authorization-granted message from an SP and obtains an access token. /// /// The access token. public string ProcessUserAuthorization() { var authorizationMessage = this.Channel.ReadFromRequest(); // Exchange request token for access token. string requestTokenSecret = this.TokenManager.GetTokenSecret(authorizationMessage.RequestToken); var requestAccess = new RequestAccessTokenMessage(this.ServiceProvider.AccessTokenEndpoint) { RequestToken = authorizationMessage.RequestToken, TokenSecret = requestTokenSecret, ConsumerKey = this.ConsumerKey, ConsumerSecret = this.ConsumerSecret, }; var grantAccess = this.Channel.Request(requestAccess); this.TokenManager.ExpireRequestTokenAndStoreNewAccessToken(this.ConsumerKey, authorizationMessage.RequestToken, grantAccess.AccessToken, grantAccess.TokenSecret); return grantAccess.AccessToken; } /// /// 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 CreateAuthorizedRequest(MessageReceivingEndpoint endpoint, string accessToken) { IDirectedProtocolMessage message = this.CreateAuthorizedRequestInternal(endpoint, accessToken); WebRequest 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 SendAuthorizedRequest(MessageReceivingEndpoint endpoint, string accessToken) { IDirectedProtocolMessage message = this.CreateAuthorizedRequestInternal(endpoint, accessToken); HttpWebRequest wr = this.Channel.InitializeRequest(message); return this.WebRequestHandler.GetResponse(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. internal AccessProtectedResourcesMessage CreateAuthorizedRequestInternal(MessageReceivingEndpoint endpoint, string accessToken) { if (endpoint == null) { throw new ArgumentNullException("endpoint"); } if (String.IsNullOrEmpty(accessToken)) { throw new ArgumentNullException("accessToken"); } AccessProtectedResourcesMessage message = new AccessProtectedResourcesMessage(endpoint) { AccessToken = accessToken, TokenSecret = this.TokenManager.GetTokenSecret(accessToken), ConsumerKey = this.ConsumerKey, ConsumerSecret = this.ConsumerSecret, }; return message; } } }