summaryrefslogtreecommitdiffstats
path: root/samples/TestAzureAD/Account
diff options
context:
space:
mode:
Diffstat (limited to 'samples/TestAzureAD/Account')
-rw-r--r--samples/TestAzureAD/Account/Login.aspx47
-rw-r--r--samples/TestAzureAD/Account/Login.aspx.cs24
-rw-r--r--samples/TestAzureAD/Account/Login.aspx.designer.cs35
-rw-r--r--samples/TestAzureAD/Account/Manage.aspx126
-rw-r--r--samples/TestAzureAD/Account/Manage.aspx.cs95
-rw-r--r--samples/TestAzureAD/Account/Manage.aspx.designer.cs66
-rw-r--r--samples/TestAzureAD/Account/OpenAuthProviders.ascx21
-rw-r--r--samples/TestAzureAD/Account/OpenAuthProviders.ascx.cs43
-rw-r--r--samples/TestAzureAD/Account/OpenAuthProviders.ascx.designer.cs27
-rw-r--r--samples/TestAzureAD/Account/Register.aspx62
-rw-r--r--samples/TestAzureAD/Account/Register.aspx.cs31
-rw-r--r--samples/TestAzureAD/Account/Register.aspx.designer.cs35
-rw-r--r--samples/TestAzureAD/Account/RegisterExternalLogin.aspx35
-rw-r--r--samples/TestAzureAD/Account/RegisterExternalLogin.aspx.cs151
-rw-r--r--samples/TestAzureAD/Account/RegisterExternalLogin.aspx.designer.cs39
-rw-r--r--samples/TestAzureAD/Account/Web.config12
16 files changed, 849 insertions, 0 deletions
diff --git a/samples/TestAzureAD/Account/Login.aspx b/samples/TestAzureAD/Account/Login.aspx
new file mode 100644
index 0000000..42ec544
--- /dev/null
+++ b/samples/TestAzureAD/Account/Login.aspx
@@ -0,0 +1,47 @@
+<%@ Page Title="Log in" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="Login.aspx.cs" Inherits="TestAzureAD.Account.Login" %>
+<%@ Register Src="~/Account/OpenAuthProviders.ascx" TagPrefix="uc" TagName="OpenAuthProviders" %>
+
+<asp:Content runat="server" ID="BodyContent" ContentPlaceHolderID="MainContent">
+ <hgroup class="title">
+ <h1><%: Title %>.</h1>
+ </hgroup>
+ <section id="loginForm">
+ <h2>Use a local account to log in.</h2>
+ <asp:Login runat="server" ViewStateMode="Disabled" RenderOuterTable="false">
+ <LayoutTemplate>
+ <p class="validation-summary-errors">
+ <asp:Literal runat="server" ID="FailureText" />
+ </p>
+ <fieldset>
+ <legend>Log in Form</legend>
+ <ol>
+ <li>
+ <asp:Label runat="server" AssociatedControlID="UserName">User name</asp:Label>
+ <asp:TextBox runat="server" ID="UserName" />
+ <asp:RequiredFieldValidator runat="server" ControlToValidate="UserName" CssClass="field-validation-error" ErrorMessage="The user name field is required." />
+ </li>
+ <li>
+ <asp:Label runat="server" AssociatedControlID="Password">Password</asp:Label>
+ <asp:TextBox runat="server" ID="Password" TextMode="Password" />
+ <asp:RequiredFieldValidator runat="server" ControlToValidate="Password" CssClass="field-validation-error" ErrorMessage="The password field is required." />
+ </li>
+ <li>
+ <asp:CheckBox runat="server" ID="RememberMe" />
+ <asp:Label runat="server" AssociatedControlID="RememberMe" CssClass="checkbox">Remember me?</asp:Label>
+ </li>
+ </ol>
+ <asp:Button runat="server" CommandName="Login" Text="Log in" />
+ </fieldset>
+ </LayoutTemplate>
+ </asp:Login>
+ <p>
+ <asp:HyperLink runat="server" ID="RegisterHyperLink" ViewStateMode="Disabled">Register</asp:HyperLink>
+ if you don't have an account.
+ </p>
+ </section>
+
+ <section id="socialLoginForm">
+ <h2>Use another service to log in.</h2>
+ <uc:OpenAuthProviders runat="server" ID="OpenAuthLogin" />
+ </section>
+</asp:Content>
diff --git a/samples/TestAzureAD/Account/Login.aspx.cs b/samples/TestAzureAD/Account/Login.aspx.cs
new file mode 100644
index 0000000..de1bc9d
--- /dev/null
+++ b/samples/TestAzureAD/Account/Login.aspx.cs
@@ -0,0 +1,24 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Web;
+using System.Web.UI;
+using System.Web.UI.WebControls;
+
+namespace TestAzureAD.Account
+{
+ public partial class Login : Page
+ {
+ protected void Page_Load(object sender, EventArgs e)
+ {
+ RegisterHyperLink.NavigateUrl = "Register.aspx";
+ OpenAuthLogin.ReturnUrl = Request.QueryString["ReturnUrl"];
+
+ var returnUrl = HttpUtility.UrlEncode(Request.QueryString["ReturnUrl"]);
+ if (!String.IsNullOrEmpty(returnUrl))
+ {
+ RegisterHyperLink.NavigateUrl += "?ReturnUrl=" + returnUrl;
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/samples/TestAzureAD/Account/Login.aspx.designer.cs b/samples/TestAzureAD/Account/Login.aspx.designer.cs
new file mode 100644
index 0000000..05da402
--- /dev/null
+++ b/samples/TestAzureAD/Account/Login.aspx.designer.cs
@@ -0,0 +1,35 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+// This code was generated by a tool.
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace TestAzureAD.Account
+{
+
+
+ public partial class Login
+ {
+
+ /// <summary>
+ /// RegisterHyperLink control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.HyperLink RegisterHyperLink;
+
+ /// <summary>
+ /// OpenAuthLogin control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::TestAzureAD.Account.OpenAuthProviders OpenAuthLogin;
+ }
+}
diff --git a/samples/TestAzureAD/Account/Manage.aspx b/samples/TestAzureAD/Account/Manage.aspx
new file mode 100644
index 0000000..9045648
--- /dev/null
+++ b/samples/TestAzureAD/Account/Manage.aspx
@@ -0,0 +1,126 @@
+<%@ Page Title="Manage Account" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="Manage.aspx.cs" Inherits="TestAzureAD.Account.Manage" %>
+<%@ Register Src="~/Account/OpenAuthProviders.ascx" TagPrefix="uc" TagName="OpenAuthProviders" %>
+
+<asp:Content ContentPlaceHolderID="MainContent" runat="server">
+ <hgroup class="title">
+ <h1><%: Title %>.</h1>
+ </hgroup>
+
+ <section id="passwordForm">
+ <asp:PlaceHolder runat="server" ID="successMessage" Visible="false" ViewStateMode="Disabled">
+ <p class="message-success"><%: SuccessMessage %></p>
+ </asp:PlaceHolder>
+
+ <p>You're logged in as <strong><%: User.Identity.Name %></strong>.</p>
+
+ <asp:PlaceHolder runat="server" ID="setPassword" Visible="false">
+ <p>
+ You do not have a local password for this site. Add a local
+ password so you can log in without an external login.
+ </p>
+ <fieldset>
+ <legend>Set Password Form</legend>
+ <ol>
+ <li>
+ <asp:Label runat="server" AssociatedControlID="password">Password</asp:Label>
+ <asp:TextBox runat="server" ID="password" TextMode="Password" />
+ <asp:RequiredFieldValidator runat="server" ControlToValidate="password"
+ CssClass="field-validation-error" ErrorMessage="The password field is required."
+ Display="Dynamic" ValidationGroup="SetPassword" />
+
+ <asp:ModelErrorMessage runat="server" ModelStateKey="NewPassword" AssociatedControlID="password"
+ CssClass="field-validation-error" SetFocusOnError="true" />
+
+ </li>
+ <li>
+ <asp:Label runat="server" AssociatedControlID="confirmPassword">Confirm password</asp:Label>
+ <asp:TextBox runat="server" ID="confirmPassword" TextMode="Password" />
+ <asp:RequiredFieldValidator runat="server" ControlToValidate="confirmPassword"
+ CssClass="field-validation-error" Display="Dynamic" ErrorMessage="The confirm password field is required."
+ ValidationGroup="SetPassword" />
+ <asp:CompareValidator runat="server" ControlToCompare="Password" ControlToValidate="confirmPassword"
+ CssClass="field-validation-error" Display="Dynamic" ErrorMessage="The password and confirmation password do not match."
+ ValidationGroup="SetPassword" />
+ </li>
+ </ol>
+ <asp:Button runat="server" Text="Set Password" ValidationGroup="SetPassword" OnClick="setPassword_Click" />
+ </fieldset>
+ </asp:PlaceHolder>
+
+ <asp:PlaceHolder runat="server" ID="changePassword" Visible="false">
+ <h3>Change password</h3>
+ <asp:ChangePassword runat="server" CancelDestinationPageUrl="~/" ViewStateMode="Disabled" RenderOuterTable="false" SuccessPageUrl="Manage.aspx?m=ChangePwdSuccess">
+ <ChangePasswordTemplate>
+ <p class="validation-summary-errors">
+ <asp:Literal runat="server" ID="FailureText" />
+ </p>
+ <fieldset class="changePassword">
+ <legend>Change password details</legend>
+ <ol>
+ <li>
+ <asp:Label runat="server" ID="CurrentPasswordLabel" AssociatedControlID="CurrentPassword">Current password</asp:Label>
+ <asp:TextBox runat="server" ID="CurrentPassword" CssClass="passwordEntry" TextMode="Password" />
+ <asp:RequiredFieldValidator runat="server" ControlToValidate="CurrentPassword"
+ CssClass="field-validation-error" ErrorMessage="The current password field is required."
+ ValidationGroup="ChangePassword" />
+ </li>
+ <li>
+ <asp:Label runat="server" ID="NewPasswordLabel" AssociatedControlID="NewPassword">New password</asp:Label>
+ <asp:TextBox runat="server" ID="NewPassword" CssClass="passwordEntry" TextMode="Password" />
+ <asp:RequiredFieldValidator runat="server" ControlToValidate="NewPassword"
+ CssClass="field-validation-error" ErrorMessage="The new password is required."
+ ValidationGroup="ChangePassword" />
+ </li>
+ <li>
+ <asp:Label runat="server" ID="ConfirmNewPasswordLabel" AssociatedControlID="ConfirmNewPassword">Confirm new password</asp:Label>
+ <asp:TextBox runat="server" ID="ConfirmNewPassword" CssClass="passwordEntry" TextMode="Password" />
+ <asp:RequiredFieldValidator runat="server" ControlToValidate="ConfirmNewPassword"
+ CssClass="field-validation-error" Display="Dynamic" ErrorMessage="Confirm new password is required."
+ ValidationGroup="ChangePassword" />
+ <asp:CompareValidator runat="server" ControlToCompare="NewPassword" ControlToValidate="ConfirmNewPassword"
+ CssClass="field-validation-error" Display="Dynamic" ErrorMessage="The new password and confirmation password do not match."
+ ValidationGroup="ChangePassword" />
+ </li>
+ </ol>
+ <asp:Button runat="server" CommandName="ChangePassword" Text="Change password" ValidationGroup="ChangePassword" />
+ </fieldset>
+ </ChangePasswordTemplate>
+ </asp:ChangePassword>
+ </asp:PlaceHolder>
+ </section>
+
+ <section id="externalLoginsForm">
+
+ <asp:ListView runat="server"
+ ItemType="Microsoft.AspNet.Membership.OpenAuth.OpenAuthAccountData"
+ SelectMethod="GetExternalLogins" DeleteMethod="RemoveExternalLogin" DataKeyNames="ProviderName,ProviderUserId">
+
+ <LayoutTemplate>
+ <h3>Registered external logins</h3>
+ <table>
+ <thead><tr><th>Service</th><th>User Name</th><th>Last Used</th><th>&nbsp;</th></tr></thead>
+ <tbody>
+ <tr runat="server" id="itemPlaceholder"></tr>
+ </tbody>
+ </table>
+ </LayoutTemplate>
+ <ItemTemplate>
+ <tr>
+
+ <td><%#: Item.ProviderDisplayName %></td>
+ <td><%#: Item.ProviderUserName %></td>
+ <td><%#: ConvertToDisplayDateTime(Item.LastUsedUtc) %></td>
+ <td>
+ <asp:Button runat="server" Text="Remove" CommandName="Delete" CausesValidation="false"
+ ToolTip='<%# "Remove this " + Item.ProviderDisplayName + " login from your account" %>'
+ Visible="<%# CanRemoveExternalLogins %>" />
+ </td>
+
+ </tr>
+ </ItemTemplate>
+ </asp:ListView>
+
+ <h3>Add an external login</h3>
+ <uc:OpenAuthProviders runat="server" ReturnUrl="~/Account/Manage.aspx" />
+ </section>
+</asp:Content>
diff --git a/samples/TestAzureAD/Account/Manage.aspx.cs b/samples/TestAzureAD/Account/Manage.aspx.cs
new file mode 100644
index 0000000..98ca4c7
--- /dev/null
+++ b/samples/TestAzureAD/Account/Manage.aspx.cs
@@ -0,0 +1,95 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+using Microsoft.AspNet.Membership.OpenAuth;
+
+namespace TestAzureAD.Account
+{
+ public partial class Manage : System.Web.UI.Page
+ {
+ protected string SuccessMessage
+ {
+ get;
+ private set;
+ }
+
+ protected bool CanRemoveExternalLogins
+ {
+ get;
+ private set;
+ }
+
+ protected void Page_Load()
+ {
+ if (!IsPostBack)
+ {
+ // Determine the sections to render
+ var hasLocalPassword = OpenAuth.HasLocalPassword(User.Identity.Name);
+ setPassword.Visible = !hasLocalPassword;
+ changePassword.Visible = hasLocalPassword;
+
+ CanRemoveExternalLogins = hasLocalPassword;
+
+ // Render success message
+ var message = Request.QueryString["m"];
+ if (message != null)
+ {
+ // Strip the query string from action
+ Form.Action = ResolveUrl("~/Account/Manage.aspx");
+
+ SuccessMessage =
+ message == "ChangePwdSuccess" ? "Your password has been changed."
+ : message == "SetPwdSuccess" ? "Your password has been set."
+ : message == "RemoveLoginSuccess" ? "The external login was removed."
+ : String.Empty;
+ successMessage.Visible = !String.IsNullOrEmpty(SuccessMessage);
+ }
+ }
+
+ }
+
+ protected void setPassword_Click(object sender, EventArgs e)
+ {
+ if (IsValid)
+ {
+ var result = OpenAuth.AddLocalPassword(User.Identity.Name, password.Text);
+ if (result.IsSuccessful)
+ {
+ Response.Redirect("~/Account/Manage.aspx?m=SetPwdSuccess");
+ }
+ else
+ {
+
+ ModelState.AddModelError("NewPassword", result.ErrorMessage);
+
+ }
+ }
+ }
+
+
+ public IEnumerable<OpenAuthAccountData> GetExternalLogins()
+ {
+ var accounts = OpenAuth.GetAccountsForUser(User.Identity.Name);
+ CanRemoveExternalLogins = CanRemoveExternalLogins || accounts.Count() > 1;
+ return accounts;
+ }
+
+ public void RemoveExternalLogin(string providerName, string providerUserId)
+ {
+ var m = OpenAuth.DeleteAccount(User.Identity.Name, providerName, providerUserId)
+ ? "?m=RemoveLoginSuccess"
+ : String.Empty;
+ Response.Redirect("~/Account/Manage.aspx" + m);
+ }
+
+
+ protected static string ConvertToDisplayDateTime(DateTime? utcDateTime)
+ {
+ // You can change this method to convert the UTC date time into the desired display
+ // offset and format. Here we're converting it to the server timezone and formatting
+ // as a short date and a long time string, using the current thread culture.
+ return utcDateTime.HasValue ? utcDateTime.Value.ToLocalTime().ToString("G") : "[never]";
+ }
+ }
+} \ No newline at end of file
diff --git a/samples/TestAzureAD/Account/Manage.aspx.designer.cs b/samples/TestAzureAD/Account/Manage.aspx.designer.cs
new file mode 100644
index 0000000..1c70310
--- /dev/null
+++ b/samples/TestAzureAD/Account/Manage.aspx.designer.cs
@@ -0,0 +1,66 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+// This code was generated by a tool.
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace TestAzureAD.Account
+{
+
+
+ public partial class Manage
+ {
+
+ /// <summary>
+ /// successMessage control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.PlaceHolder successMessage;
+
+ /// <summary>
+ /// setPassword control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.PlaceHolder setPassword;
+
+ /// <summary>
+ /// password control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.TextBox password;
+
+
+
+ /// <summary>
+ /// confirmPassword control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.TextBox confirmPassword;
+
+ /// <summary>
+ /// changePassword control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.PlaceHolder changePassword;
+
+
+ }
+}
diff --git a/samples/TestAzureAD/Account/OpenAuthProviders.ascx b/samples/TestAzureAD/Account/OpenAuthProviders.ascx
new file mode 100644
index 0000000..e57633b
--- /dev/null
+++ b/samples/TestAzureAD/Account/OpenAuthProviders.ascx
@@ -0,0 +1,21 @@
+<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="OpenAuthProviders.ascx.cs" Inherits="TestAzureAD.Account.OpenAuthProviders" %>
+
+<fieldset class="open-auth-providers">
+ <legend>Log in using another service</legend>
+
+ <asp:ListView runat="server" ID="providerDetails" ItemType="Microsoft.AspNet.Membership.OpenAuth.ProviderDetails"
+ SelectMethod="GetProviderNames" ViewStateMode="Disabled">
+ <ItemTemplate>
+ <button type="submit" name="provider" value="<%#: Item.ProviderName %>"
+ title="Log in using your <%#: Item.ProviderDisplayName %> account.">
+ <%#: Item.ProviderDisplayName %>
+ </button>
+ </ItemTemplate>
+
+ <EmptyDataTemplate>
+ <div class="message-info">
+ <p>There are no external authentication services configured. See <a href="http://go.microsoft.com/fwlink/?LinkId=252803">this article</a> for details on setting up this ASP.NET application to support logging in via external services.</p>
+ </div>
+ </EmptyDataTemplate>
+ </asp:ListView>
+</fieldset> \ No newline at end of file
diff --git a/samples/TestAzureAD/Account/OpenAuthProviders.ascx.cs b/samples/TestAzureAD/Account/OpenAuthProviders.ascx.cs
new file mode 100644
index 0000000..2058c27
--- /dev/null
+++ b/samples/TestAzureAD/Account/OpenAuthProviders.ascx.cs
@@ -0,0 +1,43 @@
+using System;
+using System.Collections.Generic;
+using System.Web;
+using Microsoft.AspNet.Membership.OpenAuth;
+
+namespace TestAzureAD.Account
+{
+ public partial class OpenAuthProviders : System.Web.UI.UserControl
+ {
+ protected void Page_Load(object sender, EventArgs e)
+ {
+
+ if (IsPostBack)
+ {
+ var provider = Request.Form["provider"];
+ if (provider == null)
+ {
+ return;
+ }
+
+ var redirectUrl = "~/Account/RegisterExternalLogin.aspx";
+ if (!String.IsNullOrEmpty(ReturnUrl))
+ {
+ var resolvedReturnUrl = ResolveUrl(ReturnUrl);
+ redirectUrl += "?ReturnUrl=" + HttpUtility.UrlEncode(resolvedReturnUrl);
+ }
+
+ OpenAuth.RequestAuthentication(provider, redirectUrl);
+ }
+ }
+
+
+
+ public string ReturnUrl { get; set; }
+
+
+ public IEnumerable<ProviderDetails> GetProviderNames()
+ {
+ return OpenAuth.AuthenticationClients.GetAll();
+ }
+
+ }
+} \ No newline at end of file
diff --git a/samples/TestAzureAD/Account/OpenAuthProviders.ascx.designer.cs b/samples/TestAzureAD/Account/OpenAuthProviders.ascx.designer.cs
new file mode 100644
index 0000000..cfd1af8
--- /dev/null
+++ b/samples/TestAzureAD/Account/OpenAuthProviders.ascx.designer.cs
@@ -0,0 +1,27 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+// This code was generated by a tool.
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace TestAzureAD.Account
+{
+
+
+ public partial class OpenAuthProviders
+ {
+
+ /// <summary>
+ /// providerDetails control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.ListView providerDetails;
+
+ }
+}
diff --git a/samples/TestAzureAD/Account/Register.aspx b/samples/TestAzureAD/Account/Register.aspx
new file mode 100644
index 0000000..7958963
--- /dev/null
+++ b/samples/TestAzureAD/Account/Register.aspx
@@ -0,0 +1,62 @@
+<%@ Page Title="Register" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="Register.aspx.cs" Inherits="TestAzureAD.Account.Register" %>
+
+<asp:Content runat="server" ID="BodyContent" ContentPlaceHolderID="MainContent">
+ <hgroup class="title">
+ <h1><%: Title %>.</h1>
+ <h2>Use the form below to create a new account.</h2>
+ </hgroup>
+
+ <asp:CreateUserWizard runat="server" ID="RegisterUser" ViewStateMode="Disabled" OnCreatedUser="RegisterUser_CreatedUser">
+ <LayoutTemplate>
+ <asp:PlaceHolder runat="server" ID="wizardStepPlaceholder" />
+ <asp:PlaceHolder runat="server" ID="navigationPlaceholder" />
+ </LayoutTemplate>
+ <WizardSteps>
+ <asp:CreateUserWizardStep runat="server" ID="RegisterUserWizardStep">
+ <ContentTemplate>
+ <p class="message-info">
+ Passwords are required to be a minimum of <%: Membership.MinRequiredPasswordLength %> characters in length.
+ </p>
+
+ <p class="validation-summary-errors">
+ <asp:Literal runat="server" ID="ErrorMessage" />
+ </p>
+
+ <fieldset>
+ <legend>Registration Form</legend>
+ <ol>
+ <li>
+ <asp:Label runat="server" AssociatedControlID="UserName">User name</asp:Label>
+ <asp:TextBox runat="server" ID="UserName" />
+ <asp:RequiredFieldValidator runat="server" ControlToValidate="UserName"
+ CssClass="field-validation-error" ErrorMessage="The user name field is required." />
+ </li>
+ <li>
+ <asp:Label runat="server" AssociatedControlID="Email">Email address</asp:Label>
+ <asp:TextBox runat="server" ID="Email" TextMode="Email" />
+ <asp:RequiredFieldValidator runat="server" ControlToValidate="Email"
+ CssClass="field-validation-error" ErrorMessage="The email address field is required." />
+ </li>
+ <li>
+ <asp:Label runat="server" AssociatedControlID="Password">Password</asp:Label>
+ <asp:TextBox runat="server" ID="Password" TextMode="Password" />
+ <asp:RequiredFieldValidator runat="server" ControlToValidate="Password"
+ CssClass="field-validation-error" ErrorMessage="The password field is required." />
+ </li>
+ <li>
+ <asp:Label runat="server" AssociatedControlID="ConfirmPassword">Confirm password</asp:Label>
+ <asp:TextBox runat="server" ID="ConfirmPassword" TextMode="Password" />
+ <asp:RequiredFieldValidator runat="server" ControlToValidate="ConfirmPassword"
+ CssClass="field-validation-error" Display="Dynamic" ErrorMessage="The confirm password field is required." />
+ <asp:CompareValidator runat="server" ControlToCompare="Password" ControlToValidate="ConfirmPassword"
+ CssClass="field-validation-error" Display="Dynamic" ErrorMessage="The password and confirmation password do not match." />
+ </li>
+ </ol>
+ <asp:Button runat="server" CommandName="MoveNext" Text="Register" />
+ </fieldset>
+ </ContentTemplate>
+ <CustomNavigationTemplate />
+ </asp:CreateUserWizardStep>
+ </WizardSteps>
+ </asp:CreateUserWizard>
+</asp:Content> \ No newline at end of file
diff --git a/samples/TestAzureAD/Account/Register.aspx.cs b/samples/TestAzureAD/Account/Register.aspx.cs
new file mode 100644
index 0000000..6d0315d
--- /dev/null
+++ b/samples/TestAzureAD/Account/Register.aspx.cs
@@ -0,0 +1,31 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Web;
+using System.Web.Security;
+using System.Web.UI;
+using System.Web.UI.WebControls;
+using Microsoft.AspNet.Membership.OpenAuth;
+
+namespace TestAzureAD.Account
+{
+ public partial class Register : Page
+ {
+ protected void Page_Load(object sender, EventArgs e)
+ {
+ RegisterUser.ContinueDestinationPageUrl = Request.QueryString["ReturnUrl"];
+ }
+
+ protected void RegisterUser_CreatedUser(object sender, EventArgs e)
+ {
+ FormsAuthentication.SetAuthCookie(RegisterUser.UserName, createPersistentCookie: false);
+
+ string continueUrl = RegisterUser.ContinueDestinationPageUrl;
+ if (!OpenAuth.IsLocalUrl(continueUrl))
+ {
+ continueUrl = "~/";
+ }
+ Response.Redirect(continueUrl);
+ }
+ }
+} \ No newline at end of file
diff --git a/samples/TestAzureAD/Account/Register.aspx.designer.cs b/samples/TestAzureAD/Account/Register.aspx.designer.cs
new file mode 100644
index 0000000..641a4b2
--- /dev/null
+++ b/samples/TestAzureAD/Account/Register.aspx.designer.cs
@@ -0,0 +1,35 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+// This code was generated by a tool.
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace TestAzureAD.Account
+{
+
+
+ public partial class Register
+ {
+
+ /// <summary>
+ /// RegisterUser control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.CreateUserWizard RegisterUser;
+
+ /// <summary>
+ /// RegisterUserWizardStep control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.CreateUserWizardStep RegisterUserWizardStep;
+ }
+}
diff --git a/samples/TestAzureAD/Account/RegisterExternalLogin.aspx b/samples/TestAzureAD/Account/RegisterExternalLogin.aspx
new file mode 100644
index 0000000..8424465
--- /dev/null
+++ b/samples/TestAzureAD/Account/RegisterExternalLogin.aspx
@@ -0,0 +1,35 @@
+<%@ Page Language="C#" Title="Register an external login" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="RegisterExternalLogin.aspx.cs" Inherits="TestAzureAD.Account.RegisterExternalLogin" %>
+<asp:Content ContentPlaceHolderID="MainContent" runat="server">
+ <hgroup class="title">
+ <h1>Register with your <%: ProviderDisplayName %> account</h1>
+ <h2><%: ProviderUserName %>.</h2>
+ </hgroup>
+
+
+ <asp:ModelErrorMessage runat="server" ModelStateKey="Provider" CssClass="field-validation-error" />
+
+
+ <asp:PlaceHolder runat="server" ID="userNameForm">
+ <fieldset>
+ <legend>Association Form</legend>
+ <p>
+ You've authenticated with <strong><%: ProviderDisplayName %></strong> as
+ <strong><%: ProviderUserName %></strong>. Please enter a user name below for the current site
+ and click the Log in button.
+ </p>
+ <ol>
+ <li class="email">
+ <asp:Label runat="server" AssociatedControlID="userName">User name</asp:Label>
+ <asp:TextBox runat="server" ID="userName" />
+ <asp:RequiredFieldValidator runat="server" ControlToValidate="userName"
+ Display="Dynamic" ErrorMessage="User name is required" ValidationGroup="NewUser" />
+
+ <asp:ModelErrorMessage runat="server" ModelStateKey="UserName" CssClass="field-validation-error" />
+
+ </li>
+ </ol>
+ <asp:Button runat="server" Text="Log in" ValidationGroup="NewUser" OnClick="logIn_Click" />
+ <asp:Button runat="server" Text="Cancel" CausesValidation="false" OnClick="cancel_Click" />
+ </fieldset>
+ </asp:PlaceHolder>
+</asp:Content>
diff --git a/samples/TestAzureAD/Account/RegisterExternalLogin.aspx.cs b/samples/TestAzureAD/Account/RegisterExternalLogin.aspx.cs
new file mode 100644
index 0000000..dd3d1b4
--- /dev/null
+++ b/samples/TestAzureAD/Account/RegisterExternalLogin.aspx.cs
@@ -0,0 +1,151 @@
+using System;
+using System.Web;
+using System.Web.Security;
+using DotNetOpenAuth.AspNet;
+using Microsoft.AspNet.Membership.OpenAuth;
+
+namespace TestAzureAD.Account
+{
+ public partial class RegisterExternalLogin : System.Web.UI.Page
+ {
+ protected string ProviderName
+ {
+ get { return (string)ViewState["ProviderName"] ?? String.Empty; }
+ private set { ViewState["ProviderName"] = value; }
+ }
+
+ protected string ProviderDisplayName
+ {
+ get { return (string)ViewState["ProviderDisplayName"] ?? String.Empty; }
+ private set { ViewState["ProviderDisplayName"] = value; }
+ }
+
+ protected string ProviderUserId
+ {
+ get { return (string)ViewState["ProviderUserId"] ?? String.Empty; }
+ private set { ViewState["ProviderUserId"] = value; }
+ }
+
+ protected string ProviderUserName
+ {
+ get { return (string)ViewState["ProviderUserName"] ?? String.Empty; }
+ private set { ViewState["ProviderUserName"] = value; }
+ }
+
+ protected void Page_Load()
+ {
+ if (!IsPostBack)
+ {
+ ProcessProviderResult();
+ }
+ }
+
+ protected void logIn_Click(object sender, EventArgs e)
+ {
+ CreateAndLoginUser();
+ }
+
+ protected void cancel_Click(object sender, EventArgs e)
+ {
+ RedirectToReturnUrl();
+ }
+
+ private void ProcessProviderResult()
+ {
+ // Process the result from an auth provider in the request
+ ProviderName = OpenAuth.GetProviderNameFromCurrentRequest();
+
+ if (String.IsNullOrEmpty(ProviderName))
+ {
+ Response.Redirect(FormsAuthentication.LoginUrl);
+ }
+
+ // Build the redirect url for OpenAuth verification
+ var redirectUrl = "~/Account/RegisterExternalLogin.aspx";
+ var returnUrl = Request.QueryString["ReturnUrl"];
+ if (!String.IsNullOrEmpty(returnUrl))
+ {
+ redirectUrl += "?ReturnUrl=" + HttpUtility.UrlEncode(returnUrl);
+ }
+
+ // Verify the OpenAuth payload
+ var authResult = OpenAuth.VerifyAuthentication(redirectUrl);
+ ProviderDisplayName = OpenAuth.GetProviderDisplayName(ProviderName);
+ if (!authResult.IsSuccessful)
+ {
+ Title = "External login failed";
+ userNameForm.Visible = false;
+
+ ModelState.AddModelError("Provider", String.Format("External login {0} failed.", ProviderDisplayName));
+
+ // To view this error, enable page tracing in web.config (<system.web><trace enabled="true"/></system.web>) and visit ~/Trace.axd
+ Trace.Warn("OpenAuth", String.Format("There was an error verifying authentication with {0})", ProviderDisplayName), authResult.Error);
+ return;
+ }
+
+ // User has logged in with provider successfully
+ // Check if user is already registered locally
+ if (OpenAuth.Login(authResult.Provider, authResult.ProviderUserId, createPersistentCookie: false))
+ {
+ RedirectToReturnUrl();
+ }
+
+ // Store the provider details in ViewState
+ ProviderName = authResult.Provider;
+ ProviderUserId = authResult.ProviderUserId;
+ ProviderUserName = authResult.UserName;
+
+ // Strip the query string from action
+ Form.Action = ResolveUrl(redirectUrl);
+
+ if (User.Identity.IsAuthenticated)
+ {
+ // User is already authenticated, add the external login and redirect to return url
+ OpenAuth.AddAccountToExistingUser(ProviderName, ProviderUserId, ProviderUserName, User.Identity.Name);
+ RedirectToReturnUrl();
+ }
+ else
+ {
+ // User is new, ask for their desired membership name
+ userName.Text = authResult.UserName;
+ }
+ }
+
+ private void CreateAndLoginUser()
+ {
+ if (!IsValid)
+ {
+ return;
+ }
+
+ var createResult = OpenAuth.CreateUser(ProviderName, ProviderUserId, ProviderUserName, userName.Text);
+ if (!createResult.IsSuccessful)
+ {
+
+ ModelState.AddModelError("UserName", createResult.ErrorMessage);
+
+ }
+ else
+ {
+ // User created & associated OK
+ if (OpenAuth.Login(ProviderName, ProviderUserId, createPersistentCookie: false))
+ {
+ RedirectToReturnUrl();
+ }
+ }
+ }
+
+ private void RedirectToReturnUrl()
+ {
+ var returnUrl = Request.QueryString["ReturnUrl"];
+ if (!String.IsNullOrEmpty(returnUrl) && OpenAuth.IsLocalUrl(returnUrl))
+ {
+ Response.Redirect(returnUrl);
+ }
+ else
+ {
+ Response.Redirect("~/");
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/samples/TestAzureAD/Account/RegisterExternalLogin.aspx.designer.cs b/samples/TestAzureAD/Account/RegisterExternalLogin.aspx.designer.cs
new file mode 100644
index 0000000..a135f0c
--- /dev/null
+++ b/samples/TestAzureAD/Account/RegisterExternalLogin.aspx.designer.cs
@@ -0,0 +1,39 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+// This code was generated by a tool.
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace TestAzureAD.Account
+{
+
+
+ public partial class RegisterExternalLogin
+ {
+
+
+
+ /// <summary>
+ /// userNameForm control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.PlaceHolder userNameForm;
+
+ /// <summary>
+ /// userName control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.TextBox userName;
+
+
+ }
+}
diff --git a/samples/TestAzureAD/Account/Web.config b/samples/TestAzureAD/Account/Web.config
new file mode 100644
index 0000000..90fe314
--- /dev/null
+++ b/samples/TestAzureAD/Account/Web.config
@@ -0,0 +1,12 @@
+<?xml version="1.0"?>
+<configuration>
+
+ <location path="Manage.aspx">
+ <system.web>
+ <authorization>
+ <deny users="?"/>
+ </authorization>
+ </system.web>
+ </location>
+
+</configuration>