Blocking Direct Access To Views in ASP.NET MVC

UPDATE: I improved this based on some feedback in my comments.

With ASP.NET MVC it is possible for someone to try and navigate directly to a .aspx view. In general, this only leaves them with an ugly error message as Views typically need ViewData in order to work.

However, one approach that I think will easily work is to create a Web.config file in the root of your Views directory that contains the following.

We need to do more testing on our side to make sure there's no pathological case in doing this, but so far in my personal testing, it seems to work.

<?xml version="1.0"?>
<configuration>
  <system.web>
    <httpHandlers>
      <remove verb="*" path="*.aspx"/>
      <add path="*.aspx" verb="*" 
          type="System.Web.HttpNotFoundHandler"/>
    </httpHandlers>
  </system.web>

  <system.webServer>
    <validation validateIntegratedModeConfiguration="false"/>
    <handlers>
      <remove name="PageHandlerFactory-ISAPI-2.0"/>
      <remove name="PageHandlerFactory-ISAPI-1.1"/>
      <remove name="PageHandlerFactory-Integrated"/>
      <add name="BlockViewHandler" path="*.aspx" verb="*" 
        preCondition="integratedMode" 
        type="System.Web.HttpNotFoundHandler"/>
    </handlers>
  </system.webServer>
</configuration>

Let me know if you run into problems with this.

Technorati Tags: ,,

What others have said

Requesting Gravatar... Garry Shutler Feb 12, 2008 8:53 AM
# re: Blocking Direct Access To Views in ASP.NET MVC
I've had problems with common files such as style sheets not being retrieved when denying all users. Might be worth checking.
Requesting Gravatar... Chris Ortman Feb 12, 2008 8:59 AM
# re: Blocking Direct Access To Views in ASP.NET MVC
I think you will also need to be using an IIS wildcard mapping or make sure that whatever extension your views use is mapped to the ASP.Net ISAPI dll.
Requesting Gravatar... Scott Bellware Feb 12, 2008 10:37 AM
# re: Blocking Direct Access To Views in ASP.NET MVC
Why not just make it part of the convention of the framework? If your routing engine is on-line, then it could simply deny access to the conventional path where the views live.
Requesting Gravatar... Mike Bosch Feb 12, 2008 10:52 AM
# re: Blocking Direct Access To Views in ASP.NET MVC
If we're using Membership, wouldn't this redirect the user to the login url?
Requesting Gravatar... Chris Ortman Feb 12, 2008 12:15 PM
# re: Blocking Direct Access To Views in ASP.NET MVC
Probably the better way to do this is to map these files to the ASP.Net forbidden handler.

@Scott: I have no problem with the out of the box behaviour being that requests to those resources are denied, but I think you'd be giving responsibilities to the RoutingEngine that it ought not to have. The RoutingEngine's job is to turn a URL into :controller, :action, :params not authorize access to resources.
Requesting Gravatar... Damien Guard Feb 12, 2008 12:27 PM
# re: Blocking Direct Access To Views in ASP.NET MVC
You might also want to consider:


<httpHandlers>
<remove verb="*" path="*.asmx"/>
<add path="*.aspx" verb="*" type="System.Web.HttpForbiddenHandler"/>
</httpHandlers>
Requesting Gravatar... Damien Guard Feb 12, 2008 12:38 PM
# re: Blocking Direct Access To Views in ASP.NET MVC
Actually, even better don't even reveal their existance:

<httpHandlers>
<remove verb="*" path="*.aspx"/>
<add path="*.aspx" verb="*" type="System.Web.HttpNotFoundHandler"/>
</httpHandlers>
Requesting Gravatar... Haacked Feb 12, 2008 1:16 PM
# re: Blocking Direct Access To Views in ASP.NET MVC
Thanks for the feedback Damien et all! I'll make those changes.
Requesting Gravatar... Scott Bellware Feb 12, 2008 3:43 PM
# re: Blocking Direct Access To Views in ASP.NET MVC
Chris,

I'm really not talking about authorization, I'm talking about what makes sense for requests processed by the MVC framework, or the request handlers in ASP.

The routing engine exposes a meaningful, higher-level API for configuring request handling. That means that it has the ability to treat requests for internal, framework-specific resources as requests for resources that don't exist.

So, if you've got the MVC framework in-play in your app, then the framework's code should be responsible for default behaviors for request routing for resources that are its concern.
Requesting Gravatar... Matt Feb 13, 2008 6:54 AM
# re: Blocking Direct Access To Views in ASP.NET MVC
One selling point for those who like WebForms is that you don't have to give them up to incorporate MVC. Isn't this in conflict with that point?
Requesting Gravatar... Aaron Jensen Feb 13, 2008 7:04 AM
# re: Blocking Direct Access To Views in ASP.NET MVC
I'll revert again to my longstanding assertion that you should strongly consider changing the extension of the views. The views are *not* aspx pages and the proof is here and everywhere else you look. I've heard the argument that you want to reuse stuff from aspx, which I can understand, but I don't think that's a good thing either. It gives functionality to the aspx view engine that other view engines must emulate or be left behind. I'm excited to see the next release, but I really think a rename/refactor of the view needs to happen.
Requesting Gravatar... Justice~! Feb 13, 2008 8:40 AM
# re: Blocking Direct Access To Views in ASP.NET MVC
Matt - but who really likes WebForms anyway? In the end, you need to make the right choice. The choice for your CHILDREN.
Requesting Gravatar... Chris Ortman Feb 13, 2008 10:57 AM
# re: Blocking Direct Access To Views in ASP.NET MVC
@Scott: Even in rails the RoutingEngine doesn't have any 'default' behavior. The generator does however setup the conventional controller/action routes.

Think about how you would build it. Would you have the routing engine automatically redirect anything requested from /views ? What if I have a views controller or area? So now you got to add complexity to the routing engine to control the behavior anyway.

When it really is as simple as having the MVC project template generate a web.config file with the proper handler mappings.

That said, I don't think either solution is ideal. I would much rather have a 'public' folder that is setup in IIS with the rest of my app code in a level above.

@Aaron: +1
I like the Rails 2.0 naming convention of viewname.viewengine.responseformat. So something more like View.aspx.html
Requesting Gravatar... Joe Chung Feb 13, 2008 9:11 PM
# re: Blocking Direct Access To Views in ASP.NET MVC
It's looking. You'll need this:

<configuration>
<system.webServer>
<validation validateIntegratedModeConfiguration="false"/>
</system.webServer>
</configuration>

to have both styles of HTTP handler configuration work properly on an IIS 7 box that has II6 compatibility mode enabled.
Requesting Gravatar... Joe Chung Feb 13, 2008 9:27 PM
# re: Blocking Direct Access To Views in ASP.NET MVC
Err, it's looking good, that is.
Requesting Gravatar... Haacked Feb 14, 2008 8:43 AM
# re: Blocking Direct Access To Views in ASP.NET MVC
Thanks Joe!
Requesting Gravatar... Troy Cox Feb 14, 2008 8:49 PM
# re: Blocking Direct Access To Views in ASP.NET MVC
What would this do to public sites where search engine bots are important for traffic?
Requesting Gravatar... Haacked Feb 15, 2008 9:44 AM
# re: Blocking Direct Access To Views in ASP.NET MVC
@Troy Nothing. You're blocking access to the view templates, not to the site itself.
Requesting Gravatar... Dan P Mar 08, 2008 7:41 AM
# re: Blocking Direct Access To Views in ASP.NET MVC
I tried this out, but it seems to ignore a 404 errorpage specified in web.config. All I get is the default asp.net 404 page. Has anyone else run into this problem?
Requesting Gravatar... Dan P Mar 08, 2008 7:47 AM
# re: Blocking Direct Access To Views in ASP.NET MVC
Nevermind, it does work as I expected, I'm just an idiot. Next time I need to remember that I set RemoteOnly for the error pages.

What do you have to say?

(will show your gravatar)
Please add 2 and 1 and type the answer here: