<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>SquaredRoot &#187; authentication</title>
	<atom:link href="http://www.squaredroot.com/tag/authentication/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.squaredroot.com</link>
	<description>.Net Development in DC</description>
	<lastBuildDate>Sun, 16 Aug 2009 01:30:15 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>MVC Authentication and Errors</title>
		<link>http://www.squaredroot.com/2008/01/04/mvc-authentication-and-errors/</link>
		<comments>http://www.squaredroot.com/2008/01/04/mvc-authentication-and-errors/#comments</comments>
		<pubDate>Fri, 04 Jan 2008 05:25:00 +0000</pubDate>
		<dc:creator>Troy Goode</dc:creator>
				<category><![CDATA[MVC]]></category>
		<category><![CDATA[action filters]]></category>
		<category><![CDATA[authentication]]></category>
		<category><![CDATA[error handling]]></category>
		<category><![CDATA[exceptions]]></category>

		<guid isPermaLink="false">/post/2008/01/04/MVC-Authentication-and-Errors.aspx</guid>
		<description><![CDATA[NOTE: This article was written for the December CTP release of the MVC framework. Unfortunately, it does not entirely apply to the Preview 2 release or subsequent releases. I love working with the recent CTP release of the ASP.Net MVC framework, but it is definitely an early release and is lacking many of the developer [...]]]></description>
			<content:encoded><![CDATA[<blockquote><p><strong>NOTE</strong>:<br />
This article was written for the December CTP release of the MVC framework. Unfortunately, it does not entirely apply to the Preview 2 release or subsequent releases.</p></blockquote>
<p>I love working with the <a href="http://weblogs.asp.net/scottgu/archive/2007/12/09/asp-net-3-5-extensions-ctp-preview-released.aspx">recent CTP release</a> of the ASP.Net MVC framework, but it is definitely an early release and is lacking many of the developer friendly features that we have grown to rely upon in WebForms. One such feature is WebForm&#8217;s easy to understand authentication model.</p>
<p>In the WebForms world URLs can be referenced in a web.config file and then have authentication rules applied to them. A rule that says that you must be logged in to view a secure page may look something like:</p>
<p><!--<br />
{rtf1ansiansicpglang1024noproof65001uc1 deff0{fonttbl{f0fnilfcharset0fprq1 Consolas;}}{colortbl;??red0green0blue255;red255green255blue255;red163green21blue21;red255green0blue0;red0green0blue0;}??fs18 cf1 &lt;cf3 locationcf1  cf4 pathcf1 =cf0 "cf1 loginRequired.aspxcf0 "cf1 &gt;par ??tab &lt;cf3 system.webcf1 &gt;par ??tab tab &lt;cf3 authorizationcf1 &gt;par ??tab tab tab &lt;cf3 denycf1  cf4 userscf1 =cf0 "cf1 ?cf0 "cf1  /&gt;par ??tab tab &lt;/cf3 authorizationcf1 &gt;par ??tab &lt;/cf3 system.webcf1 &gt;par ??&lt;/cf3 locationcf1 &gt;}<br />
--></p>
<div style="background: white none repeat scroll 0% 0%; font-size: 9pt; color: black; font-family: courier new; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial">
<p style="margin: 0px"><span style="color: #2b91af"> 1</span> <span style="color: blue">&lt;</span><span style="color: #a31515">location</span><span style="color: blue"> </span><span style="color: red">path</span><span style="color: blue">=</span>&#8220;<span style="color: blue">loginRequired.aspx</span>&#8220;<span style="color: blue">&gt;</span></p>
<p style="margin: 0px"><span style="color: #2b91af"> 2</span> <span style="color: blue"> &lt;</span><span style="color: #a31515">system.web</span><span style="color: blue">&gt;</span></p>
<p style="margin: 0px"><span style="color: #2b91af"> 3</span> <span style="color: blue"> &lt;</span><span style="color: #a31515">authorization</span><span style="color: blue">&gt;</span></p>
<p style="margin: 0px"><span style="color: #2b91af"> 4</span> <span style="color: blue"> &lt;</span><span style="color: #a31515">deny</span><span style="color: blue"> </span><span style="color: red">users</span><span style="color: blue">=</span>&#8220;<span style="color: blue">?</span>&#8220;<span style="color: blue"> /&gt;</span></p>
<p style="margin: 0px"><span style="color: #2b91af"> 5</span> <span style="color: blue"> &lt;/</span><span style="color: #a31515">authorization</span><span style="color: blue">&gt;</span></p>
<p style="margin: 0px"><span style="color: #2b91af"> 6</span> <span style="color: blue"> &lt;/</span><span style="color: #a31515">system.web</span><span style="color: blue">&gt;</span></p>
<p style="margin: 0px"><span style="color: #2b91af"> 7</span> <span style="color: blue">&lt;/</span><span style="color: #a31515">location</span><span style="color: blue">&gt;</span></p>
</div>
<p>A rule that says only users in the Administrators group may view it might look like this:</p>
<p><!--<br />
{rtf1ansiansicpglang1024noproof65001uc1 deff0{fonttbl{f0fnilfcharset0fprq1 Consolas;}}{colortbl;??red0green0blue255;red255green255blue255;red163green21blue21;red255green0blue0;red0green0blue0;}??fs18 cf1 &lt;cf3 locationcf1  cf4 pathcf1 =cf0 "cf1 adminRequired.aspxcf0 "cf1 &gt;par ??tab &lt;cf3 system.webcf1 &gt;par ??tab tab &lt;cf3 authorizationcf1 &gt;par ??tab tab tab &lt;cf3 allowcf1  cf4 rolescf1 =cf0 "cf1 Administratorscf0 "cf1  /&gt;par ??tab tab tab &lt;cf3 denycf1  cf4 userscf1 =cf0 "cf1 *cf0 "cf1  /&gt;par ??tab tab &lt;/cf3 authorizationcf1 &gt;par ??tab &lt;/cf3 system.webcf1 &gt;par ??&lt;/cf3 locationcf1 &gt;}<br />
--></p>
<div style="background: white none repeat scroll 0% 0%; font-size: 9pt; color: black; font-family: courier new; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial">
<p style="margin: 0px"><span style="color: #2b91af"> 1</span> <span style="color: blue">&lt;</span><span style="color: #a31515">location</span><span style="color: blue"> </span><span style="color: red">path</span><span style="color: blue">=</span>&#8220;<span style="color: blue">adminRequired.aspx</span>&#8220;<span style="color: blue">&gt;</span></p>
<p style="margin: 0px"><span style="color: #2b91af"> 2</span> <span style="color: blue"> &lt;</span><span style="color: #a31515">system.web</span><span style="color: blue">&gt;</span></p>
<p style="margin: 0px"><span style="color: #2b91af"> 3</span> <span style="color: blue"> &lt;</span><span style="color: #a31515">authorization</span><span style="color: blue">&gt;</span></p>
<p style="margin: 0px"><span style="color: #2b91af"> 4</span> <span style="color: blue"> &lt;</span><span style="color: #a31515">allow</span><span style="color: blue"> </span><span style="color: red">roles</span><span style="color: blue">=</span>&#8220;<span style="color: blue">Administrators</span>&#8220;<span style="color: blue"> /&gt;</span></p>
<p style="margin: 0px"><span style="color: #2b91af"> 5</span> <span style="color: blue"> &lt;</span><span style="color: #a31515">deny</span><span style="color: blue"> </span><span style="color: red">users</span><span style="color: blue">=</span>&#8220;<span style="color: blue">*</span>&#8220;<span style="color: blue"> /&gt;</span></p>
<p style="margin: 0px"><span style="color: #2b91af"> 6</span> <span style="color: blue"> &lt;/</span><span style="color: #a31515">authorization</span><span style="color: blue">&gt;</span></p>
<p style="margin: 0px"><span style="color: #2b91af"> 7</span> <span style="color: blue"> &lt;/</span><span style="color: #a31515">system.web</span><span style="color: blue">&gt;</span></p>
<p style="margin: 0px"><span style="color: #2b91af"> 8</span> <span style="color: blue">&lt;/</span><span style="color: #a31515">location</span><span style="color: blue">&gt;</span></p>
</div>
<p>It didn&#8217;t take long for me to run into the lack of any central authentication scheme in the new MVC framework. I searched around and found some <a href="http://weblogs.asp.net/fredriknormen/archive/2007/11/25/asp-net-mvc-framework-security.aspx">older information from prior to the CTP release posted by Fredrik Normén</a> that seemed to address my issues, but unfortunately one of the features his solution requires did not make its way into the CTP release: attribute based exception handling.</p>
<p>Looking through the code samples on the page you see how he uses the .Net frameworks built in <a href="http://msdn2.microsoft.com/en-us/library/system.security.permissions.principalpermission.aspx"><strong>PrincipalPermission</strong></a> attribute (from <strong>System.Security.Permissions</strong>) to classify an action as demanding the user be in a specific role. If the user is not in that role the .Net framework will throw a <strong>SecurityException</strong>. What good does that do? Well take a look at line 3 in the below code:</p>
<p><!--<br />
{rtf1ansiansicpglang1024noproof65001uc1 deff0{fonttbl{f0fnilfcharset0fprq1 Consolas;}}{colortbl;??red0green0blue0;red255green255blue255;red43green145blue175;red163green21blue21;red0green0blue255;}??fs18 [cf3 ControllerActioncf0 ]par ??[cf3 PrincipalPermissioncf0 (cf3 SecurityActioncf0 .Demand, Role=cf4 "Admin"cf0 ]par ??[cf3 ExceptionHandlercf0 (cf4 "Error"cf0 , cf5 typeofcf0 (SecurityException))]par ??cf5 publiccf0  cf5 voidcf0  Edit(cf5 intcf0 ? id)par ??{par ??   ...par ??}}<br />
--></p>
<div style="background: white none repeat scroll 0% 0%; font-size: 9pt; color: black; font-family: courier new; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial">
<p style="margin: 0px"><span style="color: #2b91af"> 1</span> [<span style="color: #2b91af">ControllerAction</span>]</p>
<p style="margin: 0px"><span style="color: #2b91af"> 2</span> [<span style="color: #2b91af">PrincipalPermission</span>(<span style="color: #2b91af">SecurityAction</span>.Demand, Role=<span style="color: #a31515">"Admin"</span>]</p>
<p style="margin: 0px"><span style="color: #2b91af"> 3</span> [<span style="color: #2b91af">ExceptionHandler</span>(<span style="color: #a31515">"Error"</span>, <span style="color: blue">typeof</span>(SecurityException))]</p>
<p style="margin: 0px"><span style="color: #2b91af"> 4</span> <span style="color: blue">public</span> <span style="color: blue">void</span> Edit(<span style="color: blue">int</span>? id)</p>
<p style="margin: 0px"><span style="color: #2b91af"> 5</span> {</p>
<p style="margin: 0px"><span style="color: #2b91af"> 6</span> &#8230;</p>
<p style="margin: 0px"><span style="color: #2b91af"> 7</span> }</p>
</div>
<p>The <strong>ExceptionHandler</strong> attribute appears to take two values:</p>
<ol>
<li>The view to render in the event of an error.</li>
<li>The type of error to match against.</li>
</ol>
<p>So based upon this code the <strong>PrincipalPermission</strong> will interrogate the user&#8217;s roles when the action is requested and if the user is not in the &#8220;Admin&#8221; role it will throw a <strong>SecurityException</strong>. At that point the <strong>ExceptionHandler</strong> will wake up and say &#8220;hey I can handle that&#8221; and render the view named &#8220;Error&#8221;. Neat huh? Too bad <strong>ExceptionHandler</strong> doesn&#8217;t exist&#8230;</p>
<p>Personally I liked most of the concepts that were introduced in Frederik&#8217;s post, so I went ahead and began to implement the <strong>ExceptionHandler</strong> attribute. Along the way I realized that what was really needed was a way to apply filters to a controller. I&#8217;ve seen <a href="http://flanders.co.nz/blog/archive/2007/12/17/implementing-filters-in-asp.net-mvc.aspx">Ivan Carrero&#8217;s controller filter implementation</a>, but I wanted filters that hooked straight into the MVC Controller&#8217;s three major lifecycle events: <strong>OnPreAction</strong>, <strong>OnPostAction</strong>, and <strong>OnError</strong>. By doing so I felt I would minimize the difference between code in a filter and code in a controller. Thus was born the <strong>FilterController</strong>.</p>
<h2>Filter Controller</h2>
<p>The <strong>FilterController</strong> is an abstract class deriving from the <strong>System.Web.Mvc.Controller</strong>. It&#8217;s primary purpose is to interrogate itself via reflection when it is created and to then load any attributes that implement the <strong>IControllerFilter</strong> interface:</p>
<p><!--<br />
{rtf1ansiansicpglang1024noproof65001uc1 deff0{fonttbl{f0fnilfcharset0fprq1 Consolas;}}{colortbl;??red0green0blue0;red255green255blue255;red128green128blue128;red0green128blue0;red0green0blue255;red43green145blue175;}??fs18 tab cf3 ///cf4  cf3 &lt;summary&gt;par ??cf0 tab cf3 ///cf4  Descendent of the MVC Controller class that adds capability of processing filters specified by attributes.par ??cf0 tab cf3 ///cf4  cf3 &lt;/summary&gt;par ??cf0 tab cf5 publiccf0  cf5 abstractcf0  cf5 classcf0  cf6 FilterControllercf0  : cf6 Controllerpar ??cf0 tab {par ??par ??tab tab cf3 ///cf4  cf3 &lt;summary&gt;par ??cf0 tab tab cf3 ///cf4  Default constructor.par ??cf0 tab tab cf3 ///cf4  cf3 &lt;/summary&gt;par ??cf0 tab tab cf5 publiccf0  FilterController()par ??tab tab {par ??tab tab tab Filters = GetFilterAttributes();par ??tab tab tab cf5 foreachcf0 ( cf6 IControllerFiltercf0  filter cf5 incf0  Filters )par ??tab tab tab {par ??tab tab tab tab filter.Initialize(cf5 thiscf0 );par ??tab tab tab }par ??tab tab }par ??}<br />
--></p>
<div style="background: white none repeat scroll 0% 0%; font-size: 9pt; color: black; font-family: courier new; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial">
<p style="margin: 0px"><span style="color: #2b91af"> 1</span> <span style="color: gray">///</span><span style="color: green"> </span><span style="color: gray">&lt;summary&gt;</span></p>
<p style="margin: 0px"><span style="color: #2b91af"> 2</span> <span style="color: gray">///</span><span style="color: green"> Descendent of the MVC Controller class that adds capability of processing filters specified by attributes.</span></p>
<p style="margin: 0px"><span style="color: #2b91af"> 3</span> <span style="color: gray">///</span><span style="color: green"> </span><span style="color: gray">&lt;/summary&gt;</span></p>
<p style="margin: 0px"><span style="color: #2b91af"> 4</span> <span style="color: blue">public</span> <span style="color: blue">abstract</span> <span style="color: blue">class</span> <span style="color: #2b91af">FilterController</span> : <span style="color: #2b91af">Controller</span></p>
<p style="margin: 0px"><span style="color: #2b91af"> 5</span> {</p>
<p style="margin: 0px"><span style="color: #2b91af"> 6</span></p>
<p style="margin: 0px"><span style="color: #2b91af"> 7</span> <span style="color: gray">///</span><span style="color: green"> </span><span style="color: gray">&lt;summary&gt;</span></p>
<p style="margin: 0px"><span style="color: #2b91af"> 8</span> <span style="color: gray">///</span><span style="color: green"> Default constructor.</span></p>
<p style="margin: 0px"><span style="color: #2b91af"> 9</span> <span style="color: gray">///</span><span style="color: green"> </span><span style="color: gray">&lt;/summary&gt;</span></p>
<p style="margin: 0px"><span style="color: #2b91af"> 10</span> <span style="color: blue">public</span> FilterController()</p>
<p style="margin: 0px"><span style="color: #2b91af"> 11</span> {</p>
<p style="margin: 0px"><span style="color: #2b91af"> 12</span> Filters = GetFilterAttributes();</p>
<p style="margin: 0px"><span style="color: #2b91af"> 13</span> <span style="color: blue">foreach</span>( <span style="color: #2b91af">IControllerFilter</span> filter <span style="color: blue">in</span> Filters )</p>
<p style="margin: 0px"><span style="color: #2b91af"> 14</span> {</p>
<p style="margin: 0px"><span style="color: #2b91af"> 15</span> filter.Initialize(<span style="color: blue">this</span>);</p>
<p style="margin: 0px"><span style="color: #2b91af"> 16</span> }</p>
<p style="margin: 0px"><span style="color: #2b91af"> 17</span> }</p>
</div>
<p>The filters are then called for each of the three integration events: <strong>OnPreAction</strong>, <strong>OnPostAction</strong>, and <strong>OnError</strong>. Here is what the <strong>OnError</strong> event does:</p>
<p><!--<br />
{rtf1ansiansicpglang1024noproof65001uc1 deff0{fonttbl{f0fnilfcharset0fprq1 Consolas;}}{colortbl;??red0green0blue0;red255green255blue255;red128green128blue128;red0green128blue0;red0green0blue255;red43green145blue175;}??fs18 tab tab cf3 ///cf4  cf3 &lt;summary&gt;par ??cf0 tab tab cf3 ///cf4  Passes control of the OnError event on to all filters that want to handle it.par ??cf0 tab tab cf3 ///cf4  cf3 &lt;/summary&gt;par ??cf0 tab tab cf3 ///cf4  cf3 &lt;param name="actionName"&gt;cf4 The name of the action being requested when the exception was thrown.cf3 &lt;/param&gt;par ??cf0 tab tab cf3 ///cf4  cf3 &lt;param name="methodInfo"&gt;cf4 Reflection object representing the action being requested when the exception was thrown.cf3 &lt;/param&gt;par ??cf0 tab tab cf3 ///cf4  cf3 &lt;param name="exception"&gt;cf4 The exception thrown while the action was being requested.cf3 &lt;/param&gt;par ??cf0 tab tab cf3 ///cf4  cf3 &lt;returns&gt;cf4 A boolean denoting the successful handling of the event.cf3 &lt;/returns&gt;par ??cf0 tab tab cf5 protectedcf0  cf5 overridecf0  cf5 boolcf0  OnError( cf5 stringcf0  actionName, cf6 MethodInfocf0  methodInfo, cf6 Exceptioncf0  exception )par ??tab tab {par ??tab tab tab cf5 boolcf0  handled = cf5 falsecf0 ;par ??tab tab tab cf5 boolcf0  allTrue = cf5 truecf0 ;par ??tab tab tab cf5 foreachcf0 ( cf6 IControllerFiltercf0  filter cf5 incf0  Filters )par ??tab tab tab {par ??tab tab tab tab cf5 ifcf0 ( filter.HandleOnError )par ??tab tab tab tab {par ??tab tab tab tab tab handled = cf5 truecf0 ;par ??tab tab tab tab tab cf5 ifcf0 ( !filter.OnError( actionName, methodInfo, exception ) )par ??tab tab tab tab tab tab allTrue = cf5 falsecf0 ;par ??tab tab tab tab }par ??tab tab tab }par ??tab tab tab cf5 ifcf0 ( !handled )par ??tab tab tab tab cf5 throwcf0  exception;par ??tab tab tab cf5 returncf0  allTrue;par ??tab tab }}<br />
--></p>
<div style="background: white none repeat scroll 0% 0%; font-size: 9pt; color: black; font-family: courier new; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial">
<p style="margin: 0px"><span style="color: #2b91af"> 1</span> <span style="color: gray">///</span><span style="color: green"> </span><span style="color: gray">&lt;summary&gt;</span></p>
<p style="margin: 0px"><span style="color: #2b91af"> 2</span> <span style="color: gray">///</span><span style="color: green"> Passes control of the OnError event on to all filters that want to handle it.</span></p>
<p style="margin: 0px"><span style="color: #2b91af"> 3</span> <span style="color: gray">///</span><span style="color: green"> </span><span style="color: gray">&lt;/summary&gt;</span></p>
<p style="margin: 0px"><span style="color: #2b91af"> 4</span> <span style="color: gray">///</span><span style="color: green"> </span><span style="color: gray">&lt;param name=&#8221;actionName&#8221;&gt;</span><span style="color: green">The name of the action being requested when the exception was thrown.</span><span style="color: gray">&lt;/param&gt;</span></p>
<p style="margin: 0px"><span style="color: #2b91af"> 5</span> <span style="color: gray">///</span><span style="color: green"> </span><span style="color: gray">&lt;param name=&#8221;methodInfo&#8221;&gt;</span><span style="color: green">Reflection object representing the action being requested when the exception was thrown.</span><span style="color: gray">&lt;/param&gt;</span></p>
<p style="margin: 0px"><span style="color: #2b91af"> 6</span> <span style="color: gray">///</span><span style="color: green"> </span><span style="color: gray">&lt;param name=&#8221;exception&#8221;&gt;</span><span style="color: green">The exception thrown while the action was being requested.</span><span style="color: gray">&lt;/param&gt;</span></p>
<p style="margin: 0px"><span style="color: #2b91af"> 7</span> <span style="color: gray">///</span><span style="color: green"> </span><span style="color: gray">&lt;returns&gt;</span><span style="color: green">A boolean denoting the successful handling of the event.</span><span style="color: gray">&lt;/returns&gt;</span></p>
<p style="margin: 0px"><span style="color: #2b91af"> 8</span> <span style="color: blue">protected</span> <span style="color: blue">override</span> <span style="color: blue">bool</span> OnError( <span style="color: blue">string</span> actionName, <span style="color: #2b91af">MethodInfo</span> methodInfo, <span style="color: #2b91af">Exception</span> exception )</p>
<p style="margin: 0px"><span style="color: #2b91af"> 9</span> {</p>
<p style="margin: 0px"><span style="color: #2b91af"> 10</span> <span style="color: blue">bool</span> handled = <span style="color: blue">false</span>;</p>
<p style="margin: 0px"><span style="color: #2b91af"> 11</span> <span style="color: blue">bool</span> allTrue = <span style="color: blue">true</span>;</p>
<p style="margin: 0px"><span style="color: #2b91af"> 12</span> <span style="color: blue">foreach</span>( <span style="color: #2b91af">IControllerFilter</span> filter <span style="color: blue">in</span> Filters )</p>
<p style="margin: 0px"><span style="color: #2b91af"> 13</span> {</p>
<p style="margin: 0px"><span style="color: #2b91af"> 14</span> <span style="color: blue">if</span>( filter.HandleOnError )</p>
<p style="margin: 0px"><span style="color: #2b91af"> 15</span> {</p>
<p style="margin: 0px"><span style="color: #2b91af"> 16</span> handled = <span style="color: blue">true</span>;</p>
<p style="margin: 0px"><span style="color: #2b91af"> 17</span> <span style="color: blue">if</span>( !filter.OnError( actionName, methodInfo, exception ) )</p>
<p style="margin: 0px"><span style="color: #2b91af"> 18</span> allTrue = <span style="color: blue">false</span>;</p>
<p style="margin: 0px"><span style="color: #2b91af"> 19</span> }</p>
<p style="margin: 0px"><span style="color: #2b91af"> 20</span> }</p>
<p style="margin: 0px"><span style="color: #2b91af"> 21</span> <span style="color: blue">if</span>( !handled )</p>
<p style="margin: 0px"><span style="color: #2b91af"> 22</span> <span style="color: blue">throw</span> exception;</p>
<p style="margin: 0px"><span style="color: #2b91af"> 23</span> <span style="color: blue">return</span> allTrue;</p>
<p style="margin: 0px"><span style="color: #2b91af"> 24</span> }</p>
</div>
<p>The <strong>OnPreAction</strong> and <strong>OnPostAction</strong> events look almost exactly like the <strong>OnError</strong> event.</p>
<p>To fulfill my initial goal of obtaining functionality similar to that described in Frederik&#8217;s post, I have created two filters:</p>
<ul>
<li><strong>SecurityFilter</strong></li>
<li><strong>ErrorHandlerFilter</strong></li>
</ul>
<h2>Security Filter</h2>
<p>While the <strong>PrincipalPermission</strong> attribute used in Frederik&#8217;s post handles many security scenarios well, it wasn&#8217;t as flexible or keyboard friendly as I would prefer. I created the <strong>SecurityFilter</strong> and an arrangement of sub-filters to create what I think is an easier solution.</p>
<p>To use the security filter in your controller you must first inherit from <strong>FilterController</strong> and apply the <strong>[SecurityFilter]</strong> attribute.</p>
<p><!--<br />
{rtf1ansiansicpglang1024noproof65001uc1 deff0{fonttbl{f0fnilfcharset0fprq1 Consolas;}}{colortbl;??red0green0blue255;red255green255blue255;red0green0blue0;red43green145blue175;}??fs18 cf1 usingcf0  System;par ??cf1 usingcf0  System.Web.Mvc;par ??cf1 usingcf0  SquaredRoot.Mvc;par ??par ??cf1 namespacecf0  Examplepar ??{par ??par ??tab [cf4 SecurityFiltercf0 ]par ??tab cf1 publiccf0  cf1 classcf0  cf4 MyControllercf0  : cf4 FilterControllerpar ??cf0 tab {par ??tab tab ...par ??tab }par ??}<br />
--></p>
<div style="background: white none repeat scroll 0% 0%; font-size: 9pt; color: black; font-family: courier new; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial">
<p style="margin: 0px"><span style="color: #2b91af"> 1</span> <span style="color: blue">using</span> System;</p>
<p style="margin: 0px"><span style="color: #2b91af"> 2</span> <span style="color: blue">using</span> System.Web.Mvc;</p>
<p style="margin: 0px"><span style="color: #2b91af"> 3</span> <span style="color: blue">using</span> SquaredRoot.Mvc;</p>
<p style="margin: 0px"><span style="color: #2b91af"> 4</span></p>
<p style="margin: 0px"><span style="color: #2b91af"> 5</span> <span style="color: blue">namespace</span> Example</p>
<p style="margin: 0px"><span style="color: #2b91af"> 6</span> {</p>
<p style="margin: 0px"><span style="color: #2b91af"> 7</span></p>
<p style="margin: 0px"><span style="color: #2b91af"> 8</span> [<span style="color: #2b91af">SecurityFilter</span>]</p>
<p style="margin: 0px"><span style="color: #2b91af"> 9</span> <span style="color: blue">public</span> <span style="color: blue">class</span> <span style="color: #2b91af">MyController</span> : <span style="color: #2b91af">FilterController</span></p>
<p style="margin: 0px"><span style="color: #2b91af"> 10</span> {</p>
<p style="margin: 0px"><span style="color: #2b91af"> 11</span> &#8230;</p>
<p style="margin: 0px"><span style="color: #2b91af"> 12</span> }</p>
</div>
<p>This alone does nothing, but you are now able to add one or more of the <strong>SecurityFilter</strong>&#8216;s sub-filters to this controller or it&#8217;s actions. The sub-filters I have created are:</p>
<ul>
<li><strong>RequireLogin</strong><br />
Validates that the user is logged in.</li>
<li><strong>RequireAnonymous</strong><br />
Validates that the user is NOT logged in.</li>
<li><strong>RequireRole</strong><br />
Validates that the user is in the specified role.</li>
<li><strong>RequireAnyRole</strong><br />
Validates that the user is in at least one of the specified roles</li>
<li><strong>RequireEachRole</strong><br />
Validates that the user is in every one of the specified roles.</li>
</ul>
<p>Let&#8217;s imagine a controller for a simple bulletin board system. In order to post to this forum you must be logged in, if you want to delete a post you must be in either the &#8220;Administrators&#8221; role or the &#8220;Moderators&#8221; role, and if you want to undelete a post you must be in the &#8220;Administrators&#8221; group. That controller would look something like:</p>
<p><!--<br />
{rtf1ansiansicpglang1024noproof65001uc1 deff0{fonttbl{f0fnilfcharset0fprq1 Consolas;}}{colortbl;??red0green0blue0;red255green255blue255;red43green145blue175;red0green0blue255;red163green21blue21;}??fs18 tab [cf3 SecurityFiltercf0 ]par ??tab [cf3 RequireLogincf0 ]par ??tab cf4 publiccf0  cf4 classcf0  cf3 ForumControllercf0  : cf3 FilterControllerpar ??cf0 tab {par ??par ??tab tab [cf3 ControllerActioncf0 ]par ??tab tab cf4 publiccf0  cf4 voidcf0  Post( cf4 stringcf0  message ){ ... }par ??par ??tab tab [cf3 ControllerActioncf0 ,cf3 RequireAnyRolecf0 ( cf5 "Administrators"cf0 , cf5 "Moderators"cf0  )]par ??tab tab cf4 publiccf0  cf4 voidcf0  Delete( cf4 intcf0  id ){ ... }par ??par ??tab tab [cf3 ControllerActioncf0 ,cf3 RequireRolecf0 ( cf5 "Administrators"cf0  )]par ??tab tab cf4 publiccf0  cf4 voidcf0  Undelete( cf4 intcf0  id ){ ... }par ??par ??tab }}<br />
--></p>
<div style="background: white none repeat scroll 0% 0%; font-size: 9pt; color: black; font-family: courier new; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial">
<p style="margin: 0px"><span style="color: #2b91af"> 1</span> [<span style="color: #2b91af">SecurityFilter</span>]</p>
<p style="margin: 0px"><span style="color: #2b91af"> 2</span> [<span style="color: #2b91af">RequireLogin</span>]</p>
<p style="margin: 0px"><span style="color: #2b91af"> 3</span> <span style="color: blue">public</span> <span style="color: blue">class</span> <span style="color: #2b91af">ForumController</span> : <span style="color: #2b91af">FilterController</span></p>
<p style="margin: 0px"><span style="color: #2b91af"> 4</span> {</p>
<p style="margin: 0px"><span style="color: #2b91af"> 5</span></p>
<p style="margin: 0px"><span style="color: #2b91af"> 6</span> [<span style="color: #2b91af">ControllerAction</span>]</p>
<p style="margin: 0px"><span style="color: #2b91af"> 7</span> <span style="color: blue">public</span> <span style="color: blue">void</span> Post( <span style="color: blue">string</span> message ){ &#8230; }</p>
<p style="margin: 0px"><span style="color: #2b91af"> 8</span></p>
<p style="margin: 0px"><span style="color: #2b91af"> 9</span> [<span style="color: #2b91af">ControllerAction</span>,<span style="color: #2b91af">RequireAnyRole</span>( <span style="color: #a31515">"Administrators"</span>, <span style="color: #a31515">"Moderators"</span> )]</p>
<p style="margin: 0px"><span style="color: #2b91af"> 10</span> <span style="color: blue">public</span> <span style="color: blue">void</span> Delete( <span style="color: blue">int</span> id ){ &#8230; }</p>
<p style="margin: 0px"><span style="color: #2b91af"> 11</span></p>
<p style="margin: 0px"><span style="color: #2b91af"> 12</span> [<span style="color: #2b91af">ControllerAction</span>,<span style="color: #2b91af">RequireRole</span>( <span style="color: #a31515">"Administrators"</span> )]</p>
<p style="margin: 0px"><span style="color: #2b91af"> 13</span> <span style="color: blue">public</span> <span style="color: blue">void</span> Undelete( <span style="color: blue">int</span> id ){ &#8230; }</p>
<p style="margin: 0px"><span style="color: #2b91af"> 14</span></p>
<p style="margin: 0px"><span style="color: #2b91af"> 15</span> }</p>
</div>
<p>By applying the [<strong>RequireLogin</strong>] attribute to the class you have applied that filter to all of the actions as well, which means you must be logged in to call the <strong>Post</strong> method. The other two methods use the appropriate version of the role requirement filters to achieve their goal.</p>
<p>What happens if the filter validations fail? In the case of an anonymous user attempting to access a restricted resource an <strong>AnonymousAccessException</strong> (which derives from <strong>SecurityException</strong>) is thrown while all other scenarios throw a <strong>SecurityException</strong>. What you do with those exceptions leads us to&#8230;</p>
<h2>Error Handler Filter</h2>
<p>Using the above <strong>ForumController</strong>, let&#8217;s add the <strong>ErrorHandler</strong> filter:</p>
<p><!--<br />
{rtf1ansiansicpglang1024noproof65001uc1 deff0{fonttbl{f0fnilfcharset0fprq1 Consolas;}}{colortbl;??red0green0blue0;red255green255blue255;red43green145blue175;red0green0blue255;}??fs18 tab [cf3 SecurityFiltercf0 ]par ??tab [cf3 ErrorHandlerFiltercf0 ]par ??tab [cf3 RequireLogincf0 ]par ??tab cf4 publiccf0  cf4 classcf0  cf3 ForumControllercf0  : cf3 FilterControllerpar ??cf0 tab {par ??tab tab ...par ??tab }}<br />
--></p>
<div style="background: white none repeat scroll 0% 0%; font-size: 9pt; color: black; font-family: courier new; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial">
<p style="margin: 0px"><span style="color: #2b91af"> 1</span> [<span style="color: #2b91af">SecurityFilter</span>]</p>
<p style="margin: 0px"><span style="color: #2b91af"> 2</span> [<span style="color: #2b91af">ErrorHandlerFilter</span>]</p>
<p style="margin: 0px"><span style="color: #2b91af"> 3</span> [<span style="color: #2b91af">RequireLogin</span>]</p>
<p style="margin: 0px"><span style="color: #2b91af"> 4</span> <span style="color: blue">public</span> <span style="color: blue">class</span> <span style="color: #2b91af">ForumController</span> : <span style="color: #2b91af">FilterController</span></p>
<p style="margin: 0px"><span style="color: #2b91af"> 5</span> {</p>
<p style="margin: 0px"><span style="color: #2b91af"> 6</span> &#8230;</p>
<p style="margin: 0px"><span style="color: #2b91af"> 7</span> }</p>
</div>
<p>Like with the last filter, this filter by itself does nothing but allow us to use the <strong>ErrorHandler</strong> sub-filter. Let&#8217;s go ahead and add two sub-filters: one to handle security exceptions and one to handle all other exceptions.</p>
<p>In the event of a security exception we&#8217;ll render the &#8220;AccessDenied&#8221; view while all other exceptions will render the &#8220;SystemError&#8221; view:</p>
<p><!--<br />
{rtf1ansiansicpglang1024noproof65001uc1 deff0{fonttbl{f0fnilfcharset0fprq1 Consolas;}}{colortbl;??red0green0blue0;red255green255blue255;red43green145blue175;red255green0blue255;red163green21blue21;red0green0blue255;}??fs18 tab [cf3 SecurityFiltercf0 ]par ??tab [cf3 ErrorHandlerFiltercf0 ]par ??tab [cf3 RequireLogincf0 ]par ??tab [cf3 ErrorHandlercf0 ( cf4 1cf0 , cf5 "AccessDenied"cf0 , cf6 typeofcf0 (cf3 SecurityExceptioncf0 ) )]par ??tab [cf3 ErrorHandlercf0 ( cf4 2cf0 , cf5 "SystemError"cf0 , cf6 typeofcf0 (cf3 Exceptioncf0 ) )]par ??tab cf6 publiccf0  cf6 classcf0  cf3 ForumControllercf0  : cf3 FilterControllerpar ??cf0 tab {par ??tab tab ...par ??tab }}<br />
--></p>
<div style="background: white none repeat scroll 0% 0%; font-size: 9pt; color: black; font-family: courier new; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial">
<p style="margin: 0px"><span style="color: #2b91af"> 1</span> [<span style="color: #2b91af">SecurityFilter</span>]</p>
<p style="margin: 0px"><span style="color: #2b91af"> 2</span> [<span style="color: #2b91af">ErrorHandlerFilter(ErrorHandlerMode.Render)</span>]</p>
<p style="margin: 0px"><span style="color: #2b91af"> 3</span> [<span style="color: #2b91af">RequireLogin</span>]</p>
<p style="margin: 0px"><span style="color: #2b91af"> 4</span> [<span style="color: #2b91af">ErrorHandler</span>( <span style="color: fuchsia">1</span>, <span style="color: #a31515">"AccessDenied"</span>, <span style="color: blue">typeof</span>(<span style="color: #2b91af">SecurityException</span>) )]</p>
<p style="margin: 0px"><span style="color: #2b91af"> 5</span> [<span style="color: #2b91af">ErrorHandler</span>( <span style="color: fuchsia">2</span>, <span style="color: #a31515">"SystemError"</span>, <span style="color: blue">typeof</span>(<span style="color: #2b91af">Exception</span>) )]</p>
<p style="margin: 0px"><span style="color: #2b91af"> 6</span> <span style="color: blue">public</span> <span style="color: blue">class</span> <span style="color: #2b91af">ForumController</span> : <span style="color: #2b91af">FilterController</span></p>
<p style="margin: 0px"><span style="color: #2b91af"> 7</span> {</p>
<p style="margin: 0px"><span style="color: #2b91af"> 8</span> &#8230;</p>
<p style="margin: 0px"><span style="color: #2b91af"> 9</span> }</p>
</div>
<p>First notice that we are now providing the <strong>ErrorHandlerFilter</strong> attribute with an option that says <strong>ErrorHandlerMode.Render</strong>. This is because in the event of an error we want the controller to render the view with the name passed in. Later on we&#8217;ll look at the other mode: <strong>ErrorHandlerMode.Redirect</strong>.</p>
<p>Next notice that we are providing three values to each of the two <strong>ErrorHandler</strong> sub-filters:</p>
<ol>
<li>The order in which the sub-filter should be processed. This is important because the order the attribute is returned by reflection is unknown.</li>
<li>The name of the view to render. Just like calling <strong>RenderView</strong>() from an action, this view name must be accessible to the controller (either in the controller&#8217;s view directory or in the <strong>Shared</strong> directory).</li>
<li>The type of the exception to match against.</li>
</ol>
<p>Keep in mind that these sub-filters could be applied at either the class level or the method level and that method-level sub-filters are processed before class-level sub-filters. We&#8217;ll stick with class-level throughout this article.</p>
<p>An &#8220;Access Denied&#8221; page popping up whenever we try to go somewhere we aren&#8217;t allowed to without logging in isn&#8217;t the best user experience. Let&#8217;s improve it by sending anonymous users to the login page instead. This time however, we don&#8217;t want just render the login view, we want to actually redirect to the <strong>SecurityController</strong>&#8216;s <strong>Login</strong> action. While we&#8217;re at it, I&#8217;ll show you an example of handling multiple exceptions with one sub-filter:</p>
<p><!--<br />
{rtf1ansiansicpglang1024noproof65001uc1 deff0{fonttbl{f0fnilfcharset0fprq1 Consolas;}}{colortbl;??red0green0blue0;red255green255blue255;red43green145blue175;red255green0blue255;red163green21blue21;red0green0blue255;}??fs18 tab [cf3 ErrorHandlercf0 ( cf4 1cf0 , cf5 "Login,Security"cf0 ,par ??tab cf3 ErrorHandlerModecf0 .Redirect,par ??tab tab cf6 typeofcf0 (cf3 AnonymousAccessExceptioncf0 ) )]par ??tab [cf3 ErrorHandlercf0 ( cf4 2cf0 , cf5 "AccessDenied"cf0 ,par ??tab tab cf6 typeofcf0 (cf3 SecurityExceptioncf0 ) )]par ??tab [cf3 ErrorHandlercf0 ( cf4 3cf0 , cf5 "BadArgument"cf0 ,par ??tab tab cf6 typeofcf0 (cf3 ArgumentExceptioncf0 ),par ??tab tab cf6 typeofcf0 (cf3 ArgumentNullExceptioncf0 ),par ??tab tab cf6 typeofcf0 (cf3 ArgumentOutOfRangeExceptioncf0 ) )]par ??tab [cf3 ErrorHandlercf0 ( cf4 4cf0 , cf5 "SystemError"cf0 ,par ??tab tab cf6 typeofcf0 (cf3 Exceptioncf0 ) )]}<br />
--></p>
<div style="background: white none repeat scroll 0% 0%; font-size: 9pt; color: black; font-family: courier new; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial">
<p style="margin: 0px"><span style="color: #2b91af"> 1</span> [<span style="color: #2b91af">ErrorHandler</span>( <span style="color: fuchsia">1</span>, <span style="color: #a31515">"Login,Security"</span>,</p>
<p style="margin: 0px"><span style="color: #2b91af"> 2</span> <span style="color: #2b91af">ErrorHandlerMode</span>.Redirect,</p>
<p style="margin: 0px"><span style="color: #2b91af"> 3</span> <span style="color: blue">typeof</span>(<span style="color: #2b91af">AnonymousAccessException</span>) )]</p>
<p style="margin: 0px"><span style="color: #2b91af"> 4</span> [<span style="color: #2b91af">ErrorHandler</span>( <span style="color: fuchsia">2</span>, <span style="color: #a31515">"AccessDenied"</span>,</p>
<p style="margin: 0px"><span style="color: #2b91af"> 5</span> <span style="color: blue">typeof</span>(<span style="color: #2b91af">SecurityException</span>) )]</p>
<p style="margin: 0px"><span style="color: #2b91af"> 6</span> [<span style="color: #2b91af">ErrorHandler</span>( <span style="color: fuchsia">3</span>, <span style="color: #a31515">"BadArgument"</span>,</p>
<p style="margin: 0px"><span style="color: #2b91af"> 7</span> <span style="color: blue">typeof</span>(<span style="color: #2b91af">ArgumentException</span>),</p>
<p style="margin: 0px"><span style="color: #2b91af"> 8</span> <span style="color: blue">typeof</span>(<span style="color: #2b91af">ArgumentNullException</span>),</p>
<p style="margin: 0px"><span style="color: #2b91af"> 9</span> <span style="color: blue">typeof</span>(<span style="color: #2b91af">ArgumentOutOfRangeException</span>) )]</p>
<p style="margin: 0px"><span style="color: #2b91af"> 10</span> [<span style="color: #2b91af">ErrorHandler</span>( <span style="color: fuchsia">4</span>, <span style="color: #a31515">"SystemError"</span>,</p>
<p style="margin: 0px"><span style="color: #2b91af"> 11</span> <span style="color: blue">typeof</span>(<span style="color: #2b91af">Exception</span>) )]</p>
</div>
<p>Here in line 1 we specify not the name of the view to render, but the name of the action and controller to redirect to (in the format &#8220;action,controller&#8221;). The handler knows to process this as a redirect because we&#8217;ve changed the mode for this one sub-filter to <strong>ErrorHandlerMode.Redirect</strong>. Lines 7, 8, &amp; 9 illustrate the capability for one sub-filter to match against many exceptions.</p>
<h2>Download The Code</h2>
<p>I hope you find these filters useful. If they don&#8217;t happen to match your particular problem, then feel free to write your own filters. To do so you only have to implement the <strong>IControllerFilter</strong> interface. I&#8217;ve attempted to make it even easier to do so by providing a base class named <strong>ControllerFilter</strong> that already implements the interface and has several hooks for you to take advantage of.</p>
<p>You are free to use or modify this code for anything including commercial purposes. The only restriction I ask is that you do not take credit for this work yourself, but I do not require any specific attribution.</p>
<p>I have packaged the code into four different releases:</p>
<p><strong>NOTE:</strong> <span style="color: red">These projects were built on Vista x64. If you are running a 32-bit version of Windows you may initially have trouble building the source versions below. To fix this you&#8217;ll need to re-add the System.Web.Extensions reference.</span> <a href="/post/2008/01/MVC-Authentication-and-Errors.aspx#Commentb18287b2-6e57-43be-88f0-022f0d247959">See my comment below for more details.</a></p>
<p><strong>Full Source Release<br />
</strong>The entire solution zipped up.<br />
<a rel="enclosure" href="/file.axd?file=MVC+Controller+Filters+(Source+and+Example+Website).zip">Controller Filters (Full Source).zip</a></p>
<p><strong>Example Site &amp; Binaries Release</strong><br />
<strong>(Recommended)</strong> Just the binaries zipped up with an example site.<br />
<a rel="enclosure" href="/file.axd?file=MVC+Controller+Filters+(Example+Website).zip">Controller Filters (Example Site).zip</a></p>
<p><strong>Filter Source Release</strong><br />
The source code for the FilterController and filters. No example site.<br />
<a rel="enclosure" href="/file.axd?file=MVC+Controller+Filters+(Source).zip">Controller Filters (Filter Source).zip</a><strong> </strong></p>
<p><strong>Filter Binaries Release</strong><br />
The binaries for the FilterController and filters only. No source.<br />
<a rel="enclosure" href="/file.axd?file=MVC+Controller+Filters+(Binaries).zip">Controller Filters (Filter Binaries).zip</a> </p>
<div style="text-align: center;"><a href="http://www.dotnetkicks.com/kick/?url=http://www.squaredroot.com/2008/01/04/mvc-authentication-and-errors/" style="border:0; position: relative; top: -2px;"><img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http://www.squaredroot.com/2008/01/04/mvc-authentication-and-errors/" style="border:0;" alt="Kick It on DotNetKicks.com" /></a><a href="http://dotnetshoutout.com/Submit?url=http://www.squaredroot.com/2008/01/04/mvc-authentication-and-errors/" style="border: 0;"><img src="http://dotnetshoutout.com/image.axd?url=http://www.squaredroot.com/2008/01/04/mvc-authentication-and-errors/" style="border:0px" alt="Shout It on DotNetShoutOuts.com" /></a></div>]]></content:encoded>
			<wfw:commentRss>http://www.squaredroot.com/2008/01/04/mvc-authentication-and-errors/feed/</wfw:commentRss>
		<slash:comments>21</slash:comments>
		</item>
		<item>
		<title>ASP.Net MVC Membership Basics</title>
		<link>http://www.squaredroot.com/2007/12/10/aspnet-mvc-membership-basics/</link>
		<comments>http://www.squaredroot.com/2007/12/10/aspnet-mvc-membership-basics/#comments</comments>
		<pubDate>Mon, 10 Dec 2007 20:26:00 +0000</pubDate>
		<dc:creator>Troy Goode</dc:creator>
				<category><![CDATA[MVC]]></category>
		<category><![CDATA[authentication]]></category>
		<category><![CDATA[membership]]></category>
		<category><![CDATA[open source]]></category>

		<guid isPermaLink="false">/post/2007/12/10/ASPNet-MVC-Membership-Basics.aspx</guid>
		<description><![CDATA[NOTE: This article was written for the December CTP release of the MVC framework. Unfortunately, it does not entirely apply to the Preview 2 release or subsequent releases. The MVC bits have finally arrived and I&#8217;ve spent a while digesting them. I&#8217;ve been waiting for the bits to be released to begin working on a [...]]]></description>
			<content:encoded><![CDATA[<blockquote class="warning"><p><b>NOTE</b>:      <br />This article was written for the December CTP release of the MVC framework. Unfortunately, it does not entirely apply to the Preview 2 release or subsequent releases.</p>
</blockquote>
<p><a href="http://asp.net/downloads/3.5-extensions/">The MVC bits have finally arrived</a> and I&#8217;ve spent a while digesting them. I&#8217;ve been waiting for the bits to be released to begin working on a side-project, so the first thing I did after downloading them last night was crank it up and start working on a new ASP.NET MVC Web Application project. </p>
<p>Typically, the first thing I do on a new project is set up the authentication/authorization system. For the project I am working on I want to use the ASP.Net Membership system, but most of the Membership controls do not work with the MVC framework because they require postbacks. I spent some time last night building a Security controller and views for Registration and Login that I thought would be worth sharing. </p>
<p>So far I have implemented basic functionality for Register, Login, and Logout. There are three files we will have to create. We will also have to change the routing table. Let&#8217;s start with the SecurityController: </p>
<p> <!--<br />
{rtf1ansiansicpglang1024noproof65001uc1 deff0{fonttbl{f0fnilfcharset0fprq1 Courier New;}}{colortbl;??red0green0blue255;red255green255blue255;red0green0blue0;red43green145blue175;red163green21blue21;red0green128blue0;}??fs20 cf1 publiccf0  cf1 classcf0  cf4 SecurityControllercf0  : cf4 Controllerpar ??cf0 {par ??par ??tab [cf4 ControllerActioncf0 ]par ??tab cf1 publiccf0  cf1 voidcf0  Login()par ??tab {par ??tab tab RenderView(cf5 "Login"cf0 );par ??tab }par ??par ??tab [cf4 ControllerActioncf0 ]par ??tab cf1 publiccf0  cf1 voidcf0  Register()par ??tab {par ??tab tab RenderView( cf5 "Register"cf0  );par ??tab }par ??par ??tab [cf4 ControllerActioncf0 ]par ??tab cf1 publiccf0  cf1 voidcf0  Logout()par ??tab {par ??tab tab cf4 FormsAuthenticationcf0 .SignOut();par ??tab tab Response.Redirect( cf5 "/"cf0  );par ??tab }par ??par ??tab [cf4 ControllerActioncf0 ]par ??tab cf1 publiccf0  cf1 voidcf0  Authenticate( cf1 stringcf0  userName, cf1 stringcf0  password, cf1 stringcf0  rememberMe, cf1 stringcf0  returnUrl )par ??tab {par ??tab tab cf6 // figure out if username and password are correctpar ??cf0 tab tab cf1 ifcf0 ( cf4 Membershipcf0 .ValidateUser( userName, password ) )par ??tab tab {par ??tab tab tab cf6 // everything is good, create an authticket and gopar ??cf0 tab tab tab cf4 FormsAuthenticationcf0 .SetAuthCookie( userName, (rememberMe == cf1 nullcf0 ) );par ??tab tab tab Response.Redirect( returnUrl );par ??tab tab }par ??tab tab cf1 elsepar ??cf0 tab tab {par ??tab tab tab cf6 // something was wrong, figure out which and pass it into viewpar ??cf0 tab tab tab cf1 ifcf0 ( cf4 Membershipcf0 .GetUser(userName) == cf1 nullcf0  )par ??tab tab tab tab ViewData[cf5 "ErrorMessage"cf0 ] = cf5 "Incorrect username."cf0 ;par ??tab tab tab cf1 elsepar ??cf0 tab tab tab tab ViewData[cf5 "ErrorMessage"cf0 ] = cf5 "Incorrect password."cf0 ;par ??tab tab tab RenderView( cf5 "Login"cf0  );par ??tab tab }par ??tab }par ??par ??tab [cf4 ControllerActioncf0 ]par ??tab cf1 publiccf0  cf1 voidcf0  CreateUser( cf1 stringcf0  userName, cf1 stringcf0  emailAddress, cf1 stringcf0  password, cf1 stringcf0  returnUrl )par ??tab {par ??tab tab cf1 trypar ??cf0 tab tab {par ??tab tab tab cf6 // try to create user and then login that userpar ??cf0 tab tab tab cf1 ifcf0 ( cf4 Membershipcf0 .CreateUser( userName, password, emailAddress ) == cf1 nullcf0  )par ??tab tab tab tab cf1 throwcf0  cf1 newcf0  cf4 MembershipCreateUserExceptioncf0 ( cf5 "An unspecified error occurred."cf0  );par ??tab tab tab cf4 FormsAuthenticationcf0 .SetAuthCookie( userName, cf1 truecf0  );par ??tab tab tab Response.Redirect( returnUrl );par ??tab tab }par ??tab tab cf1 catchcf0 ( cf4 MembershipCreateUserExceptioncf0  e )par ??tab tab {par ??tab tab tab cf6 // something went wrong, pass the message down to the viewpar ??cf0 tab tab tab ViewData[cf5 "ErrorMessage"cf0 ] = e.Message;par ??tab tab tab RenderView(cf5 "Register"cf0 );par ??tab tab tab cf1 returncf0 ;par ??tab tab }par ??tab }par ??par ??}}<br />
-->
<div style="font-size: 9pt; background: white; color: black; font-family: courier new">
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160;&#160; 1</span>&#160;<span style="color: blue">public</span> <span style="color: blue">class</span> <span style="color: #2b91af">SecurityController</span> : <span style="color: #2b91af">Controller</span> </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160;&#160; 2</span> { </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160;&#160; 3</span>&#160; </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160;&#160; 4</span>&#160;&#160;&#160;&#160; [<span style="color: #2b91af">ControllerAction</span>] </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160;&#160; 5</span>&#160;&#160;&#160;&#160; <span style="color: blue">public</span> <span style="color: blue">void</span> Login() </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160;&#160; 6</span>&#160;&#160;&#160;&#160; { </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160;&#160; 7</span>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; RenderView(<span style="color: #a31515">&quot;Login&quot;</span>); </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160;&#160; 8</span>&#160;&#160;&#160;&#160; } </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160;&#160; 9</span>&#160; </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160; 10</span>&#160;&#160;&#160;&#160; [<span style="color: #2b91af">ControllerAction</span>] </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160; 11</span>&#160;&#160;&#160;&#160; <span style="color: blue">public</span> <span style="color: blue">void</span> Register() </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160; 12</span>&#160;&#160;&#160;&#160; { </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160; 13</span>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; RenderView( <span style="color: #a31515">&quot;Register&quot;</span> ); </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160; 14</span>&#160;&#160;&#160;&#160; } </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160; 15</span>&#160; </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160; 16</span>&#160;&#160;&#160;&#160; [<span style="color: #2b91af">ControllerAction</span>] </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160; 17</span>&#160;&#160;&#160;&#160; <span style="color: blue">public</span> <span style="color: blue">void</span> Logout() </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160; 18</span>&#160;&#160;&#160;&#160; { </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160; 19</span>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #2b91af">FormsAuthentication</span>.SignOut(); </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160; 20</span>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Response.Redirect( <span style="color: #a31515">&quot;/&quot;</span> ); </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160; 21</span>&#160;&#160;&#160;&#160; } </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160; 22</span>&#160; </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160; 23</span>&#160;&#160;&#160;&#160; [<span style="color: #2b91af">ControllerAction</span>] </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160; 24</span>&#160;&#160;&#160;&#160; <span style="color: blue">public</span> <span style="color: blue">void</span> Authenticate( <span style="color: blue">string</span> userName, <span style="color: blue">string</span> password, <span style="color: blue">string</span> rememberMe, <span style="color: blue">string</span> returnUrl ) </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160; 25</span>&#160;&#160;&#160;&#160; { </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160; 26</span>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: green">// figure out if username and password are correct</span> </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160; 27</span>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: blue">if</span>( <span style="color: #2b91af">Membership</span>.ValidateUser( userName, password ) ) </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160; 28</span>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; { </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160; 29</span>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: green">// everything is good, create an authticket and go</span> </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160; 30</span>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #2b91af">FormsAuthentication</span>.SetAuthCookie( userName, (rememberMe != <span style="color: blue">null</span>) ); </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160; 31</span>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Response.Redirect( returnUrl ); </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160; 32</span>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; } </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160; 33</span>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: blue">else</span> </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160; 34</span>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; { </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160; 35</span>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: green">// something was wrong, figure out which and pass it into view</span> </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160; 36</span>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: blue">if</span>( <span style="color: #2b91af">Membership</span>.GetUser(userName) == <span style="color: blue">null</span> ) </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160; 37</span>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; ViewData[<span style="color: #a31515">&quot;ErrorMessage&quot;</span>] = <span style="color: #a31515">&quot;Incorrect username.&quot;</span>; </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160; 38</span>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: blue">else</span> </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160; 39</span>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; ViewData[<span style="color: #a31515">&quot;ErrorMessage&quot;</span>] = <span style="color: #a31515">&quot;Incorrect password.&quot;</span>; </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160; 40</span>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; RenderView( <span style="color: #a31515">&quot;Login&quot;</span> ); </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160; 41</span>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; } </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160; 42</span>&#160;&#160;&#160;&#160; } </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160; 43</span>&#160; </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160; 44</span>&#160;&#160;&#160;&#160; [<span style="color: #2b91af">ControllerAction</span>] </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160; 45</span>&#160;&#160;&#160;&#160; <span style="color: blue">public</span> <span style="color: blue">void</span> CreateUser( <span style="color: blue">string</span> userName, <span style="color: blue">string</span> emailAddress, <span style="color: blue">string</span> password, <span style="color: blue">string</span> returnUrl ) </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160; 46</span>&#160;&#160;&#160;&#160; { </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160; 47</span>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: blue">try</span> </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160; 48</span>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; { </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160; 49</span>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: green">// try to create user and then login that user</span> </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160; 50</span>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: blue">if</span>( <span style="color: #2b91af">Membership</span>.CreateUser( userName, password, emailAddress ) == <span style="color: blue">null</span> ) </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160; 51</span>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: blue">throw</span> <span style="color: blue">new</span> <span style="color: #2b91af">MembershipCreateUserException</span>( <span style="color: #a31515">&quot;An unspecified error occurred.&quot;</span> ); </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160; 52</span>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #2b91af">FormsAuthentication</span>.SetAuthCookie( userName, <span style="color: blue">true</span> ); </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160; 53</span>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Response.Redirect( returnUrl ); </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160; 54</span>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; } </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160; 55</span>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: blue">catch</span>( <span style="color: #2b91af">MembershipCreateUserException</span> e ) </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160; 56</span>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; { </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160; 57</span>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: green">// something went wrong</span> </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160; 58</span>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; ViewData[<span style="color: #a31515">&quot;ErrorMessage&quot;</span>] = e.Message; </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160; 59</span>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; RenderView(<span style="color: #a31515">&quot;Register&quot;</span>); </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160; 60</span>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: blue">return</span>; </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160; 61</span>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; } </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160; 62</span>&#160;&#160;&#160;&#160; } </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160; 63</span>&#160; </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160; 64</span> } </p>
</p></div>
<p>&#160; </p>
<p>So we have two basic actions methods that only display views (Register and Login) and three action-only methods that have no views (CreateUser, Authenticate, Logout). </p>
<p>I have chosen to not have a logout page, but to instead redirect to the homepage. Switch out &#8216;Response.Redirect( <span style="color: #a31515">&quot;/&quot;</span> );&#8217; for &#8216;RenderView( &quot;Logout&quot; );&#8217; and create a Logout.aspx view if you would like to display a logout message. </p>
<p>Now let&#8217;s look at the Login view: </p>
<p> <!--<br />
{rtf1ansiansicpglang1024noproof65001uc1 deff0{fonttbl{f0fnilfcharset0fprq1 Courier New;}}{colortbl;??red0green0blue255;red255green255blue255;red163green21blue21;red0green0blue0;red255green0blue0;red255green238blue98;}??fs20 cf1 &lt;cf3 aspcf1 :cf3 Contentcf0  cf5 IDcf1 ="content"cf0  cf5 ContentPlaceHolderIDcf1 ="MainContentPlaceHolder"cf0  cf5 runatcf1 ="server"&gt;par ??par ??cf0 tab cf1 &lt;cf3 h2cf1 &gt;cf0 Logincf1 &lt;/cf3 h2cf1 &gt;par ??par ??cf0 tab cb6highlight6 &lt;%cb0highlight0  cf1 ifcf0 ( ViewData[cf3 "ErrorMessage"cf0 ] != cf1 nullcf0  ){ cb6highlight6 %&gt;par ??cb0highlight0 tab cf1 &lt;cf3 pcf1 &gt;cf0cb6highlight6 &lt;%cb0highlight0  cf1 =cf0 ViewData[cf3 "ErrorMessage"cf0 ] cb6highlight6 %&gt;cf1cb0highlight0 &lt;/cf3 pcf1 &gt;par ??cf0 tab cb6highlight6 &lt;%cb0highlight0  } cb6highlight6 %&gt;par ??par ??cb0highlight0 tab cb6highlight6 &lt;%cb0highlight0  cf1 usingcf0 (Html.Form( cf3 "Authenticate"cf0 , cf3 "Security"cf0  )){ cb6highlight6 %&gt;par ??cb0highlight0 tab cf1 &lt;cf3 fieldsetcf1 &gt;par ??cf0 tab tab cf1 &lt;cf3 legendcf1 &gt;cf0 Logincf1 &lt;/cf3 legendcf1 &gt;par ??cf0 tab tab cf1 &lt;cf3 divcf1 &gt;&lt;cf3 labelcf0  cf5 forcf1 ="userName"&gt;cf0 User Name:cf1 &lt;/cf3 labelcf1 &gt;cf0  cb6highlight6 &lt;%cb0highlight0  cf1 =cf0 Html.TextBox( cf3 "userName"cf0  ) cb6highlight6 %&gt;cf1cb0highlight0 &lt;/cf3 divcf1 &gt;par ??cf0 tab tab cf1 &lt;cf3 divcf1 &gt;&lt;cf3 labelcf0  cf5 forcf1 ="password"&gt;cf0 Password:cf1 &lt;/cf3 labelcf1 &gt;cf0  cb6highlight6 &lt;%cb0highlight0  cf1 =cf0 Html.Password( cf3 "password"cf0  ) cb6highlight6 %&gt;cf1cb0highlight0 &lt;/cf3 divcf1 &gt;par ??cf0 tab tab cf1 &lt;cf3 divcf1 &gt;&lt;cf3 labelcf0  cf5 forcf1 ="password"cf0  cf5 onclickcf1 ="document.getElementById('rememberMe').checked = !document.getElementById('rememberMe').checked;"&gt;cf0 Remember Me:cf1 &lt;/cf3 labelcf1 &gt;par ??cf0 tab tab tab cf1 &lt;cf3 inputcf0  cf5 typecf1 ="checkbox"cf0  cf5 idcf1 ="rememberMe"cf0  cf5 namecf1 ="rememberMe"cf0  cf5 checkedcf1 ="checked"cf0  cf5 valuecf1 ="checked"cf0  cf1 /&gt;&lt;/cf3 divcf1 &gt;par ??cf0 tab tab cf1 &lt;cf3 divcf1 &gt;cf0cb6highlight6 &lt;%cb0highlight0  cf1 =cf0 Html.SubmitButton() cb6highlight6 %&gt;cf1cb0highlight0 &lt;/cf3 divcf1 &gt;par ??cf0 tab tab cb6highlight6 &lt;%cb0highlight0  cf1 =cf0 Html.Hidden( cf3 "returnUrl"cf0 , cf3 "/"cf0  ) cb6highlight6 %&gt;par ??cb0highlight0 tab cf1 &lt;/cf3 fieldsetcf1 &gt;par ??cf0 tab cb6highlight6 &lt;%cb0highlight0  } cb6highlight6 %&gt;par ??par ??cf1cb0highlight0 &lt;/cf3 aspcf1 :cf3 Contentcf1 &gt;}<br />
-->
<div style="font-size: 9pt; background: white; color: black; font-family: courier new">
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160;&#160; 1</span>&#160;<span style="color: blue">&lt;</span><span style="color: #a31515">asp</span><span style="color: blue">:</span><span style="color: #a31515">Content</span> <span style="color: red">ID</span><span style="color: blue">=&quot;content&quot;</span> <span style="color: red">ContentPlaceHolderID</span><span style="color: blue">=&quot;MainContentPlaceHolder&quot;</span> <span style="color: red">runat</span><span style="color: blue">=&quot;server&quot;&gt;</span> </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160;&#160; 2</span>&#160; </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160;&#160; 3</span>&#160;&#160;&#160;&#160; <span style="color: blue">&lt;</span><span style="color: #a31515">h2</span><span style="color: blue">&gt;</span>Login<span style="color: blue">&lt;/</span><span style="color: #a31515">h2</span><span style="color: blue">&gt;</span> </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160;&#160; 4</span>&#160; </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160;&#160; 5</span>&#160;&#160;&#160;&#160; <span style="background: #ffee62">&lt;%</span> <span style="color: blue">if</span>( ViewData[<span style="color: #a31515">&quot;ErrorMessage&quot;</span>] != <span style="color: blue">null</span> ){ <span style="background: #ffee62">%&gt;</span> </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160;&#160; 6</span>&#160;&#160;&#160;&#160; <span style="color: blue">&lt;</span><span style="color: #a31515">p</span><span style="color: blue">&gt;</span><span style="background: #ffee62">&lt;%</span> <span style="color: blue">=</span>ViewData[<span style="color: #a31515">&quot;ErrorMessage&quot;</span>] <span style="background: #ffee62">%&gt;</span><span style="color: blue">&lt;/</span><span style="color: #a31515">p</span><span style="color: blue">&gt;</span> </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160;&#160; 7</span>&#160;&#160;&#160;&#160; <span style="background: #ffee62">&lt;%</span> } <span style="background: #ffee62">%&gt;</span> </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160;&#160; 8</span>&#160; </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160;&#160; 9</span>&#160;&#160;&#160;&#160; <span style="background: #ffee62">&lt;%</span> <span style="color: blue">using</span>(Html.Form( <span style="color: #a31515">&quot;Authenticate&quot;</span>, <span style="color: #a31515">&quot;Security&quot;</span> )){ <span style="background: #ffee62">%&gt;</span> </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160; 10</span>&#160;&#160;&#160;&#160; <span style="color: blue">&lt;</span><span style="color: #a31515">fieldset</span><span style="color: blue">&gt;</span> </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160; 11</span>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: blue">&lt;</span><span style="color: #a31515">legend</span><span style="color: blue">&gt;</span>Login<span style="color: blue">&lt;/</span><span style="color: #a31515">legend</span><span style="color: blue">&gt;</span> </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160; 12</span>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: blue">&lt;</span><span style="color: #a31515">div</span><span style="color: blue">&gt;&lt;</span><span style="color: #a31515">label</span> <span style="color: red">for</span><span style="color: blue">=&quot;userName&quot;&gt;</span>User Name:<span style="color: blue">&lt;/</span><span style="color: #a31515">label</span><span style="color: blue">&gt;</span> <span style="background: #ffee62">&lt;%</span> <span style="color: blue">=</span>Html.TextBox( <span style="color: #a31515">&quot;userName&quot;</span> ) <span style="background: #ffee62">%&gt;</span><span style="color: blue">&lt;/</span><span style="color: #a31515">div</span><span style="color: blue">&gt;</span> </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160; 13</span>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: blue">&lt;</span><span style="color: #a31515">div</span><span style="color: blue">&gt;&lt;</span><span style="color: #a31515">label</span> <span style="color: red">for</span><span style="color: blue">=&quot;password&quot;&gt;</span>Password:<span style="color: blue">&lt;/</span><span style="color: #a31515">label</span><span style="color: blue">&gt;</span> <span style="background: #ffee62">&lt;%</span> <span style="color: blue">=</span>Html.Password( <span style="color: #a31515">&quot;password&quot;</span> ) <span style="background: #ffee62">%&gt;</span><span style="color: blue">&lt;/</span><span style="color: #a31515">div</span><span style="color: blue">&gt;</span> </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160; 14</span>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: blue">&lt;</span><span style="color: #a31515">div</span><span style="color: blue">&gt;&lt;</span><span style="color: #a31515">label</span> <span style="color: red">for</span><span style="color: blue">=&quot;rememberMe&quot;</span><span style="color: blue">&gt;</span>Remember Me:<span style="color: blue">&lt;/</span><span style="color: #a31515">label</span><span style="color: blue">&gt;</span> </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160; 15</span>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: blue">&lt;</span><span style="color: #a31515">input</span> <span style="color: red">type</span><span style="color: blue">=&quot;checkbox&quot;</span> <span style="color: red">id</span><span style="color: blue">=&quot;rememberMe&quot;</span> <span style="color: red">name</span><span style="color: blue">=&quot;rememberMe&quot;</span> <span style="color: red">checked</span><span style="color: blue">=&quot;checked&quot;</span> <span style="color: red">value</span><span style="color: blue">=&quot;checked&quot;</span> <span style="color: blue">/&gt;&lt;/</span><span style="color: #a31515">div</span><span style="color: blue">&gt;</span> </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160; 16</span>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: blue">&lt;</span><span style="color: #a31515">div</span><span style="color: blue">&gt;</span><span style="background: #ffee62">&lt;%</span> <span style="color: blue">=</span>Html.SubmitButton() <span style="background: #ffee62">%&gt;</span><span style="color: blue">&lt;/</span><span style="color: #a31515">div</span><span style="color: blue">&gt;</span> </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160; 17</span>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="background: #ffee62">&lt;%</span> <span style="color: blue">=</span>Html.Hidden( <span style="color: #a31515">&quot;returnUrl&quot;</span>, <span style="color: #a31515">&quot;/&quot;</span> ) <span style="background: #ffee62">%&gt;</span> </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160; 18</span>&#160;&#160;&#160;&#160; <span style="color: blue">&lt;/</span><span style="color: #a31515">fieldset</span><span style="color: blue">&gt;</span> </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160; 19</span>&#160;&#160;&#160;&#160; <span style="background: #ffee62">&lt;%</span> } <span style="background: #ffee62">%&gt;</span> </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160; 20</span>&#160; </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160; 21</span>&#160;<span style="color: blue">&lt;/</span><span style="color: #a31515">asp</span><span style="color: blue">:</span><span style="color: #a31515">Content</span><span style="color: blue">&gt;</span> </p>
</p></div>
<p>&#160; </p>
<p>The toolkit&#8217;s Html.Checkbox(&#8230;) method annoys me. More on why in another post. For now I&#8217;ve instead just written the html out by hand. You&#8217;ll note I&#8217;ve also linked the label to the checkbox with JavaScript so that clicking the label toggles the checkbox. </p>
<p>Then the Register view: </p>
<p> <!--<br />
{rtf1ansiansicpglang1024noproof65001uc1 deff0{fonttbl{f0fnilfcharset0fprq1 Courier New;}}{colortbl;??red0green0blue255;red255green255blue255;red163green21blue21;red0green0blue0;red255green0blue0;red255green238blue98;}??fs20 cf1 &lt;cf3 aspcf1 :cf3 Contentcf0  cf5 IDcf1 ="content"cf0  cf5 ContentPlaceHolderIDcf1 ="MainContentPlaceHolder"cf0  cf5 runatcf1 ="server"&gt;par ??par ??cf0 tab cf1 &lt;cf3 h2cf1 &gt;cf0 Registercf1 &lt;/cf3 h2cf1 &gt;par ??par ??cf0 tab cb6highlight6 &lt;%cb0highlight0  cf1 ifcf0 ( ViewData[cf3 "ErrorMessage"cf0 ] != cf1 nullcf0  ){ cb6highlight6 %&gt;par ??cb0highlight0 tab cf1 &lt;cf3 pcf1 &gt;cf0cb6highlight6 &lt;%cb0highlight0  cf1 =cf0 ViewData[cf3 "ErrorMessage"cf0 ] cb6highlight6 %&gt;cf1cb0highlight0 &lt;/cf3 pcf1 &gt;par ??cf0 tab cb6highlight6 &lt;%cb0highlight0  } cb6highlight6 %&gt;par ??par ??cb0highlight0 tab cb6highlight6 &lt;%cb0highlight0  cf1 usingcf0 (Html.Form( cf3 "CreateUser"cf0 , cf3 "Security"cf0  )){ cb6highlight6 %&gt;par ??cb0highlight0 tab cf1 &lt;cf3 fieldsetcf1 &gt;par ??cf0 tab tab cf1 &lt;cf3 legendcf1 &gt;cf0 Registercf1 &lt;/cf3 legendcf1 &gt;par ??cf0 tab tab cf1 &lt;cf3 divcf1 &gt;&lt;cf3 labelcf0  cf5 forcf1 ="userName"&gt;cf0 User Name:cf1 &lt;/cf3 labelcf1 &gt;cf0  cb6highlight6 &lt;%cb0highlight0  cf1 =cf0 Html.TextBox( cf3 "userName"cf0  ) cb6highlight6 %&gt;cf1cb0highlight0 &lt;/cf3 divcf1 &gt;par ??cf0 tab tab cf1 &lt;cf3 divcf1 &gt;&lt;cf3 labelcf0  cf5 forcf1 ="emailAddress"&gt;cf0 Email Address:cf1 &lt;/cf3 labelcf1 &gt;cf0  cb6highlight6 &lt;%cb0highlight0  cf1 =cf0 Html.TextBox( cf3 "emailAddress"cf0  ) cb6highlight6 %&gt;cf1cb0highlight0 &lt;/cf3 divcf1 &gt;par ??cf0 tab tab cf1 &lt;cf3 divcf1 &gt;&lt;cf3 labelcf0  cf5 forcf1 ="password"&gt;cf0 Password:cf1 &lt;/cf3 labelcf1 &gt;cf0  cb6highlight6 &lt;%cb0highlight0  cf1 =cf0 Html.Password( cf3 "password"cf0  ) cb6highlight6 %&gt;cf1cb0highlight0 &lt;/cf3 divcf1 &gt;par ??cf0 tab tab cf1 &lt;cf3 divcf1 &gt;cf0cb6highlight6 &lt;%cb0highlight0  cf1 =cf0 Html.SubmitButton() cb6highlight6 %&gt;cf1cb0highlight0 &lt;/cf3 divcf1 &gt;par ??cf0 tab tab cb6highlight6 &lt;%cb0highlight0  cf1 =cf0 Html.Hidden( cf3 "returnUrl"cf0 , cf3 "/"cf0  ) cb6highlight6 %&gt;par ??cb0highlight0 tab cf1 &lt;/cf3 fieldsetcf1 &gt;par ??cf0 tab cb6highlight6 &lt;%cb0highlight0  } cb6highlight6 %&gt;par ??par ??cf1cb0highlight0 &lt;/cf3 aspcf1 :cf3 Contentcf1 &gt;}<br />
-->
<div style="font-size: 9pt; background: white; color: black; font-family: courier new">
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160;&#160; 1</span>&#160;<span style="color: blue">&lt;</span><span style="color: #a31515">asp</span><span style="color: blue">:</span><span style="color: #a31515">Content</span> <span style="color: red">ID</span><span style="color: blue">=&quot;content&quot;</span> <span style="color: red">ContentPlaceHolderID</span><span style="color: blue">=&quot;MainContentPlaceHolder&quot;</span> <span style="color: red">runat</span><span style="color: blue">=&quot;server&quot;&gt;</span> </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160;&#160; 2</span>&#160; </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160;&#160; 3</span>&#160;&#160;&#160;&#160; <span style="color: blue">&lt;</span><span style="color: #a31515">h2</span><span style="color: blue">&gt;</span>Register<span style="color: blue">&lt;/</span><span style="color: #a31515">h2</span><span style="color: blue">&gt;</span> </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160;&#160; 4</span>&#160; </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160;&#160; 5</span>&#160;&#160;&#160;&#160; <span style="background: #ffee62">&lt;%</span> <span style="color: blue">if</span>( ViewData[<span style="color: #a31515">&quot;ErrorMessage&quot;</span>] != <span style="color: blue">null</span> ){ <span style="background: #ffee62">%&gt;</span> </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160;&#160; 6</span>&#160;&#160;&#160;&#160; <span style="color: blue">&lt;</span><span style="color: #a31515">p</span><span style="color: blue">&gt;</span><span style="background: #ffee62">&lt;%</span> <span style="color: blue">=</span>ViewData[<span style="color: #a31515">&quot;ErrorMessage&quot;</span>] <span style="background: #ffee62">%&gt;</span><span style="color: blue">&lt;/</span><span style="color: #a31515">p</span><span style="color: blue">&gt;</span> </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160;&#160; 7</span>&#160;&#160;&#160;&#160; <span style="background: #ffee62">&lt;%</span> } <span style="background: #ffee62">%&gt;</span> </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160;&#160; 8</span>&#160; </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160;&#160; 9</span>&#160;&#160;&#160;&#160; <span style="background: #ffee62">&lt;%</span> <span style="color: blue">using</span>(Html.Form( <span style="color: #a31515">&quot;CreateUser&quot;</span>, <span style="color: #a31515">&quot;Security&quot;</span> )){ <span style="background: #ffee62">%&gt;</span> </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160; 10</span>&#160;&#160;&#160;&#160; <span style="color: blue">&lt;</span><span style="color: #a31515">fieldset</span><span style="color: blue">&gt;</span> </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160; 11</span>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: blue">&lt;</span><span style="color: #a31515">legend</span><span style="color: blue">&gt;</span>Register<span style="color: blue">&lt;/</span><span style="color: #a31515">legend</span><span style="color: blue">&gt;</span> </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160; 12</span>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: blue">&lt;</span><span style="color: #a31515">div</span><span style="color: blue">&gt;&lt;</span><span style="color: #a31515">label</span> <span style="color: red">for</span><span style="color: blue">=&quot;userName&quot;&gt;</span>User Name:<span style="color: blue">&lt;/</span><span style="color: #a31515">label</span><span style="color: blue">&gt;</span> <span style="background: #ffee62">&lt;%</span> <span style="color: blue">=</span>Html.TextBox( <span style="color: #a31515">&quot;userName&quot;</span> ) <span style="background: #ffee62">%&gt;</span><span style="color: blue">&lt;/</span><span style="color: #a31515">div</span><span style="color: blue">&gt;</span> </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160; 13</span>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: blue">&lt;</span><span style="color: #a31515">div</span><span style="color: blue">&gt;&lt;</span><span style="color: #a31515">label</span> <span style="color: red">for</span><span style="color: blue">=&quot;emailAddress&quot;&gt;</span>Email Address:<span style="color: blue">&lt;/</span><span style="color: #a31515">label</span><span style="color: blue">&gt;</span> <span style="background: #ffee62">&lt;%</span> <span style="color: blue">=</span>Html.TextBox( <span style="color: #a31515">&quot;emailAddress&quot;</span> ) <span style="background: #ffee62">%&gt;</span><span style="color: blue">&lt;/</span><span style="color: #a31515">div</span><span style="color: blue">&gt;</span> </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160; 14</span>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: blue">&lt;</span><span style="color: #a31515">div</span><span style="color: blue">&gt;&lt;</span><span style="color: #a31515">label</span> <span style="color: red">for</span><span style="color: blue">=&quot;password&quot;&gt;</span>Password:<span style="color: blue">&lt;/</span><span style="color: #a31515">label</span><span style="color: blue">&gt;</span> <span style="background: #ffee62">&lt;%</span> <span style="color: blue">=</span>Html.Password( <span style="color: #a31515">&quot;password&quot;</span> ) <span style="background: #ffee62">%&gt;</span><span style="color: blue">&lt;/</span><span style="color: #a31515">div</span><span style="color: blue">&gt;</span> </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160; 15</span>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: blue">&lt;</span><span style="color: #a31515">div</span><span style="color: blue">&gt;</span><span style="background: #ffee62">&lt;%</span> <span style="color: blue">=</span>Html.SubmitButton() <span style="background: #ffee62">%&gt;</span><span style="color: blue">&lt;/</span><span style="color: #a31515">div</span><span style="color: blue">&gt;</span> </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160; 16</span>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="background: #ffee62">&lt;%</span> <span style="color: blue">=</span>Html.Hidden( <span style="color: #a31515">&quot;returnUrl&quot;</span>, <span style="color: #a31515">&quot;/&quot;</span> ) <span style="background: #ffee62">%&gt;</span> </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160; 17</span>&#160;&#160;&#160;&#160; <span style="color: blue">&lt;/</span><span style="color: #a31515">fieldset</span><span style="color: blue">&gt;</span> </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160; 18</span>&#160;&#160;&#160;&#160; <span style="background: #ffee62">&lt;%</span> } <span style="background: #ffee62">%&gt;</span> </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160; 19</span>&#160; </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160; 20</span>&#160;<span style="color: blue">&lt;/</span><span style="color: #a31515">asp</span><span style="color: blue">:</span><span style="color: #a31515">Content</span><span style="color: blue">&gt;</span> </p>
</p></div>
<p>&#160; </p>
<p>Another straightforward view. Not much to discuss here. </p>
<p>And finally, let&#8217;s add the new routes: </p>
<p> <!--<br />
{rtf1ansiansicpglang1024noproof65001uc1 deff0{fonttbl{f0fnilfcharset0fprq1 Courier New;}}{colortbl;??red43green145blue175;red255green255blue255;red0green0blue0;red0green0blue255;red163green21blue21;}??fs20 cf1 RouteTablecf0 .Routes.Add( cf4 newcf0  cf1 Routepar ??cf0 {par ??tab Url = cf5 "Login"cf0 ,par ??tab Defaults = cf4 newcf0  {par ??tab tab controller = cf5 "Security"cf0 ,par ??tab tab action = cf5 "Register"cf0  },par ??tab RouteHandler = cf4 typeofcf0 ( cf1 MvcRouteHandlercf0  )par ??} );par ??cf1 RouteTablecf0 .Routes.Add( cf4 newcf0  cf1 Routepar ??cf0 {par ??tab Url = cf5 "Register"cf0 ,par ??tab Defaults = cf4 newcf0  {par ??tab tab controller = cf5 "Security"cf0 ,par ??tab tab action = cf5 "Register"cf0  },par ??tab RouteHandler = cf4 typeofcf0 ( cf1 MvcRouteHandlercf0  )par ??} );}<br />
-->
<div style="font-size: 9pt; background: white; color: black; font-family: courier new">
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160;&#160; 1</span>&#160;<span style="color: #2b91af">RouteTable</span>.Routes.Add( <span style="color: blue">new</span> <span style="color: #2b91af">Route</span> </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160;&#160; 2</span> { </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160;&#160; 3</span>&#160;&#160;&#160;&#160; Url = <span style="color: #a31515">&quot;Login&quot;</span>, </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160;&#160; 4</span>&#160;&#160;&#160;&#160; Defaults = <span style="color: blue">new</span> { </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160;&#160; 5</span>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; controller = <span style="color: #a31515">&quot;Security&quot;</span>, </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160;&#160; 6</span>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; action = <span style="color: #a31515">&quot;Login&quot;</span> }, </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160;&#160; 7</span>&#160;&#160;&#160;&#160; RouteHandler = <span style="color: blue">typeof</span>( <span style="color: #2b91af">MvcRouteHandler</span> ) </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160;&#160; 8</span> } ); </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160;&#160; 9</span>&#160;<span style="color: #2b91af">RouteTable</span>.Routes.Add( <span style="color: blue">new</span> <span style="color: #2b91af">Route</span> </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160; 10</span> { </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160; 11</span>&#160;&#160;&#160;&#160; Url = <span style="color: #a31515">&quot;Register&quot;</span>, </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160; 12</span>&#160;&#160;&#160;&#160; Defaults = <span style="color: blue">new</span> { </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160; 13</span>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; controller = <span style="color: #a31515">&quot;Security&quot;</span>, </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160; 14</span>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; action = <span style="color: #a31515">&quot;Register&quot;</span> }, </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160; 15</span>&#160;&#160;&#160;&#160; RouteHandler = <span style="color: blue">typeof</span>( <span style="color: #2b91af">MvcRouteHandler</span> ) </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160; 16</span> } ); </p>
</p></div>
<p>&#160; </p>
<p>I personally like login to be <a href="http://website/login">http://website/login</a> and register to be <a href="http://website/register">http://website/register</a>, so that is how I have configured it. The other three actions (Logout, Authenticate, and CreateUser) I access via the default route (ex: /Security/Logout). </p>
<p>That&#8217;s it! You should now have a working registration/login system. I&#8217;ll leave making it pretty with CSS as an exercise for the reader. </p>
<p>I have included all of the code samples above in the below ZIP file. Just unzip it and place the controller into the Controllers directory, the views into the Views/Security directory (which you will have to create), and copy the code from Routes.txt to the appropriate area of your Global.asax. </p>
<p><a href="/file.axd?file=MVCMembership_v1.2.zip" rel="enclosure">MVCMembership_v1.2.zip (2.03 kb)</a> </p>
<p><strong>UPDATE (Dec 11):</strong> Johan and <a href="http://stevenharman.net/">Steve Harman</a> were kind enough to <a href="/post/2007/12/ASPNet-MVC-Membership-Basics.aspx#Comment64151417-6f79-472c-83a7-2db37cbbb73a">point out</a> that I had foolishly set the &quot;remember me&quot; checkbox&#8217;s label&#8217;s &quot;for&quot; attribute to point to the password field instead of the checkbox itself. I have fixed the code above and provided a new zip file (1.1) for download. Thanks guys! </p>
<p><strong>Update (Dec 19):</strong> <a href="http://www.superwasp.net/weblog/">oVan</a> <a href="/post/2007/12/ASPNet-MVC-Membership-Basics.aspx#Comment76caa980-70fe-4d9e-b1c5-a7f75e43de3d">pointed out a bug</a> in the routing rules defined in the routes.txt file. I have updated the zip file with the correct code. Thanks oVan! </p>
<p><strong>Update (Jan 3):</strong> <a href="/post/2007/12/ASPNet-MVC-Membership-Basics.aspx#Comment84f3301f-4a3f-408d-b472-ae81cbcb6ad1">James Nail asked a very good question via a comment</a>: what do you set for the loginUrl and defaultUrl in your web.config? Well James, here is how I&#8217;ve setup my web.config&#8230; </p>
<p>Assuming we&#8217;ll be using forms authentication and securing all pages except login and the homepage, place the following inside the &lt;system.web&gt;element: </p>
<p> <!--<br />
{rtf1ansiansicpglang1024noproof65001uc1 deff0{fonttbl{f0fnilfcharset0fprq1 Consolas;}}{colortbl;??red0green0blue255;red255green255blue255;red163green21blue21;red255green0blue0;red0green0blue0;}??fs18 cf1 &lt;cf3 authenticationcf1  cf4 modecf1 =cf0 "cf1 Formscf0 "cf1 &gt;par ??tab &lt;cf3 formscf1  cf4 loginUrlcf1 =cf0 "cf1 /Logincf0 "cf1  cf4 defaultUrlcf1 =cf0 "cf1 /cf0 "cf1  /&gt;par ??&lt;/cf3 authenticationcf1 &gt;par ??&lt;cf3 authorizationcf1 &gt;par ??tab &lt;cf3 denycf1  cf4 userscf1 =cf0 "cf1 ?cf0 "cf1  /&gt;par ??&lt;/cf3 authorizationcf1 &gt;}<br />
-->
<div style="font-size: 9pt; background: white; color: black; font-family: courier new">
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160;&#160; 1</span>&#160;<span style="color: blue">&lt;</span><span style="color: #a31515">authentication</span><span style="color: blue"> </span><span style="color: red">mode</span><span style="color: blue">=</span>&quot;<span style="color: blue">Forms</span>&quot;<span style="color: blue">&gt;</span> </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160;&#160; 2</span>&#160;<span style="color: blue">&#160; &lt;</span><span style="color: #a31515">forms</span><span style="color: blue"> </span><span style="color: red">loginUrl</span><span style="color: blue">=</span>&quot;<span style="color: blue">/Login</span>&quot;<span style="color: blue"> </span><span style="color: red">defaultUrl</span><span style="color: blue">=</span>&quot;<span style="color: blue">/</span>&quot;<span style="color: blue"> /&gt;</span> </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160;&#160; 3</span>&#160;<span style="color: blue">&lt;/</span><span style="color: #a31515">authentication</span><span style="color: blue">&gt;</span> </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160;&#160; 4</span>&#160;<span style="color: blue">&lt;</span><span style="color: #a31515">authorization</span><span style="color: blue">&gt;</span> </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160;&#160; 5</span>&#160;<span style="color: blue">&#160; &lt;</span><span style="color: #a31515">deny</span><span style="color: blue"> </span><span style="color: red">users</span><span style="color: blue">=</span>&quot;<span style="color: blue">?</span>&quot;<span style="color: blue"> /&gt;</span> </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160;&#160; 6</span>&#160;<span style="color: blue">&lt;/</span><span style="color: #a31515">authorization</span><span style="color: blue">&gt;</span> </p>
</p></div>
<p>Then, somewhere outside the &lt;system.web&gt; element add: </p>
<p> <!--<br />
{rtf1ansiansicpglang1024noproof65001uc1 deff0{fonttbl{f0fnilfcharset0fprq1 Consolas;}}{colortbl;??red0green0blue255;red255green255blue255;red163green21blue21;red255green0blue0;red0green0blue0;}??fs18 cf1 tab &lt;cf3 locationcf1  cf4 pathcf1 =cf0 "cf1 Default.aspxcf0 "cf1 &gt;par ??tab tab &lt;cf3 system.webcf1 &gt;par ??tab tab tab &lt;cf3 authorizationcf1 &gt;par ??tab tab tab tab &lt;cf3 allowcf1  cf4 userscf1 =cf0 "cf1 *cf0 "cf1  /&gt;par ??tab tab tab &lt;/cf3 authorizationcf1 &gt;par ??tab tab &lt;/cf3 system.webcf1 &gt;par ??tab &lt;/cf3 locationcf1 &gt;par ??tab &lt;cf3 locationcf1  cf4 pathcf1 =cf0 "cf1 Security/Authenticatecf0 "cf1 &gt;par ??tab tab &lt;cf3 system.webcf1 &gt;par ??tab tab tab &lt;cf3 authorizationcf1 &gt;par ??tab tab tab tab &lt;cf3 allowcf1  cf4 userscf1 =cf0 "cf1 *cf0 "cf1  /&gt;par ??tab tab tab &lt;/cf3 authorizationcf1 &gt;par ??tab tab &lt;/cf3 system.webcf1 &gt;par ??tab &lt;/cf3 locationcf1 &gt;par ??tab &lt;cf3 locationcf1  cf4 pathcf1 =cf0 "cf1 Logincf0 "cf1 &gt;par ??tab tab &lt;cf3 system.webcf1 &gt;par ??tab tab tab &lt;cf3 authorizationcf1 &gt;par ??tab tab tab tab &lt;cf3 allowcf1  cf4 userscf1 =cf0 "cf1 *cf0 "cf1  /&gt;par ??tab tab tab &lt;/cf3 authorizationcf1 &gt;par ??tab tab &lt;/cf3 system.webcf1 &gt;par ??tab &lt;/cf3 locationcf1 &gt;}<br />
-->
<div style="font-size: 9pt; background: white; color: black; font-family: courier new">
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160;&#160; 1</span>&#160;<span style="color: blue">&lt;</span><span style="color: #a31515">location</span><span style="color: blue"> </span><span style="color: red">path</span><span style="color: blue">=</span>&quot;<span style="color: blue">Default.aspx</span>&quot;<span style="color: blue">&gt;</span> </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160;&#160; 2</span>&#160;<span style="color: blue">&#160; &lt;</span><span style="color: #a31515">system.web</span><span style="color: blue">&gt;</span> </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160;&#160; 3</span>&#160;<span style="color: blue">&#160;&#160;&#160; &lt;</span><span style="color: #a31515">authorization</span><span style="color: blue">&gt;</span> </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160;&#160; 4</span>&#160;<span style="color: blue">&#160;&#160;&#160;&#160;&#160; &lt;</span><span style="color: #a31515">allow</span><span style="color: blue"> </span><span style="color: red">users</span><span style="color: blue">=</span>&quot;<span style="color: blue">*</span>&quot;<span style="color: blue"> /&gt;</span> </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160;&#160; 5</span>&#160;<span style="color: blue">&#160;&#160;&#160; &lt;/</span><span style="color: #a31515">authorization</span><span style="color: blue">&gt;</span> </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160;&#160; 6</span>&#160;<span style="color: blue">&#160; &lt;/</span><span style="color: #a31515">system.web</span><span style="color: blue">&gt;</span> </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160;&#160; 7</span>&#160;<span style="color: blue">&lt;/</span><span style="color: #a31515">location</span><span style="color: blue">&gt;</span> </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160;&#160; 8</span>&#160;<span style="color: blue">&lt;</span><span style="color: #a31515">location</span><span style="color: blue"> </span><span style="color: red">path</span><span style="color: blue">=</span>&quot;<span style="color: blue">Security</span>&quot;<span style="color: blue">&gt;</span> </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160;&#160; 9</span>&#160;<span style="color: blue">&#160; &lt;</span><span style="color: #a31515">system.web</span><span style="color: blue">&gt;</span> </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160; 10</span>&#160;<span style="color: blue">&#160;&#160;&#160; &lt;</span><span style="color: #a31515">authorization</span><span style="color: blue">&gt;</span> </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160; 11</span>&#160;<span style="color: blue">&#160;&#160;&#160;&#160;&#160; &lt;</span><span style="color: #a31515">allow</span><span style="color: blue"> </span><span style="color: red">users</span><span style="color: blue">=</span>&quot;<span style="color: blue">*</span>&quot;<span style="color: blue"> /&gt;</span> </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160; 12</span>&#160;<span style="color: blue">&#160;&#160;&#160; &lt;/</span><span style="color: #a31515">authorization</span><span style="color: blue">&gt;</span> </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160; 13</span>&#160;<span style="color: blue">&#160; &lt;/</span><span style="color: #a31515">system.web</span><span style="color: blue">&gt;</span> </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160; 14</span>&#160;<span style="color: blue">&lt;/</span><span style="color: #a31515">location</span><span style="color: blue">&gt;</span> </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160; 15</span>&#160;<span style="color: blue">&lt;</span><span style="color: #a31515">location</span><span style="color: blue"> </span><span style="color: red">path</span><span style="color: blue">=</span>&quot;<span style="color: blue">Login</span>&quot;<span style="color: blue">&gt;</span> </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160; 16</span>&#160;<span style="color: blue">&#160; &lt;</span><span style="color: #a31515">system.web</span><span style="color: blue">&gt;</span> </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160; 17</span>&#160;<span style="color: blue">&#160;&#160;&#160; &lt;</span><span style="color: #a31515">authorization</span><span style="color: blue">&gt;</span> </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160; 18</span>&#160;<span style="color: blue">&#160;&#160;&#160;&#160;&#160; &lt;</span><span style="color: #a31515">allow</span><span style="color: blue"> </span><span style="color: red">users</span><span style="color: blue">=</span>&quot;<span style="color: blue">*</span>&quot;<span style="color: blue"> /&gt;</span> </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160; 19</span>&#160;<span style="color: blue">&#160;&#160;&#160; &lt;/</span><span style="color: #a31515">authorization</span><span style="color: blue">&gt;</span> </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160; 20</span>&#160;<span style="color: blue">&#160; &lt;/</span><span style="color: #a31515">system.web</span><span style="color: blue">&gt;</span> </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160; 21</span>&#160;<span style="color: blue">&lt;/</span><span style="color: #a31515">location</span><span style="color: blue">&gt;</span> </p>
</p></div>
<p>Note that this will grant access to all actions within the Security controller. It is also worth pointing out that, dependent on your setup, your CSS and image files may not load unless you also create a location path for their directory and grant all users access like so: </p>
<p> <!--<br />
{rtf1ansiansicpglang1024noproof65001uc1 deff0{fonttbl{f0fnilfcharset0fprq1 Consolas;}}{colortbl;??red0green0blue255;red255green255blue255;red163green21blue21;red255green0blue0;red0green0blue0;}??fs18 cf1 tab &lt;cf3 locationcf1  cf4 pathcf1 =cf0 "cf1 Contentcf0 "cf1 &gt;par ??tab tab &lt;cf3 system.webcf1 &gt;par ??tab tab tab &lt;cf3 authorizationcf1 &gt;par ??tab tab tab tab &lt;cf3 allowcf1  cf4 userscf1 =cf0 "cf1 *cf0 "cf1  /&gt;par ??tab tab tab &lt;/cf3 authorizationcf1 &gt;par ??tab tab &lt;/cf3 system.webcf1 &gt;par ??tab &lt;/cf3 locationcf1 &gt;}<br />
-->
<div style="font-size: 9pt; background: white; color: black; font-family: courier new">
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160;&#160; 1</span>&#160;<span style="color: blue">&lt;</span><span style="color: #a31515">location</span><span style="color: blue"> </span><span style="color: red">path</span><span style="color: blue">=</span>&quot;<span style="color: blue">Content</span>&quot;<span style="color: blue">&gt;</span> </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160;&#160; 2</span>&#160;<span style="color: blue">&#160; &lt;</span><span style="color: #a31515">system.web</span><span style="color: blue">&gt;</span> </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160;&#160; 3</span>&#160;<span style="color: blue">&#160;&#160;&#160; &lt;</span><span style="color: #a31515">authorization</span><span style="color: blue">&gt;</span> </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160;&#160; 4</span>&#160;<span style="color: blue">&#160;&#160;&#160;&#160;&#160; &lt;</span><span style="color: #a31515">allow</span><span style="color: blue"> </span><span style="color: red">users</span><span style="color: blue">=</span>&quot;<span style="color: blue">*</span>&quot;<span style="color: blue"> /&gt;</span> </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160;&#160; 5</span>&#160;<span style="color: blue">&#160;&#160;&#160; &lt;/</span><span style="color: #a31515">authorization</span><span style="color: blue">&gt;</span> </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160;&#160; 6</span>&#160;<span style="color: blue">&#160; &lt;/</span><span style="color: #a31515">system.web</span><span style="color: blue">&gt;</span> </p>
<p style="margin: 0px"><span style="color: #2b91af">&#160;&#160;&#160; 7</span>&#160;<span style="color: blue">&lt;/</span><span style="color: #a31515">location</span><span style="color: blue">&gt;</span> </p>
</p></div>
<p>I have not updated the zip file with these web.config settings; let me know if anyone would prefer that I add it. I hope this helps some of you! </p>
<div style="text-align: center;"><a href="http://www.dotnetkicks.com/kick/?url=http://www.squaredroot.com/2007/12/10/aspnet-mvc-membership-basics/" style="border:0; position: relative; top: -2px;"><img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http://www.squaredroot.com/2007/12/10/aspnet-mvc-membership-basics/" style="border:0;" alt="Kick It on DotNetKicks.com" /></a><a href="http://dotnetshoutout.com/Submit?url=http://www.squaredroot.com/2007/12/10/aspnet-mvc-membership-basics/" style="border: 0;"><img src="http://dotnetshoutout.com/image.axd?url=http://www.squaredroot.com/2007/12/10/aspnet-mvc-membership-basics/" style="border:0px" alt="Shout It on DotNetShoutOuts.com" /></a></div>]]></content:encoded>
			<wfw:commentRss>http://www.squaredroot.com/2007/12/10/aspnet-mvc-membership-basics/feed/</wfw:commentRss>
		<slash:comments>36</slash:comments>
		</item>
	</channel>
</rss>
