//----------------------------------------------------------------------- // // Copyright (c) Microsoft. All rights reserved. // //----------------------------------------------------------------------- namespace DotNetOpenAuth.AspNet { using System; using System.Diagnostics.CodeAnalysis; using System.Web; using DotNetOpenAuth.AspNet.Clients; using DotNetOpenAuth.Messaging; /// /// Manage authenticating with an external OAuth or OpenID provider /// public class OpenAuthSecurityManager { #region Constants and Fields /// /// The provider query string name. /// private const string ProviderQueryStringName = "__provider__"; /// /// The _authentication provider. /// private readonly IAuthenticationClient authenticationProvider; /// /// The _data provider. /// private readonly IOpenAuthDataProvider dataProvider; /// /// The _request context. /// private readonly HttpContextBase requestContext; #endregion #region Constructors and Destructors /// /// Initializes a new instance of the class. /// /// /// The request context. /// public OpenAuthSecurityManager(HttpContextBase requestContext) : this(requestContext, provider: null, dataProvider: null) { } /// /// Initializes a new instance of the class. /// /// /// The request context. /// /// /// The provider. /// /// /// The data provider. /// public OpenAuthSecurityManager( HttpContextBase requestContext, IAuthenticationClient provider, IOpenAuthDataProvider dataProvider) { if (requestContext == null) { throw new ArgumentNullException("requestContext"); } this.requestContext = requestContext; this.dataProvider = dataProvider; this.authenticationProvider = provider; } #endregion #region Public Properties /// /// Gets a value indicating whether IsAuthenticatedWithOpenAuth. /// public bool IsAuthenticatedWithOpenAuth { get { return this.requestContext.Request.IsAuthenticated && OpenAuthAuthenticationTicketHelper.IsValidAuthenticationTicket(this.requestContext); } } #endregion #region Public Methods and Operators /// /// Gets the provider that is responding to an authentication request. /// /// /// The HTTP request context. /// /// /// The provider name, if one is available. /// public static string GetProviderName(HttpContextBase context) { return context.Request.QueryString[ProviderQueryStringName]; } /// /// Checks if the specified provider user id represents a valid account. If it does, log user in. /// /// /// The provider user id. /// /// /// if set to true create persistent cookie. /// /// /// true if the login is successful. /// [SuppressMessage("Microsoft.Naming", "CA1726:UsePreferredTerms", MessageId = "Login", Justification = "Login is used more consistently in ASP.Net")] public bool Login(string providerUserId, bool createPersistentCookie) { string userName = this.dataProvider.GetUserNameFromOpenAuth( this.authenticationProvider.ProviderName, providerUserId); if (string.IsNullOrEmpty(userName)) { return false; } OpenAuthAuthenticationTicketHelper.SetAuthenticationTicket(this.requestContext, userName, createPersistentCookie); return true; } /// /// Requests the specified provider to start the authentication by directing users to an external website /// /// /// The return url after user is authenticated. /// public void RequestAuthentication(string returnUrl) { // convert returnUrl to an absolute path Uri uri; if (!string.IsNullOrEmpty(returnUrl)) { uri = UriHelper.ConvertToAbsoluteUri(returnUrl, this.requestContext); } else { uri = this.requestContext.Request.GetPublicFacingUrl(); } // attach the provider parameter so that we know which provider initiated // the login when user is redirected back to this page uri = uri.AttachQueryStringParameter(ProviderQueryStringName, this.authenticationProvider.ProviderName); this.authenticationProvider.RequestAuthentication(this.requestContext, uri); } /// /// Checks if user is successfully authenticated when user is redirected back to this user. /// /// The result of the authentication. public AuthenticationResult VerifyAuthentication() { AuthenticationResult result = this.authenticationProvider.VerifyAuthentication(this.requestContext); if (!result.IsSuccessful) { // if the result is a Failed result, creates a new Failed response which has providerName info. result = new AuthenticationResult( isSuccessful: false, provider: this.authenticationProvider.ProviderName, providerUserId: null, userName: null, extraData: null); } return result; } /// /// Checks if user is successfully authenticated when user is redirected back to this user. /// /// The return Url which must match exactly the Url passed into RequestAuthentication() earlier. /// /// The result of the authentication. /// public AuthenticationResult VerifyAuthentication(string returnUrl) { Requires.NotNullOrEmpty(returnUrl, "returnUrl"); // Only OAuth2 requires the return url value for the verify authenticaiton step OAuth2Client oauth2Client = this.authenticationProvider as OAuth2Client; if (oauth2Client != null) { // convert returnUrl to an absolute path Uri uri; if (!string.IsNullOrEmpty(returnUrl)) { uri = UriHelper.ConvertToAbsoluteUri(returnUrl, this.requestContext); } else { uri = this.requestContext.Request.GetPublicFacingUrl(); } AuthenticationResult result = oauth2Client.VerifyAuthentication(this.requestContext, uri); if (!result.IsSuccessful) { // if the result is a Failed result, creates a new Failed response which has providerName info. result = new AuthenticationResult( isSuccessful: false, provider: this.authenticationProvider.ProviderName, providerUserId: null, userName: null, extraData: null); } return result; } else { return this.VerifyAuthentication(); } } #endregion } }