ASP.NET MVC Controller Constructor Called Before Authentication - asp.net-mvc

I have an ASP.NET MVC application with a controller that looks something like this:
[Authorize]
public class MyController : Controller
{
IMyRepository myRepository;
public MyController(IMyRepository myRepository)
{
this.myRepository = myRepository;
}
...
}
I have noticed that this constructor gets called prior to authenticating the user, so if you are visiting the page for the first time the constructor is called prior to redirecting you to the login screen. There are many problems with this, the login page loads slower, the site has greater exposure to DOS attacks, and I'm a little nervous about unauthenticated, unauthorized users being able to invoke code 'behind the walls' sort of speak.
I could check the incomming request in the constructor and bail unless the user is authorized, but I'm using IOC (Windsor) which makes that a bit tricky, my repository is going to be initialized regardless of whether or not I store the instance, so I'd be left checking authentication in each repository's constructor. Is there an easy way to get .NET MVC to authenticate the user prior to invoking the constructor? I'm thinking something like adding [PrincipalPermission(SecurityAction.Demand, Authenticated = true)] to the controller, but there might be a better way still.
EDIT:
Ok, not too happy about it, but the show must go on for now. I cannot delay initializing the repository until some later point in time from within the controller. When your controller uses IOC as in my example, you get an already instantiated implementation of your repository interface at the time that the controller is instantiated. If I had control over the repository being created, I could easily just call IsAuthenticated, no need for a new method. In order to take control of the repository initialization you would have to implement some sort of lazy/late initialization in the repository itself in each implementation. I do not like this solution because it adds needless complexity and more importantly coupling between the controller and repository. The repository implementation(s) may be used in other contexts where lazy initialization doesn't make sense IMHO.

The controller needs to be instantiated before authorization happens because it can act as its own authorization filter via the OnAuthorization method. Changing that behavior would involve replacing some core parts of the mvc pipeline. Is there a particular reason why you think the AuthorizedAttribute might not do its job?
Another option you could consider is initializing your repository in the OnActionExecuting of your controller method instead of in the constructor.

You can use HttpModules (or HttpHandler) to authenticate the request earlier in the pipeline.
MSDN: Introduction to HTTP Modules
MSDN: Implementing Intercepting Filter in ASP.NET Using HTTP Module
EDIT
With the introduction of OWIN you can configure the entire request pipeline middleware and put authorization at whatever stage you want. Same idea as above but a bit easier to implement.

Paul,
the instantiation of the controller is many many processes ahead of any actions on the controller being callable. even if the would be attacker attempted to benefit from this time lapse between instantiation and the login-screen, the controller action would only be able to run if the action had the authority to do so i.e. i'm assuming that your actions or controller all have the [Authorize] attribute on them.
I don't think you need worry too much about this and can rest easy, tho' i understand your obvious curiosity.

In terms of DOS attacks, it really should not matter -- after the first hit, which one sees alot when developing, the controller instantiation should be cheap. Well, unless you are DDOSing yourself by having the constructor do actual work such as pre-caching database lookups . . .

Related

ASP.NET Mvc - AutoMapper Best Practice - Performance

I've not looked at the AutoMapper source code yet but was just about to make some changes to an API controller in my solution and had a thought.
The way I like to code is to keep my controller methods as concise as possible, for for instances I make use of a generic Exception attribute to handle try{}catch{} scenarios.
So only the code that is absolutely relevant to the controller action is actually in the action method.
So I just arrived at a situation where I need to create an AutoMapper map for a method. I was initially thinking that I would add this (as I have done previously) to the controller constructor so its available immediately.
However, as the controller grows following this pattern may introduce a lot unnecessary AutoMapper work depending on the controller action method which is invoked.
Considering controllers are created and destroyed per request this could get expensive.
What are some recommendations around this? Considering AutoMapper is accessed statically I was wondering if it's internals live beyond the request lifetime and it internally checks for an existing map before creating a new one each time CreateMap() is invoked?
You should create your maps (CreateMap) once per AppDomain, ideally when this domain starts (Application_Start).

Register .net MVC3 ControllerContext into windsor container

With ASP.NET MVC3 what would be the best way to register the requests ControllerContext into castle windsor container? Ultimately I'd like to be able to say
container.Resolve<ControllerContext>();
and have the requests controller context returned.
More detail
The vast majority of my actions are just going to do some validation, authentication, etc.. before sending a message to nservicebus to actually do the work. To avoid having to copy/paste these 20/30 lines of code all over the place I have put them into a handler class which my controllers take a dependency on in the constructor, the actions then call this class which leaves my actions containing just one line of code.
One of the child classes that makes up the handler needs to know about the route that was taken, I could just pass the controller to the handler and then onto this class but it seems a bit messy. It would be nice if there was a way to get Windsor registered to provide it for me.
I don't think you can register the ControllerContext without some very ugly hacks, and IMHO it's not a good idea anyway. The ControllerContext belongs to the controller, it's not meant to be shared around.
However, if you only need the routing information, you can register it like this (UNTESTED!):
container.Register(Component.For<HttpContextBase>()
.UsingFactoryMethod(() => new HttpContextBaseWrapper(HttpContext.Current))
.LifeStyle.PerWebRequest,
Component.For<RouteData>()
.UsingFactoryMethod(k => RouteTable.Routes.GetRouteData(k.Resolve<HttpContextBase>()))
.LifeStyle.PerWebRequest);
Also see ASP.NET MVC & Windsor.Castle: working with HttpContext-dependent services for more details.
I don't know concretely what you're trying to achieve but I'd look into doing it with filters or custom ActionResults instead.
Not really an answer to the original question but I can't stand dubious architectural moves :) It seems for me like ControllerContext isn't a best (well, not even a good one) place to try to extend from. The ModelBinders and ActionAttributes are the places to help with repeating code. They can take model mapping, binding and validation on their own thus freeing controllers from that responsibility.
Well, generally, what you'd really want to do is to use Dependency Injection for Controllers themselves injecting configured instances of somewhat IAuthenticationService and IValidationService (concrete implementations of them would contain all those 20/30 reusable lines of code). Then in Controllers you just call them in one line of code (or even use the MVC3 Global Filters feature to make that completely transparent).

What is the lifetime of a ASP.NET MVC Controller?

I'm in the process of developing my MVC application and I was thinking, What is the lifetime of a controller class?
When does it get created? How many instances of a single controller are there? what are the implications of local variables? when is it destroyed?
I'm sure there is a good link somewhere floating around on the internet, but my google-fu couldn't find it.
Stephen Walther has a great article on the life-cycle of a request being handled by the MVC Framework.
Here's a extract from the top of his article, it goes on to explain each step in detail:
Overview of the Lifecycle Steps
There are five main steps that happen when you make a request from an ASP.NET MVC website:
1. The RouteTable is Created
This first step happens only once when an ASP.NET application first starts. The RouteTable maps URLs to handlers.
2. The UrlRoutingModule Intercepts the Request
This second step happens whenever you make a request. The UrlRoutingModule intercepts every request and creates and executes the right handler.
3. The MvcHandler Executes
The MvcHandler creates a controller, passes the controller a ControllerContext, and executes the controller.
4. The Controller Executes
The controller determines which controller method to execute, builds a list of parameters, and executes the method.
5. The RenderView Method is Called
Typically, a controller method calls RenderView() to render content back to the browser. The Controller.RenderView() method delegates its work to a particular ViewEngine
Assuming you don't change the default ControllerFactory, controllers will be created for every request and will be garbage collected "sometime after" the request has completed.
In short, you don't need to worry about race conditions for instance variables (though you do for static variables, obviously). Having said that, I'd recommend keeping your controller actions reentrant for the sake of cleaner code.

Why is there no internal Controller redirect in ASP.Net MVC (or CodeIgniter)?

ASP.Net MVC Controllers have several methods of forwarding control to another controller or action. However, all of them cause a client redirect, with a 302 and a new browser request.
Why is there no internal "call another controller's action" functionality, without getting the client involved? I'm pretty sure that the php CodeIgniter framework also lacks this functionality.
The best reason that I can come up with is that ultimately it's unnecessary, since any code you want to call into could be factored out into someplace common, and in ASP.Net MVC at least, the operation might be quite expensive. But a lot of people ask about this, and it seems like it would ultimately be a convenience.
So... lots of smart people designed these frameworks. There must be some good reasons for not having this?
In Codeigniter you can set custom routes and stuff to direct certain URLs to other controllers/actions, but I think you mean in the middle of a controller function to jump into another?
If there is any business logic you have, especially if it's going to be reused, it should go into a model, not a controller. You can also specify different views in a controller depending on some condition or something. If you have repeating code that doesn't 'fit' into a model, then it should probably end up as a static helper function, or in a library class.
So yeah, I think you're right on when you say:
The best reason that I can come up with is that ultimately it's unnecessary, since any code you want to call into could be factored out into someplace common
This forces you into staying within the MVC pattern.
Best to keep your controllers lightweight anyways.
Well, at least in ASP.NET MVC, controller actions are just C# methods called in creative ways. So you can just explicitly call another controller action, like so:
Sample controller:
public class SampleController : Controller
{
public ActionResult Foo()
{
return View("foo");
}
public ActionResult ShowMeFoo()
{
return Foo();
}
}
Now, I think in most cases one wouldn't want to do this. Considering urls as a RPC interface for your app, it should forward to a different url when getting different results. Doesn't apply to all cases, but can appy to most.
I suspect it may go against the REST idea, everything is a resource. If you wish to perform a server transfer, you can as well offer an extra url for that resource. This way the client will know on that specific url he will receive one particular representation of a resource, and not under circumstances something else. That makes sense actually.

How to have Global Authorization in asp.net mvc

I have been looking around but i don't see any spec for this, maybe i search a wrong keyword. But i'm here so i should ask something.. :)
I'm familiar with Authorize Attribute, but I think it only apply to Actions. What should i do if i want my whole application to authorize first before getting access to any actions?
It will be very pain to just repeat in every action to put [Authorize] tag on top of them.
Thank you very much
It is not quite correct that AuthorizeAttribute applies only to actions. It can also be applied to classes containing actions. If you have a base controller type for your application (which can be abstract, if you like), and every other controller is a subtype of that base type, then your entire application now requires authorization, with just a few characters of typing.
You should find a way to make AuthorizeAttribute work for you; this is the standard way of doing authentication in ASP.NET MVC.
No, you can mark your controller with AuthorizeAttribute like an action. Check out here.

Resources