views:

119

answers:

2

I'm trying to setup Forms Authentication in an asp.net mvc 2 application that will be hosted on IIS 6. There's an issue somewhere in my routing, but I can't pinpoint exactly where it is.

Here is the route entries I'm using to route the mvc requests through the aspx processing on IIS 6. These may or may not be the "right" way, but they do work on the server at current.

        routes.MapRoute(
            "Default",
            "{controller}.aspx/{action}/{id}",
            new { action = "LogOn", id = "" }
          );

        routes.MapRoute(
          "Root",
          "",
          new { controller = "Main", action = "LogOn", id = "" }
        );

I've put the [Authorize] attribute on my Main controller.

In my web.config I have:

    <authentication mode="Forms">
        <forms  loginUrl="~/Main.aspx/LogOn" timeout="2880"/>
    </authentication>

When the application starts, a blank page loads. The page is quite literally blank. I haven't found a way to amend the loginUrl to actually execute the LogOn action & View for my Main controller.

Edited

Just as an fyi, I've setup my routing based on this article so that the mvc routing can work on IIS 6.

http://www.asp.net/mvc/tutorials/using-asp-net-mvc-with-different-versions-of-iis-cs

I'm guessing the problem here is that the windows form authentication settings aren't syncing with the routes setup so the app can run on IIS 6 via the aspx extension.

Anyone have thoughts on how I could fix this?

Edit 2

Tried adding the following route:

        routes.MapRoute(
            "Login",
            "Login",
            new { controller = "Main", action = "LogOn" }
          );

Amended the web.config to:

    <authentication mode="Forms">
        <forms  loginUrl="~/Login" timeout="2880"/>
    </authentication>

The result is the same white screen as I originally got. It seems like the page doesn't get processed at all. Viewing the source from page generated shows absolutely nothing....no markup...no html declaration....just nothing.

EDIT 3

It seems that I can't seem to get the correct routing configured with the default forms authentication via the web.config. To circumvent this, I've created my own Authorize attribute class. At current, I only care that the user has logged into the system. To accomodate this, I moved the LogOn & LogOff actions to an Account controller. I've remapped the root path to point to this controller. In my custom Authorize attribute, I check to see if the user is logged in and redirect them back to the LogOn page if they aren't. Here is the code:

        routes.MapRoute(
          "Root",
          "",
          new { controller = "Account", action = "LogOn", id = "" }
        );

And here's the code for the RequireLoginAttribute class I derrived.

     [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
        public class RequireLoginAttribute : AuthorizeAttribute, IAuthorizationFilter
        {
            #region IAuthorizationFilter Members

            public override void OnAuthorization(AuthorizationContext filterContext)
            {
                if (!filterContext.HttpContext.Request.IsAuthenticated) 
                {   
                    //This didn't work...it would try routing to urls like
                    //http://localhost:1524/Main.aspx/Account.aspx/Logon
                    //new RedirectResult("Account.aspx/Logon");

                    //This seems sloppy to me somehow, but it works.
                    filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary(new { controller = "Account", action = "LogOn" }));
                }

            }

            #endregion
        }

Now, I can just apply the [RequireLogin] attribute to the Main controller and it ensures the user must be authenticated.

For the curious, and completeness of this scenerio, I am using the following code in the LogOn action (repository isn't ready yet so things are hard coded):

        public ActionResult LogOn(LogOnModel login, String returnUrl)
        {
            if (ModelState.IsValid)
            {
                FormsAuthentication.SetAuthCookie(login.UserName, false);
                return Redirect(returnUrl ?? Url.Action("NextPage", "Main"));
            }
            else
            {
                return View(login);
            }
        }

The returnUrl is a throwback to the Windows Forms authentication. Since I can't seem to get that working here, the parameter will always be null.

Please, critique this if you see specific areas that need improvement. I'm reading what I can and trying to do things right, so all input is greatly appreciated. Thanks!

A: 

If you need the .aspx for the Default Root then why don't you need it for the login route ?

You could do a couple of things then

  1. Actually create a ASP.NET page called Login.aspx and put it in the root of the folder (Authentication will work for your mvc pages as well)
  2. Change your login route to say

    routes.MapRoute("Login","Login.aspx",new { controller = "Main", action = "LogOn" });

  3. You should also take a look at to see what route your actually hitting at any time.

    http://haacked.com/archive/2008/03/13/url-routing-debugger.aspx

Remember that the order you write your routes in Global matters. It stops checking when it finds one that works so your catch all should be last.

Hurricanepkt
What would I put in the Login.aspx page? I know I'm probably coming off as pretty confusing here, but despite using the *.aspx route mappings, the application is not actually using any web forms. It's entirely asp.net mvc. The instructions for running mvc in IIS 6 said you could map routes to the aspx extension to avoid any server side setup, which is what I opted for here. I've got a semi-working solution that I fear is more hack than solution. I've updated the question with the details.
Jason
A: 

The details I posted in EDIT 3 summarize the solution to this issue. I appreciate all of your input into this question, but I've resolved it. I would have liked to have gotten the "out of the box" forms authentication working, but this solution serves well enough. If we move to IIS 7, I think all of this will become moot anyhow.

Thanks again for your help guys.

Jason