ASP.Net MVC and Forms Authentication

Posted Wednesday, December 19, 2007 1:15 AM by cromwellryan

So last weekend I picked up the new ASP.Net 3.5 Extensions Preview CTP (and MVC Toolkit) from the ASP.Net team and I'm loving the MVC bits.  I never could get in to MonoRail mainly because I'm a developer diva.  I need intellisense, syntax highlighting, the whole deal.  For a CTP, this release packs quite a punch.

After running through Scott Hanselman's MVC How-To Screencast and playing around I took to writing a full site I had already 90% completed with Community Server (wpfstyle.com - it's coming).  Blew threw most of the functionality in the first 3 or 4 hours - awesome.  Then I tried to add Forms Authentication through the easy ASP.Net Configuration button of VS 2008.  Nada.

Long story short, I figured out how to get things working, but there are some manual steps.  Here they are:

image[Step 1] Create a new ASP.Net MVC site.  I've called mine SecureMVCApplication.

[Step 2] Lets add a new controller called SecureController.  This will be our set of actions that only administrators can access. 

 

 

image [Step 3] We don't need to add any new Actions, the Index action created for us is sufficient, but we will need to do something.  So add a call to RenderView("Index") within the Index method.  You'll also need to create the index view, so add a folder called Secure under the Views folder already in your project.  To this we will need to add a new MVC View Page item.  To make it clear, I've typed "This is for admin eyes only!!!" as the body of my view.

At this point we should make sure things are working.  Hitting F5 should take you to the root of the site, but you could well end up at /Views/Secure/Index.aspx or something like that.  Try browsing to http://localhost:<port>/secure/index.  You should see the "This is for admin eyes only!!!" text.  If not, go watch Scott's screencast and come back.

image [Step 4] We're ready to start securing things.  Use the ASP.Net Configuration button to set security to Internet, create a couple of users and at least 1 role called Administrators.  This is for our example, you can call your roles whatever you want in your application.

At this point, you would normally use the Create Access Rules link to specify the Adminstrators role has access to the secure directory.  Instead, we have to do this bit ourselves, because the MVC pattern will present us with a URL structure that does not map to physical directories.  At least, probably won't.  In a normal site, the ASP.Net Configuration tool would add a web.config to each configured directory that specifies the authorization rules.  This brings us to the next step:

[Step 5] Open your projects root web.config and add the following:

<location path="secure">
  <system.web>
    <authorization>
      <allow roles="Adminstrators" />
      <deny users="*" />
    </authorization>
  </system.web>
</location>

Assuming you are familiar with MVC URLs this is telling us that the http://<site>/secure path should allow access to users in the Adminstrators role and deny everyone else.  /secure is, of course, the controller.  Had this been a standard site, the stuff inside the <location /> element would have been found inside our secure\web.config.

[Step 5] We are now ready to authenticate our users, but we don't have a normal login.aspx.  Instead, we're going to create a controller called UserController and add a Login and Authenticate action.  Here's what I've added to my sample:

namespace SecureMvcApplication.Controllers
{
    public class UserController : System.Web.Mvc.Controller
    {
        [System.Web.Mvc.ControllerAction]
        public void Login()
        {
            RenderView("Login");
        }

        [System.Web.Mvc.ControllerAction]
        public void Authenticate(string username, string password)
        {
            if (System.Web.Security.Membership.ValidateUser(username, password))
            {
                System.Web.Security.FormsAuthentication.RedirectFromLoginPage(username, false);
            }
        }
    }
}

Notice that my Login action is simply displaying a view.  This view has two textboxes (one marked password) and a submit button.  If you watch(ed) Scott's Screencast, I've used the http://asp.net/downloads/3.5-extensions/MVCToolkit.zip to do this.  The form itself looks like this:

<%using (Html.Form("Authenticate?ReturnUrl=" + this.Request["ReturnUrl"], "User"))
  {%>
    <div>Username: <%=Html.TextBox("username") %></div>
    <div>Password: <%=Html.Password("password") %></div>
    <div><%=Html.SubmitButton("Login") %></div>
<%} %>

Upon Submit/Login, we're POSTing to the Authenticate( string, string ) Action in our UserController which implements the basic Forms Authentication (above).  The next step is optional, but it helped me watch the authorization status.

[Step 6] (Optional)  Add this to your global.asax.cs to see the authorization status of your requests..

protected void Application_AuthenticateRequest(object sender, EventArgs e)
{
    HttpCookie authCookie = Context.Request.Cookies[FormsAuthentication.FormsCookieName];

    if (null == authCookie)
    {//There is no authentication cookie.
        Debug.WriteLine("Don't know you, dude.");
    }
    else
        Debug.WriteLine("Enjoy the party!");
}

Now F5 and browse to http://localhost:<port>/secure/index and you should be taken to the http://localhost:<port>/user/login page.  Upon hitting login, you're directed back to the root of the site.  In our form, we had to manually set the ReturnUrl, because Forms Authentication assumes you will be posting back to yourself (classic ASP.Net Web Form).  We're posting across to the Authenticate action Url.

You can download the completed VS 2008 project I used here.

Can you believe we're already calling ASP.Net Web Forms "classic"?  Now we need to get MVC into the WPF platform.  How cool would that be!

Filed under: ,

Comments

# re: ASP.Net MVC and Forms Authentication

Wednesday, December 19, 2007 6:26 AM by dave thieben

nice. I've been watching the MVC postings, but havent had time to play with it yet. can't wait to try it out.

# ASP.Net MVC Checkbox/boolean Value Mapping

Wednesday, December 19, 2007 7:14 PM by Ryan Cromwell

In my quest to get my wpfstyle.com site written in the new ASP.Net MVC framework (day 3) I&#39;ve run

# re: ASP.Net MVC and Forms Authentication

Wednesday, January 02, 2008 8:17 AM by Paul

Your technique works, however, it will only work a the controller level. If you want to secure an action, it won't work. For example, if you had secure/admin and secure/index. If you only want secure/admin to be secured you'd add . This does not work as expected. ~ Paul

# re: ASP.Net MVC and Forms Authentication

Wednesday, January 02, 2008 8:24 AM by cromwellryan

I don't have my sample here at the office, but I'll verify this evening.  My current project using this tehcnique does include two actions within the same controller (ResourceController) which are authorized differently.  The resource/upload action is only available to authenticated users, while resource/list is available for all users, including anonymous.  I will confirm this and try to post an updated sample this evening.

Do you have a specific reason or example why you feel this doesn't work as expected?  You may wish to add the trailing slash.

# re: ASP.Net MVC and Forms Authentication

Tuesday, January 08, 2008 3:33 AM by Israel Aece

Hello Ryan,

What's the solution when we need to protect the URL like /Products/Edit/1 where "1" is a productId?

# re: ASP.Net MVC and Forms Authentication

Tuesday, January 08, 2008 5:40 AM by cromwellryan

You can do a number of things.  You can authorize the Edit url itself by using /Products/Edit as the location element.  You can authorize the Edit ControllerAction method via the PrincipalPermission attribute.  Of course, you could do it manually in code as well by asserting role membership.

# re: ASP.Net MVC and Forms Authentication

Sunday, February 03, 2008 11:38 AM by Jesper Christiansen

Hmm.. I simply dont get it! I can easily add users and roles in the "Web Site Administration" web-interface.. but it never creates a database for me.. Atleast not under my current project..

Any idea of what I might be doing wrong? It seems to by working on projects that are not MVC websites.

# re: ASP.Net MVC and Forms Authentication

Sunday, February 03, 2008 12:00 PM by cromwellryan

Jesper,

It likely did create the database, but, initially, it's not added to the project in the sense you may be expecting.  The SQL Express MDF is likely just not "included" in the Visual Studio project.  In the Solution Explorer, there is a button at the top called "Show All Files".  Click that and see if the ASPNETDB.mdf is not in the App_Data directory.  

# re: ASP.Net MVC and Forms Authentication

Sunday, February 03, 2008 12:54 PM by Jesper Christiansen

Thank you soo much! That gave me a few gray hairs trying to solve that one :) (Im still a little new in the asp.net world) ..

if you ever stop by Copenhagen, Denmark - I owe you a beer! :)

# re: ASP.Net MVC and Forms Authentication

Sunday, February 03, 2008 7:30 PM by cromwellryan

Count me in!  I'd love to make it there regardless, but a beer only helps the case.

# re: ASP.Net MVC and Forms Authentication

Thursday, March 27, 2008 7:12 AM by Dewy

Hi Ryan, this is exatcly what I am looking for, well at least I think that it is. I am using the Preview 2 download and so I had to make some changes to the web.config file to ref those files instead. I also had to change the Html.Form parameters around as these have been altered I guess for Prev2.

When I try to run my app, it goes into debug and stops on the User/Login.aspx and highlights the using statement and says that there is a NullReference exception. Its drving me nuts. Any ideas?

Also, I have done a bit of searching on this and I have also seen that you can use the PrinciplePermission attribute on the controllers themselves or in a base class or whatnot and I like this idea better as this means that you don't have to use hard coded paths in the config file. Are you planning on updateing your example to use the new release?

Cheers

Dewy

# re: ASP.Net MVC and Forms Authentication

Thursday, March 27, 2008 7:28 AM by cromwellryan

The NullReference exception is likely a result of the Request["ReturnUrl"].  It is a bit presumptuous of me to assume that you'll be arriving at the Login.aspx page from another page that was unable to authorize/authenticate you.  You may wish to do a safer "get" of the ReturnUrl.

As for the PrinciplePermission attribute, it wouldn't hurt to have a full solution for that, but I hadn't planned on it.  I do agree that it's a bit more clean to apply the attribute see as changing your Routes would change your urls and, thus, the config authorization.

I'll do what I can to post an example soon.

# form with asp

Wednesday, April 16, 2008 12:39 PM by form with asp

Pingback from  form with asp

# re: ASP.Net MVC and Forms Authentication

Tuesday, October 07, 2008 4:34 AM by spooneemi

Подскажите шооблончег  под Wordpress 2.6.2, чтобы был похож на ваш cromwellhaus.com.

Заранее благодарю)

# re: ASP.Net MVC and Forms Authentication

Saturday, October 11, 2008 2:03 PM by Почему

Подскажите, как найти хозяина cromwellhaus.com.

С меня пыво)

---------

<a href=kilomozg.ru/>%D0%9F%D0%BE%D1%87%D0%B5%D0%BC%D1%83

Leave a Comment

(required) 
(required) 
(optional)
(required)