diff options
5 files changed, 67 insertions, 36 deletions
diff --git a/projecttemplates/MvcRelyingParty/Controllers/AuthController.cs b/projecttemplates/MvcRelyingParty/Controllers/AuthController.cs index 84eedc3..da0f18f 100644 --- a/projecttemplates/MvcRelyingParty/Controllers/AuthController.cs +++ b/projecttemplates/MvcRelyingParty/Controllers/AuthController.cs @@ -157,34 +157,39 @@ namespace MvcRelyingParty.Controllers { return View("LogOn"); } - [Authorize, AcceptVerbs(HttpVerbs.Post), ValidateAntiForgeryToken] - public ActionResult AddAuthenticationToken(string openid_identifier) { - Identifier userSuppliedIdentifier; - if (Identifier.TryParse(openid_identifier, out userSuppliedIdentifier)) { - try { - var request = this.RelyingParty.CreateRequest(userSuppliedIdentifier, Realm.AutoDetect, Url.ActionFull("AddAuthenticationTokenReturnTo"), this.PrivacyPolicyUrl); - return request.RedirectingResponse.AsActionResult(); - } catch (ProtocolException ex) { - ModelState.AddModelError("openid_identifier", ex); + [Authorize, AcceptVerbs(HttpVerbs.Post), ValidateAntiForgeryToken, ValidateInput(false)] + public ActionResult AddAuthenticationToken(string openid_openidAuthData) { + IAuthenticationResponse response; + if (!string.IsNullOrEmpty(openid_openidAuthData)) { + var auth = new Uri(openid_openidAuthData); + var headers = new WebHeaderCollection(); + foreach (string header in Request.Headers) { + headers[header] = Request.Headers[header]; } + + // Always say it's a GET since the payload is all in the URL, even the large ones. + HttpRequestInfo clientResponseInfo = new HttpRequestInfo("GET", auth, auth.PathAndQuery, headers, null); + response = this.RelyingParty.GetResponse(clientResponseInfo); } else { - ModelState.AddModelError("openid_identifier", "This doesn't look like a valid OpenID."); + response = this.RelyingParty.GetResponse(); } - - return RedirectToAction("Edit", "Account"); - } - - [Authorize, AcceptVerbs(HttpVerbs.Get | HttpVerbs.Post)] - public ActionResult AddAuthenticationTokenReturnTo(string openid_identifier) { - var response = this.RelyingParty.GetResponse(); if (response != null) { switch (response.Status) { case AuthenticationStatus.Authenticated: - Database.LoggedInUser.AuthenticationTokens.Add(new AuthenticationToken { - ClaimedIdentifier = response.ClaimedIdentifier, - FriendlyIdentifier = response.FriendlyIdentifierForDisplay, - }); - Database.DataContext.SaveChanges(); + string identifierString = response.ClaimedIdentifier; + var existing = Database.DataContext.AuthenticationTokens.Include("User").FirstOrDefault(token => token.ClaimedIdentifier == identifierString); + if (existing == null) { + Database.LoggedInUser.AuthenticationTokens.Add(new AuthenticationToken { + ClaimedIdentifier = response.ClaimedIdentifier, + FriendlyIdentifier = response.FriendlyIdentifierForDisplay, + }); + Database.DataContext.SaveChanges(); + } else { + if (existing.User != Database.LoggedInUser) { + // The supplied token is already bound to a different user account. + // TODO: communicate the problem to the user. + } + } break; default: break; diff --git a/projecttemplates/MvcRelyingParty/Views/Account/AuthenticationTokens.ascx b/projecttemplates/MvcRelyingParty/Views/Account/AuthenticationTokens.ascx index 3e4b920..ad9634f 100644 --- a/projecttemplates/MvcRelyingParty/Views/Account/AuthenticationTokens.ascx +++ b/projecttemplates/MvcRelyingParty/Views/Account/AuthenticationTokens.ascx @@ -1,4 +1,7 @@ <%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<MvcRelyingParty.Models.AccountInfoModel>" %> +<%@ Import Namespace="DotNetOpenAuth.Mvc" %> +<%@ Import Namespace="DotNetOpenAuth.OpenId.RelyingParty" %> + <h3> Login methods </h3> @@ -11,10 +14,15 @@ </ul> <h4>Add a new login method </h4> + <% using(Html.BeginForm("AddAuthenticationToken", "Auth", FormMethod.Post)) { %> - <%= Html.AntiForgeryToken() %> - <label for="openid_identifier">OpenID:</label> - <%= Html.TextBox("openid_identifier")%> - <%= Html.ValidationMessage("openid_identifier")%> - <input type="submit" value="Add token" /> +<%= Html.AntiForgeryToken() %> +<%= Html.Hidden("openid_openidAuthData") %> + +<%= Html.OpenIdSelector(this.Page, new SelectorButton[] { + new SelectorProviderButton("https://me.yahoo.com/", Url.Content("~/Content/images/yahoo.gif")), + new SelectorProviderButton("https://www.google.com/accounts/o8/id", Url.Content("~/Content/images/google.gif")), + new SelectorOpenIdButton(Url.Content("~/Content/images/openid.gif")), +}) %> + <% } %>
\ No newline at end of file diff --git a/projecttemplates/MvcRelyingParty/Views/Account/Edit.aspx b/projecttemplates/MvcRelyingParty/Views/Account/Edit.aspx index 09635f2..7dae05c 100644 --- a/projecttemplates/MvcRelyingParty/Views/Account/Edit.aspx +++ b/projecttemplates/MvcRelyingParty/Views/Account/Edit.aspx @@ -2,15 +2,26 @@ Inherits="System.Web.Mvc.ViewPage<AccountInfoModel>" %> <%@ Import Namespace="MvcRelyingParty.Models" %> +<%@ Import Namespace="DotNetOpenAuth.Mvc" %> +<%@ Import Namespace="DotNetOpenAuth.OpenId.RelyingParty" %> <asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server"> Edit </asp:Content> +<asp:Content ContentPlaceHolderID="Head" runat="server"> + <link rel="Stylesheet" type="text/css" href="<%=Page.ClientScript.GetWebResourceUrl(typeof(DotNetOpenAuth.OpenId.RelyingParty.OpenIdSelector), "DotNetOpenAuth.OpenId.RelyingParty.OpenIdSelector.css")%>" /> + <link rel="Stylesheet" type="text/css" href="<%=Page.ClientScript.GetWebResourceUrl(typeof(DotNetOpenAuth.OpenId.RelyingParty.OpenIdSelector), "DotNetOpenAuth.OpenId.RelyingParty.OpenIdAjaxTextBox.css")%>" /> +</asp:Content> <asp:Content ContentPlaceHolderID="ScriptsArea" runat="server"> - - <script src="../../Scripts/MicrosoftAjax.js" type="text/javascript"></script> - - <script src="../../Scripts/MicrosoftMvcAjax.js" type="text/javascript"></script> - + <script type="text/javascript" src='<%= Url.Content("~/Scripts/MicrosoftAjax.js") %>'></script> + <script type="text/javascript" src='<%= Url.Content("~/Scripts/MicrosoftMvcAjax.js") %>'></script> + <script type="text/javascript" src='<%= Url.Content("~/Scripts/jquery.cookie.js") %>'></script> + <% var selector = new OpenIdSelector(); + selector.TextBox.LogOnText = "ADD"; + selector.TextBox.LogOnToolTip = "Bind this OpenID to your account."; + var additionalOptions = new OpenIdAjaxOptions { + FormIndex = 1, + }; %> + <%= Html.OpenIdSelectorScripts(this.Page, selector, additionalOptions)%> </asp:Content> <asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server"> <h2> diff --git a/src/DotNetOpenAuth/Mvc/OpenIdAjaxOptions.cs b/src/DotNetOpenAuth/Mvc/OpenIdAjaxOptions.cs index d50af97..505165c 100644 --- a/src/DotNetOpenAuth/Mvc/OpenIdAjaxOptions.cs +++ b/src/DotNetOpenAuth/Mvc/OpenIdAjaxOptions.cs @@ -13,10 +13,15 @@ namespace DotNetOpenAuth.Mvc { public class OpenIdAjaxOptions { public OpenIdAjaxOptions() { this.AssertionHiddenFieldId = "openid_openidAuthData"; + this.ReturnUrlHiddenFieldId = "ReturnUrl"; } public string AssertionHiddenFieldId { get; set; } + public string ReturnUrlHiddenFieldId { get; set; } + + public int FormIndex { get; set; } + public bool ShowDiagnosticTrace { get; set; } public bool ShowDiagnosticIFrame { get; set; } diff --git a/src/DotNetOpenAuth/Mvc/OpenIdHelper.cs b/src/DotNetOpenAuth/Mvc/OpenIdHelper.cs index 0df4657..effd635 100644 --- a/src/DotNetOpenAuth/Mvc/OpenIdHelper.cs +++ b/src/DotNetOpenAuth/Mvc/OpenIdHelper.cs @@ -100,12 +100,14 @@ window.openid_trace = {1}; // causes lots of messages", blockBuilder.WriteLine(@" window.postLoginAssertion = function (positiveAssertion) {{ $('#{0}')[0].setAttribute('value', positiveAssertion); - if (!$('#ReturnUrl')[0].value) {{ // popups have no ReturnUrl predefined, but full page LogOn does. - $('#ReturnUrl')[0].setAttribute('value', window.parent.location.href); + if ($('#{1}')[0] && !$('#{1}')[0].value) {{ // popups have no ReturnUrl predefined, but full page LogOn does. + $('#{1}')[0].setAttribute('value', window.parent.location.href); }} - document.forms[0].submit(); + document.forms[{2}].submit(); }};", - additionalOptions.AssertionHiddenFieldId); + additionalOptions.AssertionHiddenFieldId, + additionalOptions.ReturnUrlHiddenFieldId, + additionalOptions.FormIndex); blockBuilder.WriteLine(@" $(function () {{ var box = document.getElementsByName('openid_identifier')[0]; |