//----------------------------------------------------------------------- // // Copyright (c) Microsoft. All rights reserved. // //----------------------------------------------------------------------- namespace DotNetOpenAuth.AspNet.Clients { using System; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.IO; using System.Web; using System.Xml; using System.Xml.Linq; using DotNetOpenAuth.Messaging; using DotNetOpenAuth.OAuth; using DotNetOpenAuth.OAuth.ChannelElements; using DotNetOpenAuth.OAuth.Messages; using Validation; /// /// Represents base class for OAuth 1.0 clients /// public abstract class OAuthClient : IAuthenticationClient { #region Constructors and Destructors /// /// Initializes a new instance of the class. /// /// /// Name of the provider. /// /// /// The service description. /// /// /// The consumer key. /// /// /// The consumer secret. /// protected OAuthClient( string providerName, ServiceProviderDescription serviceDescription, string consumerKey, string consumerSecret) : this(providerName, serviceDescription, new InMemoryOAuthTokenManager(consumerKey, consumerSecret)) { } /// /// Initializes a new instance of the class. /// /// /// Name of the provider. /// /// /// The service Description. /// /// /// The token Manager. /// [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Justification = "I don't know how to ensure this rule is followed given this API")] protected OAuthClient( string providerName, ServiceProviderDescription serviceDescription, IConsumerTokenManager tokenManager) : this(providerName, new DotNetOpenAuthWebConsumer(serviceDescription, tokenManager)) { } /// /// Initializes a new instance of the class. /// /// /// The provider name. /// /// /// The web worker. /// protected OAuthClient(string providerName, IOAuthWebWorker webWorker) { Requires.NotNull(providerName, "providerName"); Requires.NotNull(webWorker, "webWorker"); this.ProviderName = providerName; this.WebWorker = webWorker; } #endregion #region Public Properties /// /// Gets the name of the provider which provides authentication service. /// public string ProviderName { get; private set; } #endregion #region Properties /// /// Gets the OAuthWebConsumer instance which handles constructing requests to the OAuth providers. /// protected IOAuthWebWorker WebWorker { get; private set; } #endregion #region Public Methods and Operators /// /// Attempts to authenticate users by forwarding them to an external website, and upon succcess or failure, redirect users back to the specified url. /// /// /// The context. /// /// /// The return url after users have completed authenticating against external website. /// public virtual void RequestAuthentication(HttpContextBase context, Uri returnUrl) { Requires.NotNull(returnUrl, "returnUrl"); Requires.NotNull(context, "context"); Uri callback = returnUrl.StripQueryArgumentsWithPrefix("oauth_"); this.WebWorker.RequestAuthentication(callback); } /// /// Check if authentication succeeded after user is redirected back from the service provider. /// /// /// The context. /// /// /// An instance of containing authentication result. /// public virtual AuthenticationResult VerifyAuthentication(HttpContextBase context) { AuthorizedTokenResponse response = this.WebWorker.ProcessUserAuthorization(); if (response == null) { return AuthenticationResult.Failed; } AuthenticationResult result = this.VerifyAuthenticationCore(response); 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 ? new Dictionary(result.ExtraData) : result.ExtraData; wrapExtraData["accesstoken"] = response.AccessToken; AuthenticationResult wrapResult = new AuthenticationResult( result.IsSuccessful, result.Provider, result.ProviderUserId, result.UserName, wrapExtraData); result = wrapResult; } return result; } #endregion #region Methods /// /// Helper method to load an XDocument from an input stream. /// /// The input stream from which to load the document. /// The XML document. internal static XDocument LoadXDocumentFromStream(Stream stream) { const int MaxChars = 0x10000; // 64k var settings = MessagingUtilities.CreateUntrustedXmlReaderSettings(); settings.MaxCharactersInDocument = MaxChars; return XDocument.Load(XmlReader.Create(stream, settings)); } /// /// Check if authentication succeeded after user is redirected back from the service provider. /// /// /// The response token returned from service provider /// /// /// Authentication result /// protected abstract AuthenticationResult VerifyAuthenticationCore(AuthorizedTokenResponse response); #endregion } }