In SharePoint 2010(like in previous versions) You can enable forms authentication along with standard AD authentication. Thanks to that the internal users can log in to SharePoint using theirs domain accounts and external users can use prepared accounts which are kept in the database. Here is very good instruction step by step how to enable this funcionality.

Now, if You were able to configure mixed authentication then when You’ll try to log in to SharePoint You should see standard login page:

When You select “Windows Authentication” Your AD account will be used. Selecting “Form authentication” will result in showing new page where You will have to provide login and password(not AD account).

You can change this standard page with Your custom login page – it’s very simple. To achieve that You have to create a new .aspx page which inherits from Microsoft.SharePoint.IdentityModel.Pages.FormsSignInPage class.

Below You can find the code for .aspx page with some comments:

<%@ Page Language="C#" MasterPageFile="~/_layouts/simple.master" AutoEventWireup="true" Inherits="zavaz.CustomLoginPage.Forms.ASPX.SignInForm, zavaz.CustomLoginPage.Forms, Version=1.0.0.0, Culture=neutral, PublicKeyToken=17b6953c6c0dd4db" %>

<%@ Assembly Name="Microsoft.SharePoint.ApplicationPages, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c"%>

<%@ Import Namespace="Microsoft.SharePoint.ApplicationPages" %>

<%@ Register Tagprefix="SharePoint" Namespace="Microsoft.SharePoint.WebControls" Assembly="Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>

<%@ Register Tagprefix="Utilities" Namespace="Microsoft.SharePoint.Utilities" Assembly="Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>

<%@ Import Namespace="Microsoft.SharePoint" %>

<%@ Assembly Name="Microsoft.Web.CommandUI, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>

<asp:Content ContentPlaceHolderId="PlaceHolderAdditionalPageHead" runat="server">

 //Loading jQuery scripts
 <script language="javascript" type="text/javascript" src="/_layouts/zavaz.CustomLoginPage/JS/jquery.min.js" ></script>
 <script language="javascript" type="text/javascript" src="/_layouts/zavaz.CustomLoginPage/JS/jquery.corner.js" ></script>

 <script language="javascript" type="text/javascript" >

 $(document).ready(function () {
 //Hidding unnecessary elements from masterpage
 $('#s4-simple-card').attr("id", "s4-simple-card2");
 $('#s4-simple-header').hide();
 $('#s4-simple-card-top').hide();
 $('#s4-simple-card-content').css("margin", "0px");
 $('.s4-simple-iconcont').hide();
 $('#s4-simple-content').css("margin", "0px");
 $('#s4-simple-content h1:first').hide();
 $('.s4-die').hide();
 //-------------------

 //Round corners of the div
 $('.rounded').corner("10px");
 });
 </script>

 <style type="text/css">

 html, body {height:100%; margin:0; padding:0;}

 #page-background {position:fixed; top:0; left:0; width:100%; height:100%;}

 #content {position:relative; z-index:1; padding:10px;}

 </style>

</asp:Content>

<asp:Content ContentPlaceHolderId="PlaceHolderPageTitle" runat="server">

 //Required from inherited class "FormsSignInPage"
 <SharePoint:EncodedLiteral ID="ClaimsFormsPageTitle" runat="server" text="<%$Resources:wss,login_pagetitle%>" EncodeMethod='HtmlEncode'/>

</asp:Content>

<asp:Content ContentPlaceHolderId="PlaceHolderPageTitleInTitleArea" runat="server">

 //Required from inherited class "FormsSignInPage"
 <SharePoint:EncodedLiteral ID="ClaimsFormsPageTitleInTitleArea" runat="server" text="<%$Resources:wss,login_pagetitle%>" EncodeMethod='HtmlEncode'/>

</asp:Content>

<asp:Content ContentPlaceHolderId="PlaceHolderSiteName" runat="server"/>

<asp:Content ContentPlaceHolderId="PlaceHolderMain" runat="server">

 <div style="background-color: Black; width: 100%; height: 100px">
 <br />
 <img src='/_layouts/images/zavaz.CustomLoginPage/Logo.png' alt='' />
 </div>
 <div style="background-color: Gray; width: 100%; height: 10px"></div>
 <center>
 <div id="content" class="rounded" style="width: 300px; height: auto; margin-top: 15%; background:transparent; filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#99000000,endColorstr=#99000000); zoom: 1;">

 //Standard Login control with set custom MembershipProvider FBAMembershipProvider
 <asp:Login ID="signInControl" style="width: 250px" FailureText="<%$Resources:wss,login_pageFailureText%>" MembershipProvider="FBAMembershipProvider"
 runat="server" DisplayRememberMe="true" TextBoxStyle-Width="250px" RememberMeSet="true" LoginButtonStyle-CssClass="ms-buttonheightwidth" UserNameLabelText="User name" TextLayout="TextOnTop" PasswordLabelText="Password" LabelStyle-Font-Bold="false" LabelStyle-Font-Size="Large" LabelStyle-ForeColor="White" LabelStyle-Font-Names="Calibri" LabelStyle-CssClass="ms-standardheader ms-inputformheader" TextBoxStyle-CssClass="ms-input" CheckBoxStyle-Font-Bold="false" CheckBoxStyle-Font-Names="Calibri" CheckBoxStyle-ForeColor="White" CheckBoxStyle-CssClass="ms-standardheader ms-inputformheader" CheckBoxStyle-Font-Size="Large" FailureTextStyle-Wrap="true" FailureTextStyle-Font-Names="Calibri" FailureTextStyle-Font-Size="Small" LoginButtonStyle-Font-Names="Calibri" LoginButtonStyle-Font-Size="Large" LoginButtonImageUrl="/_layouts/images/zavaz.CustomLoginPage/GoForward.png" LoginButtonType="Image" TitleText="" TitleTextStyle-ForeColor="White" TitleTextStyle-Font-Bold="true" TitleTextStyle-Wrap="true" TitleTextStyle-Font-Names="Calibri" TitleTextStyle-Font-Size="Larger" />

 //Link for internal users to log in using AD account
 <asp:LinkButton ID="lbInternalUsers" Text="Active Directory Login" runat="server" Font-Names="Calibri" Font-Size="Small" CssClass="ms-standardheader ms-inputformheader" Font-Bold="true" ForeColor="Wheat" OnClick="lbInternalUsers_OnClick" />

 //Label displaying errors
 <asp:Label ID="lblError" runat="server" Font-Bold="true" ForeColor="Red" EnableViewState="false"></asp:Label>
 </div>
 </center>

 //Required from inherited class "FormsSignInPage"
 <SharePoint:EncodedLiteral runat="server" EncodeMethod="HtmlEncode" ID="ClaimsFormsPageMessage" Visible="false" />

</asp:Content>

And here is the code behind for the .aspx page:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using Microsoft.SharePoint.IdentityModel.Pages;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Administration;
using Microsoft.SharePoint.Utilities;
using zavaz.CustomLoginPage.Data.Classes;
using zavaz.CustomLoginPage.Data.Helpers;
using System.Diagnostics;
using System.Text.RegularExpressions;

namespace zavaz.CustomLoginPage.Forms.ASPX
{
 public class SignInForm : FormsSignInPage
 {
 protected Label lblError;

 protected override void OnInit(EventArgs e)
 {
 base.OnInit(e);
 }

 protected override void OnLoad(EventArgs e)
 {
 try
 {
 base.OnLoad(e);
 }
 catch { }
 }

 protected void lbInternalUsers_OnClick(object sender, EventArgs e)
 {
 try
 {
 if (null != SPContext.Current && null != SPContext.Current.Site)
 {
 SPIisSettings iisSettings = SPContext.Current.Site.WebApplication.IisSettings[SPUrlZone.Default];
 if (null != iisSettings && iisSettings.UseWindowsClaimsAuthenticationProvider)
 {
 SPAuthenticationProvider provider = iisSettings.WindowsClaimsAuthenticationProvider;
 Redirect(provider);
 }
 }
 }
 catch (Exception ex)
 {
 lblError.Text = ex.Message;
 }
 }

 private void Redirect(SPAuthenticationProvider provider)
 {
 string comp = HttpContext.Current.Request.Url.GetComponents(UriComponents.Query, UriFormat.SafeUnescaped);
 string url = provider.AuthenticationRedirectionUrl.ToString();
 if (provider is SPWindowsAuthenticationProvider)
 {
 comp = EnsureUrl(comp, true);
 }

 SPUtility.Redirect(url, SPRedirectFlags.Default, this.Context, comp);
 }

 private string EnsureUrl(string url, bool urlIsQueryStringOnly)
 {
 if (!url.Contains("ReturnUrl="))
 {
 if (urlIsQueryStringOnly)
 {
 url = url + (string.IsNullOrEmpty(url) ? "" : "&");
 }
 else
 {
 url = url + ((url.IndexOf('?') == -1) ? "?" : "&");
 }
 url = url + "ReturnUrl=";
 }
 return url;
 }
 }
}

The final effect:

SignInPage DOWNLOAD

To use above page You need to:

  1. Copy .dll file to the GAC(for example using gacutil.exe)
  2. .aspx, .js files to the LAYOUTS directory
  3. In the .aspx(line 83) file change the logo image to Your custom one
  4. Configure FBA – link how to do it is at the beggining of this post.