I’m in the process of creating an Intranet site using Windows Authentication.
Maybe I’m not going about this the best way, but I’m trying to load partial views via calling a controller method that has an Authorize action filter wrapped around it, so that only authorized individuals are able to see that portion of the page. Say, for instance, I wanted to load administrator tools onto the page but only if the logged-in individual is an administrator.
So on the index.cshtml page I might have something like:
@Html.Action("LoadAdminTools","ControllerName")
The Controller would contain the code:
[Authorize(Roles="Admins")]
public ActionResult LoadAdminTools()
{
return PartialView("_AdminToolsPartialView");
}
And then the partial view containing the admin controls (or whatever) would render to the page – only if the logged-in user was part of the Admins role.
The ‘problem’ I’m having is that if the person logged-in is not authorized to load the partial view, the browser pops up the login dialog asking for the user’s credentials. Closing the dialog without inputting any credentials causes the expected results – the partial view doesn’t load while the rest of the page does. Cool, but annoying. Input the incorrect credentials and you get a 401 error – also as expected.
If it helps: In IIS, Anonymous Authentication is disabled, Windows Authentication is enabled.
“Automatic logon with current user name and password” is selected in Internet Options under “Security Settings – Local Intranet Zone.”
My question is this: Is there a way to use the [Authorize] action filter to load a partial view (or to do anything, really) without the browser asking the user to log in? Just have it take the current logged-in credentials, check if they comply with the action filter, if they do, load the partial view, if not, then don’t. If there isn’t, is there simply a better way of going about what I want to accomplish here?
UPDATE
Beautiful. I read the solution to the question you posted, Mystere Man, created a new class inside the Controller’s folder called IntranetAuthorizeAttribute.cs, threw in the code:
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = true)]
public class IntranetAuthorizeAttribute : System.Web.Mvc.AuthorizeAttribute
{
protected override void HandleUnauthorizedRequest(System.Web.Mvc.AuthorizationContext filterContext)
{
if (filterContext.HttpContext.Request.IsAuthenticated)
{
filterContext.Result = new System.Web.Mvc.HttpStatusCodeResult(403);
}
else
{
base.HandleUnauthorizedRequest(filterContext);
}
}
}
Replaced the Authorize filter with my new IntranetAuthorize filter:
[IntranetAuthorize(Roles="Admins")]
public ActionResult LoadAdminTools()
{
return PartialView("_AdminToolsPartialView");
}
And now it loads the page just fine with no browser login dialog – with the partial view when it’s an authorized user, and without the partial view when it is not an authorized user =)
Thank you!
Unfortunately, ASP.NET (and thus MVC) conflates Authorization and Authentication in may scenarios.
Check this question for a solution.
Why does AuthorizeAttribute redirect to the login page for authentication and authorization failures?