Membership API in ASP.NET

{outline||<1> - |.<1> - }

See Also



Creating the Necessary Web Pages

Login.aspx

<asp:Login ID="uxLoginControl" runat="server" VisibleWhenLoggedIn="False" BackColor="#EFF3FB"
    BorderColor="#507CD1" BorderWidth="2px" ForeColor="#333333" BorderStyle="Solid"
    Font-Names="Verdana" Font-Size="Small" CreateUserText="Request new account" 
    DisplayRememberMe="False" PasswordRecoveryText="Forgot password" Width="257px" 
    BorderPadding="0" EnableTheming="True"    
    DestinationPageUrl="~/default.aspx" 
    CreateUserUrl="~/loggedout/RequestNewAccount.aspx"
    PasswordRecoveryUrl="~/loggedout/PasswordRecovery.aspx" >
    
    <TitleTextStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" BorderColor="#507CD1"
        BorderStyle="Solid" BorderWidth="2px" Font-Size="0.9em" />
        
    <InstructionTextStyle Font-Italic="True" ForeColor="Black" />
    
    <TextBoxStyle Font-Size="0.8em" />
    
    <LoginButtonStyle CssClass="PushButton" />
        
</asp:Login>

<script type="text/javascript">
    // set the initial focus to the UserName field
    document.getElementById("ctl00_PageBody_uxLoginControl_UserName").focus();
</script>

Top

PasswordRecovery.aspx

Create the PasswordRecovery.aspx page in the LoggedOut folder.

<asp:PasswordRecovery ID="uxPasswordRecovery" runat="server" BackColor="#EFF3FB"
    BorderColor="#507CD1" BorderPadding="0" BorderStyle="Solid" BorderWidth="2px"
    Font-Names="Verdana" Font-Size="0.8em" QuestionInstructionText="Hello">
    <InstructionTextStyle Font-Italic="True" ForeColor="Black" />
    <SuccessTextStyle Font-Bold="True" ForeColor="#507CD1" />
    <TextBoxStyle Font-Size="0.8em" />
    <TitleTextStyle BackColor="#507CD1" Font-Bold="True" Font-Size="0.9em" ForeColor="White" />
    <SubmitButtonStyle CssClass="PushButton" />
</asp:PasswordRecovery>
<script type="text/javascript">
document.getElementById("ctl00_PageBody_uxPasswordRecovery_UserNameContainerID_UserName").focus();
</script>

Top

PasswordRecovery.aspx.cs

using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;

public partial class passwordRecovery : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        HtmlForm mainForm = (HtmlForm)Master.FindControl("form1");

        if (mainForm != null)
        {
            Control c = uxPasswordRecovery.FindControl("UserNameContainerID");

            if (c != null)
            {
                Button defaultButton = (Button)c.FindControl("SubmitButton");
                if (defaultButton != null)
                    mainForm.DefaultButton = defaultButton.UniqueID;
            }
        }
    }
}

Top

RequestNewAccount.aspx

Create the RequestNewAccount.aspx page in the LoggedOut folder.

<asp:Panel runat="server" ID="uxInputForm">
    <asp:Table runat="server" ID="uxRequestNewAccountTable" BorderColor="#507CD1" BorderWidth="2"
        BorderStyle="Solid">
        
        <%-- Header --%>
        <asp:TableRow>
            <asp:TableCell ColumnSpan="2" BackColor="#507CD1" ForeColor="White" Font-Bold="true"
                Font-Names="Tahoma,Arial" HorizontalAlign="Center">Request New Account
            </asp:TableCell>
        </asp:TableRow>
        
        <%-- User Name --%>
        <asp:TableRow>
            <asp:TableCell Width="150px">User Name:</asp:TableCell>
            <asp:TableCell>
                <asp:TextBox runat="server" ID="uxUserNameTextBox" Width="300px" MaxLength="256" />
                <asp:RequiredFieldValidator runat="server" ID="uxUserNameRequiredValidator" 
                    ControlToValidate="uxUserNameTextBox"
                    EnableClientScript="true" ErrorMessage="User Name is required." Text="*" />
            </asp:TableCell>
        </asp:TableRow>
        
        <%-- Password --%>
        <asp:TableRow>
            <asp:TableCell>
                Password:
            </asp:TableCell>
            <asp:TableCell>
                <asp:TextBox runat="server" ID="uxPasswordTextBox" Width="300px" MaxLength="128"
                    TextMode="Password" />
                <asp:RequiredFieldValidator ID="RequiredFieldValidator1" runat="server" 
                    ControlToValidate="uxPasswordTextBox"
                    ErrorMessage="Password is required." Text="*" />
                <asp:CustomValidator ID="CustomValidator1" runat="server" Text="*" 
                    ControlToValidate="uxPasswordTextBox"
                    ErrorMessage="Password must be 7-128 characters long and contain at least one special character."
                    ValidateEmptyText="false" OnServerValidate="uxPasswordTextBox_ServerValidate"/>
            </asp:TableCell>
        </asp:TableRow>
        
        <%-- Confirm Password --%>
        <asp:TableRow>
            <asp:TableCell>
                Confirm Password:
            </asp:TableCell>
            <asp:TableCell>
                <asp:TextBox runat="server" ID="uxConfirmPasswordTextBox" Width="300px" 
                    MaxLength="128" TextMode="Password" />
                <asp:RequiredFieldValidator ID="RequiredFieldValidator2" runat="server" 
                    ControlToValidate="uxConfirmPasswordTextBox"
                    ErrorMessage="Confirm Password is required." Text="*">
                </asp:RequiredFieldValidator>
                <asp:CompareValidator ID="CompareValidator1" runat="server" Text="*" 
                    ControlToValidate="uxConfirmPasswordTextBox"
                    ControlToCompare="uxPasswordTextBox" 
                    ErrorMessage="Confirm Password must match Password" />
            </asp:TableCell>
        </asp:TableRow>
        
        <%-- Email Address --%>
        <asp:TableRow>
            <asp:TableCell>
                Email:
            </asp:TableCell>
            <asp:TableCell>
                <asp:TextBox runat="server" ID="uxEmailTextBox" Width="300px" MaxLength="256" />
                <asp:RequiredFieldValidator ID="RequiredFieldValidator3" runat="server" 
                    ControlToValidate="uxEmailTextBox"
                    ErrorMessage="Email is required." Text="*">
                </asp:RequiredFieldValidator>
                <asp:RegularExpressionValidator ID="RegularExpressionValidator2" runat="server" 
                    ControlToValidate="uxEmailTextBox"
                    ValidationExpression="^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4}$" 
                    ErrorMessage="Email must be in the format of an email address"
                    Text="*" />
            </asp:TableCell>
        </asp:TableRow>
        
        <%-- First Name --%>
        <asp:TableRow>
            <asp:TableCell>First Name:</asp:TableCell>
            <asp:TableCell>
                <asp:TextBox runat="server" ID="uxFirstNameTextBox" Width="300px" MaxLength="50" />
                <asp:RequiredFieldValidator ID="RequiredFieldValidator4" runat="server" 
                    ControlToValidate="uxFirstNameTextBox"
                    ErrorMessage="First Name is required." Text="*">
                </asp:RequiredFieldValidator>
            </asp:TableCell>
        </asp:TableRow>
        
        <%-- Last Name --%>
        <asp:TableRow>
            <asp:TableCell>Last Name:</asp:TableCell>
            <asp:TableCell>
                <asp:TextBox runat="server" ID="uxLastNameTextBox" Width="300px" MaxLength="50" />
                <asp:RequiredFieldValidator ID="RequiredFieldValidator5" runat="server" 
                    ControlToValidate="uxLastNameTextBox"
                    ErrorMessage="Last Name is required." Text="*">
                </asp:RequiredFieldValidator>
            </asp:TableCell>
        </asp:TableRow>
        
        <%-- Submit Button --%>
        <asp:TableRow>
            <asp:TableCell ColumnSpan="2" HorizontalAlign="Center">
                <asp:Button runat="server" ID="uxSubmitButton" CssClass="PushButton" Text="Submit"
                    OnClick="uxSubmitButton_Click" />
            </asp:TableCell>
        </asp:TableRow>
        
        <%-- Validation Summary --%>
        <asp:TableRow>
            <asp:TableCell ColumnSpan="2">
                <asp:ValidationSummary runat="server" ID="uxValidationSummary" 
                    DisplayMode="BulletList" ShowSummary="true" />
            </asp:TableCell>
        </asp:TableRow>
        
        <%-- Status Label --%>
        <asp:TableRow>
            <asp:TableCell ColumnSpan="2">
                <asp:Label runat="server" ID="uxStatusLabel" ForeColor="DarkRed" />
            </asp:TableCell>
        </asp:TableRow>
    </asp:Table>
</asp:Panel>

<script type="text/javascript">
// set the initial focus  
//    var id = "ctl00_PageBody_uxRequestNewAccountControl_uxUserNameTextBox";
var id = "ctl00_PageBody_uxUserNameTextBox";
var ctl = document.getElementById(id);        
if (ctl != null) ctl.focus();
</script>

Top

RequestNewAccount.aspx.cs

using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;

public partial class LoggedOut_RequestNewAccount : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        //set the default button
        HtmlForm mainForm = (HtmlForm)Master.FindControl("form1");

        if (mainForm != null)// && defaultButton != null)
            mainForm.DefaultButton = uxSubmitButton.UniqueID;
    }
    protected void uxPasswordTextBox_ServerValidate(object sender, ServerValidateEventArgs e)
    {
        if (e.Value.Length < Membership.MinRequiredPasswordLength)
        {
            e.IsValid = false;
        }
        else
        {
            int specialCharactersFound = 0;

            for (int i = 0; i < e.Value.Length; i++)
                if (!char.IsLetterOrDigit(e.Value.ToCharArray()[i]))
                    specialCharactersFound++;

            e.IsValid = (specialCharactersFound >= Membership.MinRequiredNonAlphanumericCharacters);
        }
    }
    protected void uxSubmitButton_Click(object sender, EventArgs e)
    {
        MembershipCreateStatus s;
        Membership.CreateUser(uxUserNameTextBox.Text, uxPasswordTextBox.Text, uxEmailTextBox.Text,
            "Q", "A", false, out s);

        //todo: Update the status bar with the result of the above step

        switch (s)
        {
            case MembershipCreateStatus.DuplicateEmail:
                break;
            case MembershipCreateStatus.DuplicateProviderUserKey:
                break;
            case MembershipCreateStatus.DuplicateUserName:
                break;
            case MembershipCreateStatus.InvalidAnswer:
                break;
            case MembershipCreateStatus.InvalidEmail:
                break;
            case MembershipCreateStatus.InvalidPassword:
                break;
            case MembershipCreateStatus.InvalidProviderUserKey:
                break;
            case MembershipCreateStatus.InvalidQuestion:
                break;
            case MembershipCreateStatus.InvalidUserName:
                break;
            case MembershipCreateStatus.ProviderError:
                break;
            case MembershipCreateStatus.Success:
                // todo: Create LtUserProfile record
                break;
            case MembershipCreateStatus.UserRejected:
                break;
        }
    }
}

Top

Setting Up SQL Server as a Membership Provider

  1. Navigate to C:\(windowsDirectory)\Microsoft.NET\Framework\(versionNumber)
  2. Run aspnet_regsql.exe
  3. The ASP.NET SQL Server Setup Wizard is launched
  4. Follow directions to create the database objects in your app’s existing SQL Server database

Top

Setting Up the SQL Server Instance

Run the following script.

USE [master]
GO
CREATE LOGIN [aspnet] WITH PASSWORD=N'aspnet', DEFAULT_DATABASE=[MyDb], 
CHECK_EXPIRATION=OFF, CHECK_POLICY=OFF
GO
USE [MyDb]
GO
CREATE USER [aspnet] FOR LOGIN [aspnet]
GO
EXEC sp_addrolemember N'aspnet_Membership_FullAccess', N'aspnet'
GO
EXEC sp_addrolemember N'aspnet_Profile_FullAccess', N'aspnet'
GO
EXEC sp_addrolemember N'aspnet_Roles_FullAccess', N'aspnet'
GO

declare @AppName nvarchar(256)
declare @AppId uniqueidentifier

set @AppName = 'MyApp'

exec dbo.aspnet_Applications_CreateApplication @AppName, @AppId output

Top

Setting Up the Web.Config File

Setting the Database Connection String

<configuration>
  <connectionStrings>
    <add name="MyDb" 
      connectionString="Data Source=MyServer;
      Initial Catalog=MyDb;Integrated Security=False;User ID=aspnet;
      Password=aspnet" providerName="System.Data.SqlClient"/>
  </connectionStrings>
</configuration>

Top

Using Forms-Based Security

<configuration>
  <system.web>
    <authentication mode="Forms">
      <forms loginUrl="login.aspx"/>
    </authentication>
  </system.web>
</configuration>

Top

Configuring Membership and Role Providers

Set the connectionStringName the same as the connection string above.

<configuration>
  <system.web>
    <membership defaultProvider="SqlSvrProvider">
      <providers>
        <add name="SqlSvrProvider" 
          type="System.Web.Security.SqlMembershipProvider" 
          connectionStringName="ASPNET" 
          applicationName="MyApp" 
          enablePasswordReset="true" 
          requiresQuestionAndAnswer="true" 
          requiresUniqueEmail="true" 
          passwordFormat="Hashed" 
          maxInvalidPasswordAttempts="5" 
          minRequiredPasswordLength="7" 
          minRequiredNonalphanumericCharacters="1" 
          passwordAttemptWindow="10" 
          passwordStrengthRegularExpression="" 
          />
      </providers>
    </membership>

    <roleManager enabled="true" cacheRolesInCookie="true" 
                defaultProvider="SqlSvrRoleProvider">
      <providers>
        <add name="SqlSvrRoleProvider" 
            type="System.Web.Security.SqlRoleProvider" 
            connectionStringName="ASPNET" 
            applicationName="MyApp"/>
      </providers>
    </roleManager>
  </system.web>
</configuration>

Top

Creating an Administrator Account

On a web page, add the following to the ASPX markup.

<asp:Button runat="server" ID="uxInitButton" Text="Init" OnClick="uxInitButton_Click" />

And add this code to its code-behind.

protected void uxInitButton_Click(object sender, EventArgs e)
{
    MembershipCreateStatus s;
    Membership.CreateUser("admin", "password", "email", "Q", "A", true, out s);
    Roles.CreateRole("Administrator");
    Roles.AddUserToRole("admin", "Administrator");
}

Then run the website and click the button to create the admin user.

Top

Configuring Access to Pages and Folders

Note: In the section, the following special characters are used.
CharacterMeaning
?Anonymous users (i.e., those not-logged in)
*All authenticated users (i.e., those logged in)

Top

Using Basic Security

The following configuration will grant access to you entire website only to authorized users.

<configuration>
  <system.web>
    <authorization>
      <deny users="?"/>
      <allow users="*"/>
    </authorization>
  </system.web>
</configuration>

Granting Public Access to Pages

Top For each file or folder, create a <location> node. Note that only the FIRST matching rule (i.e., that the current user matches to) is applied.

<configuration>
  </system.web>
  <location path="default.aspx">
    <system.web>
      <authorization>
        <allow users="?"/>
      </authorization>
    </system.web>
  </location>
</configuration>

To allow only adminstrators access to an Admin folder, you could do this.

<configuration>
   ...
   </system.web>
   <location path="Admin">
      <system.web>
         <authorization>
            <allow roles="Administrator"/>
            <deny users="*" />
            <deny users="?" />
         </authorization>
      </system.web>
   </location>
</configuration>

Here is a typical web.config setup.

<configuration>
    . . .
    <system.web>
        <authorization>
            <deny users="?" />
            <allow users="*" />
        </authorization>
    </system.web>
    . . .
    <location path="Admin">
        <system.web>
            <authorization>
                <allow roles="Admin" />
                <deny users="*" />
                <deny users="?" />
            </authorization>
        </system.web>
    </location>
    . . .
    <location path="DailyBudgetReport">
        <system.web>
            <authorization>
                <allow roles="Accountant" />
                <allow roles="Executive" />
                <deny users="*" />
                <deny users="?" />
            </authorization>
        </system.web>
    </location>
    . . .
</configuration>

Top

Using the CreateUserWizard Control

Set the DisableCreatedUser property to True. This will cause any user who signs up for an account to have to be approved before their account is active.

Top