//-----------------------------------------------------------------------
//
// 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
}
}