Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ASP.NET MVC Controller Constructor Called Before Authentication

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.

like image 710
Paul Avatar asked Dec 16 '10 12:12

Paul


People also ask

Can we use constructor in MVC controller?

ASP.NET Core MVC controllers request dependencies explicitly via constructors.

How authentication and authorization works in ASP.NET MVC?

Windows Authentication is used in conjunction with IIS authentication. The Authentication is performed by IIS in one of three ways such as basic, digest, or Integrated Windows Authentication. When IIS authentication is completed, then ASP.NET uses the authenticated identity to authorize access.

What is the difference between authentication and authorization in MVC?

Authentication is done before the authorization process, whereas the authorization process is done after the authentication process. In the authentication process, the identity of users are checked for providing the access to the system.

What is the default authentication in MVC?

The default authentication is, Individual User Accounts.


2 Answers

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.

like image 189
marcind Avatar answered Sep 22 '22 08:09

marcind


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.

like image 39
Paul Avatar answered Sep 21 '22 08:09

Paul