diff options
Diffstat (limited to 'projecttemplates/MvcRelyingParty/Controllers/AccountController.cs')
-rw-r--r-- | projecttemplates/MvcRelyingParty/Controllers/AccountController.cs | 131 |
1 files changed, 131 insertions, 0 deletions
diff --git a/projecttemplates/MvcRelyingParty/Controllers/AccountController.cs b/projecttemplates/MvcRelyingParty/Controllers/AccountController.cs new file mode 100644 index 0000000..312c99f --- /dev/null +++ b/projecttemplates/MvcRelyingParty/Controllers/AccountController.cs @@ -0,0 +1,131 @@ +namespace MvcRelyingParty.Controllers { + using System; + using System.Collections.Generic; + using System.Globalization; + using System.Linq; + using System.Security.Principal; + using System.Web; + using System.Web.Mvc; + using System.Web.Security; + using System.Web.UI; + using DotNetOpenAuth.Messaging; + using DotNetOpenAuth.OpenId.Extensions.SimpleRegistration; + using DotNetOpenAuth.OpenId.RelyingParty; + using RelyingPartyLogic; + using DotNetOpenAuth.OpenId; + + [HandleError] + public class AccountController : Controller { + internal static OpenIdRelyingParty relyingParty = new OpenIdRelyingParty(); + + // This constructor is used by the MVC framework to instantiate the controller using + // the default forms authentication and membership providers. + + public AccountController() + : this(null) { + } + + // This constructor is not used by the MVC framework but is instead provided for ease + // of unit testing this type. See the comments at the end of this file for more + // information. + public AccountController(IFormsAuthentication formsAuth) { + FormsAuth = formsAuth ?? new FormsAuthenticationService(); + } + + public IFormsAuthentication FormsAuth { get; private set; } + + public Realm Realm { + get { + UriBuilder builder = new UriBuilder(Request.Url); + builder.Path = Request.ApplicationPath; + return builder.Uri; + } + } + public Uri ReturnTo { + get { return new Uri(Request.Url, Url.Action("LogOnReturnTo")); } + } + + public ActionResult LogOn() { + return View(); + } + + [AcceptVerbs(HttpVerbs.Post), ValidateAntiForgeryToken] + public ActionResult LogOn(string openid_identifier, bool rememberMe, string returnUrl) { + try { + var request = relyingParty.CreateRequest(openid_identifier, this.Realm, this.ReturnTo); + request.SetUntrustedCallbackArgument("rememberMe", rememberMe ? "1" : "0"); + + // This might be signed so the OP can't send the user to a dangerous URL. + // Of course, if that itself was a danger then the site is vulnerable to XSRF attacks anyway. + if (!string.IsNullOrEmpty(returnUrl)) { + request.SetUntrustedCallbackArgument("returnUrl", returnUrl); + } + + // 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, + }); + + return request.RedirectingResponse.AsActionResult(); + } catch (ProtocolException ex) { + ModelState.AddModelError("OpenID", ex.Message); + return View(); + } + } + + [AcceptVerbs(HttpVerbs.Get | HttpVerbs.Post)] + public ActionResult LogOnReturnTo() { + var response = relyingParty.GetResponse(); + if (response != null) { + switch (response.Status) { + case AuthenticationStatus.Authenticated: + bool rememberMe = response.GetUntrustedCallbackArgument("rememberMe") == "1"; + FormsAuth.SignIn(response.ClaimedIdentifier, rememberMe); + string returnUrl = response.GetCallbackArgument("returnUrl"); + if (!String.IsNullOrEmpty(returnUrl)) { + return Redirect(returnUrl); + } else { + return RedirectToAction("Index", "Home"); + } + break; + case AuthenticationStatus.Canceled: + ModelState.AddModelError("OpenID", "It looks like you canceled login at your OpenID Provider."); + break; + case AuthenticationStatus.Failed: + ModelState.AddModelError("OpenID", response.Exception.Message); + break; + } + } + + return View("LogOn"); + } + + public ActionResult LogOff() { + FormsAuth.SignOut(); + return RedirectToAction("Index", "Home"); + } + } + + // The FormsAuthentication type is sealed and contains static members, so it is difficult to + // unit test code that calls its members. The interface and helper class below demonstrate + // how to create an abstract wrapper around such a type in order to make the AccountController + // code unit testable. + + public interface IFormsAuthentication { + void SignIn(string claimedIdentifier, bool createPersistentCookie); + void SignOut(); + } + + public class FormsAuthenticationService : IFormsAuthentication { + public void SignIn(string claimedIdentifier, bool createPersistentCookie) { + FormsAuthentication.SetAuthCookie(claimedIdentifier, createPersistentCookie); + } + + public void SignOut() { + FormsAuthentication.SignOut(); + } + } +} |