summaryrefslogtreecommitdiffstats
path: root/src/OpenID/OpenIdRelyingPartyMvc/Controllers
diff options
context:
space:
mode:
Diffstat (limited to 'src/OpenID/OpenIdRelyingPartyMvc/Controllers')
-rw-r--r--src/OpenID/OpenIdRelyingPartyMvc/Controllers/AccountController.cs113
-rw-r--r--src/OpenID/OpenIdRelyingPartyMvc/Controllers/HomeController.cs20
-rw-r--r--src/OpenID/OpenIdRelyingPartyMvc/Controllers/UserController.cs72
3 files changed, 205 insertions, 0 deletions
diff --git a/src/OpenID/OpenIdRelyingPartyMvc/Controllers/AccountController.cs b/src/OpenID/OpenIdRelyingPartyMvc/Controllers/AccountController.cs
new file mode 100644
index 0000000..5422a61
--- /dev/null
+++ b/src/OpenID/OpenIdRelyingPartyMvc/Controllers/AccountController.cs
@@ -0,0 +1,113 @@
+namespace RelyingPartyMvc.Controllers {
+ using System;
+ using System.Collections.Generic;
+ using System.Diagnostics.CodeAnalysis;
+ using System.Globalization;
+ using System.Linq;
+ using System.Security.Cryptography;
+ using System.Security.Principal;
+ using System.Web;
+ using System.Web.Mvc;
+ using System.Web.Security;
+ using System.Web.UI;
+
+ public class AccountController : Controller {
+ // This constructor is used by the MVC framework to instantiate the controller using
+ // the default forms authentication and membership providers.
+
+ public AccountController()
+ : this(null, 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, IMembershipService service) {
+ this.FormsAuth = formsAuth ?? new FormsAuthenticationService();
+ this.MembershipService = service ?? new AccountMembershipService();
+ }
+
+ public IFormsAuthentication FormsAuth { get; private set; }
+
+ public IMembershipService MembershipService { get; private set; }
+
+ public ActionResult LogOn() {
+ return View();
+ }
+
+ [AcceptVerbs(HttpVerbs.Post)]
+ [SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings",
+ Justification = "Needs to take same parameter type as Controller.Redirect()")]
+ public ActionResult LogOn(string userName, bool rememberMe, string returnUrl) {
+ this.FormsAuth.SignIn(userName, rememberMe);
+ if (!String.IsNullOrEmpty(returnUrl)) {
+ return Redirect(returnUrl);
+ } else {
+ return RedirectToAction("Index", "Home");
+ }
+ }
+
+ public ActionResult LogOff() {
+ this.FormsAuth.SignOut();
+
+ return RedirectToAction("Index", "Home");
+ }
+
+ protected override void OnActionExecuting(ActionExecutingContext filterContext) {
+ if (filterContext.HttpContext.User.Identity is WindowsIdentity) {
+ throw new InvalidOperationException("Windows authentication is not supported.");
+ }
+ }
+ }
+
+ // 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 userName, bool createPersistentCookie);
+
+ void SignOut();
+ }
+
+ public class FormsAuthenticationService : IFormsAuthentication {
+ public void SignIn(string userName, bool createPersistentCookie) {
+ FormsAuthentication.SetAuthCookie(userName, createPersistentCookie);
+ }
+ public void SignOut() {
+ FormsAuthentication.SignOut();
+ }
+ }
+
+ public interface IMembershipService {
+ MembershipCreateStatus CreateUser(string claimedIdentifier, string email);
+ }
+
+ public class AccountMembershipService : IMembershipService {
+ private MembershipProvider provider;
+ private RandomNumberGenerator passwordGenerator;
+
+ public AccountMembershipService()
+ : this(null) {
+ }
+
+ public AccountMembershipService(MembershipProvider provider) {
+ this.provider = provider ?? Membership.Provider;
+ this.passwordGenerator = RNGCryptoServiceProvider.Create();
+ }
+
+ public MembershipCreateStatus CreateUser(string userName, string email) {
+ MembershipCreateStatus status;
+ string password = this.GenerateInsaneSecurePassword();
+ this.provider.CreateUser(userName, password, email, null, null, true, null, out status);
+ return status;
+ }
+
+ private string GenerateInsaneSecurePassword() {
+ byte[] secureBits = new byte[20];
+ this.passwordGenerator.GetBytes(secureBits);
+ return Convert.ToBase64String(secureBits);
+ }
+ }
+}
diff --git a/src/OpenID/OpenIdRelyingPartyMvc/Controllers/HomeController.cs b/src/OpenID/OpenIdRelyingPartyMvc/Controllers/HomeController.cs
new file mode 100644
index 0000000..d26cdd9
--- /dev/null
+++ b/src/OpenID/OpenIdRelyingPartyMvc/Controllers/HomeController.cs
@@ -0,0 +1,20 @@
+namespace OpenIdRelyingPartyMvc.Controllers {
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+ using System.Web;
+ using System.Web.Mvc;
+
+ public class HomeController : Controller {
+ public ActionResult Index() {
+ Response.AppendHeader(
+ "X-XRDS-Location",
+ new Uri(Request.Url, Response.ApplyAppPathModifier("~/Home/xrds")).AbsoluteUri);
+ return View("Index");
+ }
+
+ public ActionResult Xrds() {
+ return View("Xrds");
+ }
+ }
+}
diff --git a/src/OpenID/OpenIdRelyingPartyMvc/Controllers/UserController.cs b/src/OpenID/OpenIdRelyingPartyMvc/Controllers/UserController.cs
new file mode 100644
index 0000000..3ff405f
--- /dev/null
+++ b/src/OpenID/OpenIdRelyingPartyMvc/Controllers/UserController.cs
@@ -0,0 +1,72 @@
+namespace OpenIdRelyingPartyMvc.Controllers {
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+ using System.Web;
+ using System.Web.Mvc;
+ using System.Web.Security;
+ using DotNetOpenAuth.Messaging;
+ using DotNetOpenAuth.OpenId;
+ using DotNetOpenAuth.OpenId.RelyingParty;
+
+ public class UserController : Controller {
+ private static OpenIdRelyingParty openid = new OpenIdRelyingParty();
+
+ public ActionResult Index() {
+ if (!User.Identity.IsAuthenticated) {
+ Response.Redirect("~/User/Login?ReturnUrl=Index");
+ }
+
+ return View("Index");
+ }
+
+ public ActionResult Logout() {
+ FormsAuthentication.SignOut();
+ return Redirect("~/Home");
+ }
+
+ public ActionResult Login() {
+ // Stage 1: display login form to user
+ return View("Login");
+ }
+
+ [ValidateInput(false)]
+ public ActionResult Authenticate(string returnUrl) {
+ var response = openid.GetResponse();
+ if (response == null) {
+ // Stage 2: user submitting Identifier
+ Identifier id;
+ if (Identifier.TryParse(Request.Form["openid_identifier"], out id)) {
+ try {
+ return openid.CreateRequest(Request.Form["openid_identifier"]).RedirectingResponse.AsActionResult();
+ } catch (ProtocolException ex) {
+ ViewData["Message"] = ex.Message;
+ return View("Login");
+ }
+ } else {
+ ViewData["Message"] = "Invalid identifier";
+ return View("Login");
+ }
+ } else {
+ // Stage 3: OpenID Provider sending assertion response
+ switch (response.Status) {
+ case AuthenticationStatus.Authenticated:
+ Session["FriendlyIdentifier"] = response.FriendlyIdentifierForDisplay;
+ FormsAuthentication.SetAuthCookie(response.ClaimedIdentifier, false);
+ if (!string.IsNullOrEmpty(returnUrl)) {
+ return Redirect(returnUrl);
+ } else {
+ return RedirectToAction("Index", "Home");
+ }
+ case AuthenticationStatus.Canceled:
+ ViewData["Message"] = "Canceled at provider";
+ return View("Login");
+ case AuthenticationStatus.Failed:
+ ViewData["Message"] = response.Exception.Message;
+ return View("Login");
+ }
+ }
+ return new EmptyResult();
+ }
+ }
+}