namespace MvcRelyingParty { using System; using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Tasks; using System.Web; using System.Web.Mvc; using DotNetOpenAuth.Messaging; using DotNetOpenAuth.OpenId; using DotNetOpenAuth.OpenId.Extensions.SimpleRegistration; using DotNetOpenAuth.OpenId.RelyingParty; using Validation; public interface IOpenIdRelyingParty { Channel Channel { get; } Task CreateRequestAsync(Identifier userSuppliedIdentifier, Realm realm, Uri returnTo, Uri privacyPolicy, CancellationToken cancellationToken = default(CancellationToken)); Task> CreateRequestsAsync(Identifier userSuppliedIdentifier, Realm realm, Uri returnTo, Uri privacyPolicy, CancellationToken cancellationToken = default(CancellationToken)); Task AjaxDiscoveryAsync(Identifier userSuppliedIdentifier, Realm realm, Uri returnTo, Uri privacyPolicy, CancellationToken cancellationToken = default(CancellationToken)); Task PreloadDiscoveryResultsAsync(Realm realm, Uri returnTo, Uri privacyPolicy, CancellationToken cancellationToken = default(CancellationToken), params Identifier[] identifiers); Task ProcessAjaxOpenIdResponseAsync(CancellationToken cancellationToken = default(CancellationToken)); Task GetResponseAsync(CancellationToken cancellationToken = default(CancellationToken)); Task GetResponseAsync(HttpRequestBase request, CancellationToken cancellationToken = default(CancellationToken)); } /// /// A wrapper around the standard class. /// public class OpenIdRelyingPartyService : IOpenIdRelyingParty { /// /// The OpenID relying party to use for logging users in. /// /// /// This is static because it is thread-safe and is more expensive /// to create than we want to run through for every single page request. /// private static OpenIdAjaxRelyingParty relyingParty = new OpenIdAjaxRelyingParty(); /// /// Initializes a new instance of the class. /// public OpenIdRelyingPartyService() { } #region IOpenIdRelyingParty Members public Channel Channel { get { return relyingParty.Channel; } } public async Task CreateRequestAsync(Identifier userSuppliedIdentifier, Realm realm, Uri returnTo, Uri privacyPolicy, CancellationToken cancellationToken = default(CancellationToken)) { return (await this.CreateRequestsAsync(userSuppliedIdentifier, realm, returnTo, privacyPolicy, cancellationToken)).First(); } public async Task> CreateRequestsAsync(Identifier userSuppliedIdentifier, Realm realm, Uri returnTo, Uri privacyPolicy, CancellationToken cancellationToken = default(CancellationToken)) { Requires.NotNull(userSuppliedIdentifier, "userSuppliedIdentifier"); Requires.NotNull(realm, "realm"); Requires.NotNull(returnTo, "returnTo"); var requests = (await relyingParty.CreateRequestsAsync(userSuppliedIdentifier, realm, returnTo, cancellationToken)).ToList(); foreach (IAuthenticationRequest request in requests) { // Ask for the user's email, not because we necessarily need it to do our work, // but so we can display something meaningful to the user as their "username" // when they log in with a PPID from Google, for example. request.AddExtension(new ClaimsRequest { Email = DemandLevel.Require, FullName = DemandLevel.Request, PolicyUrl = privacyPolicy, }); } return requests; } public async Task AjaxDiscoveryAsync(Identifier userSuppliedIdentifier, Realm realm, Uri returnTo, Uri privacyPolicy, CancellationToken cancellationToken = default(CancellationToken)) { return (await relyingParty.AsAjaxDiscoveryResultAsync( await this.CreateRequestsAsync(userSuppliedIdentifier, realm, returnTo, privacyPolicy, cancellationToken), cancellationToken)).AsActionResult(); } public async Task PreloadDiscoveryResultsAsync(Realm realm, Uri returnTo, Uri privacyPolicy, CancellationToken cancellationToken = default(CancellationToken), params Identifier[] identifiers) { var results = new List(); foreach (var id in identifiers) { var discoveryResult = await this.CreateRequestsAsync(id, realm, returnTo, privacyPolicy, cancellationToken); results.AddRange(discoveryResult); } return await relyingParty.AsAjaxPreloadedDiscoveryResultAsync(results, cancellationToken); } public async Task ProcessAjaxOpenIdResponseAsync(CancellationToken cancellationToken = default(CancellationToken)) { return (await relyingParty.ProcessResponseFromPopupAsync(cancellationToken)).AsActionResult(); } public Task GetResponseAsync(CancellationToken cancellationToken = default(CancellationToken)) { return relyingParty.GetResponseAsync(cancellationToken); } public Task GetResponseAsync(HttpRequestBase request, CancellationToken cancellationToken = default(CancellationToken)) { return relyingParty.GetResponseAsync(request, cancellationToken); } #endregion } }