diff options
Diffstat (limited to 'projecttemplates/MvcRelyingParty/Controllers/AccountController.cs')
-rw-r--r-- | projecttemplates/MvcRelyingParty/Controllers/AccountController.cs | 313 |
1 files changed, 76 insertions, 237 deletions
diff --git a/projecttemplates/MvcRelyingParty/Controllers/AccountController.cs b/projecttemplates/MvcRelyingParty/Controllers/AccountController.cs index bcce1dc..c07b554 100644 --- a/projecttemplates/MvcRelyingParty/Controllers/AccountController.cs +++ b/projecttemplates/MvcRelyingParty/Controllers/AccountController.cs @@ -1,233 +1,112 @@ -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; - -namespace MvcRelyingParty.Controllers { +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, null) { + : 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, IMembershipService service) { + public AccountController(IFormsAuthentication formsAuth) { FormsAuth = formsAuth ?? new FormsAuthenticationService(); - MembershipService = service ?? new AccountMembershipService(); - } - - public IFormsAuthentication FormsAuth { - get; - private set; } - public IMembershipService MembershipService { - get; - private set; - } - - public ActionResult LogOn() { - - return View(); - } - - [AcceptVerbs(HttpVerbs.Post)] - [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings", - Justification = "Needs to take same parameter type as Controller.Redirect()")] - public ActionResult LogOn(string userName, string password, bool rememberMe, string returnUrl) { - - if (!ValidateLogOn(userName, password)) { - return View(); - } + public IFormsAuthentication FormsAuth { get; private set; } - FormsAuth.SignIn(userName, rememberMe); - if (!String.IsNullOrEmpty(returnUrl)) { - return Redirect(returnUrl); - } else { - return RedirectToAction("Index", "Home"); + public Realm Realm { + get { + UriBuilder builder = new UriBuilder(Request.Url); + builder.Path = Request.ApplicationPath; + return builder.Uri; } } - - public ActionResult LogOff() { - - FormsAuth.SignOut(); - - return RedirectToAction("Index", "Home"); + public Uri ReturnTo { + get { return new Uri(Request.Url, Url.Action("LogOnReturnTo")); } } - public ActionResult Register() { - - ViewData["PasswordLength"] = MembershipService.MinPasswordLength; - + public ActionResult LogOn() { return View(); } [AcceptVerbs(HttpVerbs.Post)] - public ActionResult Register(string userName, string email, string password, string confirmPassword) { - - ViewData["PasswordLength"] = MembershipService.MinPasswordLength; - - if (ValidateRegistration(userName, email, password, confirmPassword)) { - // Attempt to register the user - MembershipCreateStatus createStatus = MembershipService.CreateUser(userName, password, email); + 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"); - if (createStatus == MembershipCreateStatus.Success) { - FormsAuth.SignIn(userName, false /* createPersistentCookie */); - return RedirectToAction("Index", "Home"); - } else { - ModelState.AddModelError("_FORM", ErrorCodeToString(createStatus)); + // 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); } - } - - // If we got this far, something failed, redisplay form - return View(); - } - - [Authorize] - public ActionResult ChangePassword() { - - ViewData["PasswordLength"] = MembershipService.MinPasswordLength; - - return View(); - } - - [Authorize] - [AcceptVerbs(HttpVerbs.Post)] - [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", - Justification = "Exceptions result in password not being changed.")] - public ActionResult ChangePassword(string currentPassword, string newPassword, string confirmPassword) { - ViewData["PasswordLength"] = MembershipService.MinPasswordLength; - - if (!ValidateChangePassword(currentPassword, newPassword, confirmPassword)) { + // 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); return View(); } - - try { - if (MembershipService.ChangePassword(User.Identity.Name, currentPassword, newPassword)) { - return RedirectToAction("ChangePasswordSuccess"); - } else { - ModelState.AddModelError("_FORM", "The current password is incorrect or the new password is invalid."); - return View(); - } - } catch { - ModelState.AddModelError("_FORM", "The current password is incorrect or the new password is invalid."); - return View(); - } - } - - public ActionResult ChangePasswordSuccess() { - - return View(); - } - - protected override void OnActionExecuting(ActionExecutingContext filterContext) { - if (filterContext.HttpContext.User.Identity is WindowsIdentity) { - throw new InvalidOperationException("Windows authentication is not supported."); - } } - #region Validation Methods - - private bool ValidateChangePassword(string currentPassword, string newPassword, string confirmPassword) { - if (String.IsNullOrEmpty(currentPassword)) { - ModelState.AddModelError("currentPassword", "You must specify a current password."); - } - if (newPassword == null || newPassword.Length < MembershipService.MinPasswordLength) { - ModelState.AddModelError("newPassword", - String.Format(CultureInfo.CurrentCulture, - "You must specify a new password of {0} or more characters.", - MembershipService.MinPasswordLength)); - } - - if (!String.Equals(newPassword, confirmPassword, StringComparison.Ordinal)) { - ModelState.AddModelError("_FORM", "The new password and confirmation password do not match."); - } - - return ModelState.IsValid; - } - - private bool ValidateLogOn(string userName, string password) { - if (String.IsNullOrEmpty(userName)) { - ModelState.AddModelError("username", "You must specify a username."); - } - if (String.IsNullOrEmpty(password)) { - ModelState.AddModelError("password", "You must specify a password."); - } - if (!MembershipService.ValidateUser(userName, password)) { - ModelState.AddModelError("_FORM", "The username or password provided is incorrect."); + [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); + break; + } } - return ModelState.IsValid; - } - - private bool ValidateRegistration(string userName, string email, string password, string confirmPassword) { - if (String.IsNullOrEmpty(userName)) { - ModelState.AddModelError("username", "You must specify a username."); - } - if (String.IsNullOrEmpty(email)) { - ModelState.AddModelError("email", "You must specify an email address."); - } - if (password == null || password.Length < MembershipService.MinPasswordLength) { - ModelState.AddModelError("password", - String.Format(CultureInfo.CurrentCulture, - "You must specify a password of {0} or more characters.", - MembershipService.MinPasswordLength)); - } - if (!String.Equals(password, confirmPassword, StringComparison.Ordinal)) { - ModelState.AddModelError("_FORM", "The new password and confirmation password do not match."); - } - return ModelState.IsValid; + return View("LogOn"); } - private static string ErrorCodeToString(MembershipCreateStatus createStatus) { - // See http://msdn.microsoft.com/en-us/library/system.web.security.membershipcreatestatus.aspx for - // a full list of status codes. - switch (createStatus) { - case MembershipCreateStatus.DuplicateUserName: - return "Username already exists. Please enter a different user name."; - - case MembershipCreateStatus.DuplicateEmail: - return "A username for that e-mail address already exists. Please enter a different e-mail address."; - - case MembershipCreateStatus.InvalidPassword: - return "The password provided is invalid. Please enter a valid password value."; - - case MembershipCreateStatus.InvalidEmail: - return "The e-mail address provided is invalid. Please check the value and try again."; - - case MembershipCreateStatus.InvalidAnswer: - return "The password retrieval answer provided is invalid. Please check the value and try again."; - - case MembershipCreateStatus.InvalidQuestion: - return "The password retrieval question provided is invalid. Please check the value and try again."; - - case MembershipCreateStatus.InvalidUserName: - return "The user name provided is invalid. Please check the value and try again."; - - case MembershipCreateStatus.ProviderError: - return "The authentication provider returned an error. Please verify your entry and try again. If the problem persists, please contact your system administrator."; - - case MembershipCreateStatus.UserRejected: - return "The user creation request has been canceled. Please verify your entry and try again. If the problem persists, please contact your system administrator."; - - default: - return "An unknown error occurred. Please verify your entry and try again. If the problem persists, please contact your system administrator."; - } + public ActionResult LogOff() { + FormsAuth.SignOut(); + return RedirectToAction("Index", "Home"); } - #endregion } // The FormsAuthentication type is sealed and contains static members, so it is difficult to @@ -236,57 +115,17 @@ namespace MvcRelyingParty.Controllers { // code unit testable. public interface IFormsAuthentication { - void SignIn(string userName, bool createPersistentCookie); + void SignIn(string claimedIdentifier, bool createPersistentCookie); void SignOut(); } public class FormsAuthenticationService : IFormsAuthentication { - public void SignIn(string userName, bool createPersistentCookie) { - FormsAuthentication.SetAuthCookie(userName, createPersistentCookie); + public void SignIn(string claimedIdentifier, bool createPersistentCookie) { + FormsAuthentication.SetAuthCookie(claimedIdentifier, createPersistentCookie); } + public void SignOut() { FormsAuthentication.SignOut(); } } - - public interface IMembershipService { - int MinPasswordLength { get; } - - bool ValidateUser(string userName, string password); - MembershipCreateStatus CreateUser(string userName, string password, string email); - bool ChangePassword(string userName, string oldPassword, string newPassword); - } - - public class AccountMembershipService : IMembershipService { - private MembershipProvider _provider; - - public AccountMembershipService() - : this(null) { - } - - public AccountMembershipService(MembershipProvider provider) { - _provider = provider ?? Membership.Provider; - } - - public int MinPasswordLength { - get { - return _provider.MinRequiredPasswordLength; - } - } - - public bool ValidateUser(string userName, string password) { - return _provider.ValidateUser(userName, password); - } - - public MembershipCreateStatus CreateUser(string userName, string password, string email) { - MembershipCreateStatus status; - _provider.CreateUser(userName, password, email, null, null, true, null, out status); - return status; - } - - public bool ChangePassword(string userName, string oldPassword, string newPassword) { - MembershipUser currentUser = _provider.GetUser(userName, true /* userIsOnline */); - return currentUser.ChangePassword(oldPassword, newPassword); - } - } } |