0

I have a problem with ASP.NET in conjunction with Unity. Today the constructors of my controllers which require authenticated users have some parameters which can only be populated by Unity if the calling user is authenticated. If I call the URL which leads to such a controller UNAUTHENTICATED, the ASP.NET MVC pipeline tries to create the controller and Unit throws an exception because the required objects does not exist in the container. For the authentication I am using WSFederationAuthenticationModule and SessionAuthenticationModule and in the web.config I configured "Forms" as the authentication mode to force ASP.NET to redirect to the login page. I expected that the pipeline does not create a controller instance if the user is unauthenticated but redirects directly to the login page.

Tobias J.
  • 1,043
  • 12
  • 31

1 Answers1

0

the constructors of my controllers which require authenticated users have some parameters which can only be populated by Unity if the calling user is authenticated

That's the root of your problem. This means that the constructor of that service does too much. Constructors should not do more than store the incoming dependencies. This way you can compose object graphs with confidence.

The building of object graphs should in general be static. This means that the resolved object graph should not change based on runtime conditions (there are exceptions, but this is a good rule of thumb). It shouldn't matter whether or not a user is authorized or not, the service class should still be composed and injected. This means that authorization and loading of data is done at a later point in time; the moment that the request is actually executed (which is directly after the object graph is composed).

So instead of doing this work in the constructor, move this work to the moment that the action method is executed. You can move this logic to a service that does the authentication, use a filter attribute, or implement this using a decorator.

Steven
  • 166,672
  • 24
  • 332
  • 435
  • My constructor does not do the authorization. There is already a filter attribute (ON THE CONTROLLER!) which does and in addition forms authentication is enabled. Therefore I do not understand why the MVC runtime tries to create an instance of the controller if the user is unauthenticated. So what?! I will do the creation of the user-specific repository instance later instead of using constructor injection. – Tobias J. Feb 24 '14 at 14:32
  • 1
    MVC itself simply requests an `IController` from the `IControllerFactory` (and calls `.Execute` on it) and that factory is allowed to return anything (as long as it implements `IController`). It's the `System.Web.Mvc.Controller` class that handles the authorization and it can only do authorization when it's called. MVC can't do the authorization itself, since it allows you to completely replace the authorization mechanism. – Steven Feb 24 '14 at 16:50