After you did not find anything specifically to solve my problem on the Internet, I decided to look into the life cycle of an ASP.NET MVC 5 application. I found that I could create a custom IControllerFactory (or inherit from DefaultControllerFactory), where I could define a CreateController method.
During CreateController, I check if the user is verified. If they are, I just let the DefaultControllerFactory create the controller, as usual.
If the user is not authenticated, I create my (very) simple "Auth" controller instead of the requested controller (the one that has many levels of dependencies), while the RequestContext remains unchanged.
The Auth controller will be created without problems, since it has no dependencies. Note. No action is taken on the Auth controller. After creating the Auth controller, the global AuthorizeAttribute attribute is started and the user must authenticate (through OpenID Connect to Azure AD and ADFS).
After logging in, they are redirected back to my application with the original RequestContext, while still in tact. CusomControllerFactory sees the user as an authenticated and requested controller is created.
This method works fine for me, since my controllers have a large chain of dependencies that they introduce (i.e. the controller depends on ISomeService, which depends on many ISomeRepository, ISomeHelper, ISomethingEles ...), and none of the dependencies are resolved before until the user is logged in.
I can still definitely hear other (more elegant) ideas on how to achieve what I asked in my original question.
CustomControllerFactory.cs
public class CustomControllerFactory : DefaultControllerFactory { public override IController CreateController(RequestContext requestContext, string controllerName) { var user = HttpContext.Current.User; if (user.Identity.IsAuthenticated) { return base.CreateController(requestContext, controllerName); } var routeValues = requestContext.RouteData.Values; routeValues["action"] = "PreAuth"; return base.CreateController(requestContext, "Auth"); } }
Global.asax.cs
public class MvcApplication : HttpApplication { protected void Application_Start() {
AuthController.cs
public class AuthController : Controller { public ActionResult PreAuth() { return null; } }