In my C# MVC4 application, I am performing a couple different redirect to actions from inside of a custom authorize attribute dependent upon if the user is logged in, in a certain role, etc.
I've placed the authorize attribute above one of my action results. If the user is not logged in or not authenticated or logged in but not a member of either group that I check against, I want the code within the action result to be performed. If the user is logged in and is a member of either group, I want a redirect to another action to occur (this is currently working).
With my current code, those that are logged in and within a specified group are re-directed as desired. All those listed in the other categories, cause my AuthorizationContext to be null. Knowing that when this is null HandleUnauthorizedRequest is called, I have attempted to override it to allow access to the original actionresult but cant figure it out.
No matter what I try I receive the error: Object Reference not set to an instance of an object
on the line with: filterContext.Result = new RedirectToRouteResult(
My authorize attribute code is below:
public class AuthorizeEditAttribute : AuthorizeAttribute
{
public string hName { get; set; }
public override void OnAuthorization(AuthorizationContext filterContext)
{
base.OnAuthorization(filterContext);
// Check if user is authenticated and if this action requires authorization
if (filterContext.HttpContext.User.Identity.IsAuthenticated
&& filterContext.ActionDescriptor.IsDefined(typeof(AuthorizeAttribute), true)
|| filterContext.ActionDescriptor.ControllerDescriptor.IsDefined(typeof(AuthorizeAttribute), true))
{
List<object> attributes = new List<object>(filterContext.ActionDescriptor.GetCustomAttributes(typeof(AuthorizeAttribute), true));
attributes.AddRange(filterContext.ActionDescriptor.ControllerDescriptor.GetCustomAttributes(typeof(AuthorizeAttribute), true));
hName = filterContext.Controller.ValueProvider.GetValue("hSearch").AttemptedValue;
// Check all authorzation attributes
foreach (var attribute in attributes)
{
var authAttribute = attribute as AuthorizeAttribute;
if (authAttribute != null)
{
if ((filterContext.HttpContext.User.IsInRole("TCL-CAdmin")) || (filterContext.HttpContext.User.IsInRole("TCL-C Group")))
{
// User is not authorized to perform edits so redirect to Index_Perm ActionResult
filterContext.Result = new RedirectToRouteResult(
new RouteValueDictionary
{
//{ "area", "" },
{ "controller", "Home" },
{ "action", "Index_Perm" },
{ "hSearch", hName.ToString() }
});
break;
}
else
{
filterContext.Result = new RedirectToRouteResult(
new RouteValueDictionary
{
//{ "area", "" },
{ "controller", "Home" },
{ "action", "Index" },
{ "hSearch", hName.ToString() }
});
break;
}
}
}
}
else
{
filterContext.Result = new RedirectToRouteResult(
new RouteValueDictionary
{
{ "controller", "Home" },
{ "action", "Index" },
{ "hSearch", hName.ToString() }
});
}
}
protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
{
filterContext.Result = new RedirectToRouteResult(
new RouteValueDictionary
{
{ "controller", "Home" },
{ "action", "Index" },
{ "hSearch", hName.ToString() }
});
}
}
}
Rather than overriding HandleUnauthorizedRequest, I have also tried modifying the beginning portion of OnAuthorization to look like this:
public override void OnAuthorization(AuthorizationContext filterContext)
{
base.OnAuthorization(filterContext);
if (filterContext.Result is HttpUnauthorizedResult)
{
filterContext.Result = new RedirectToRouteResult(
new RouteValueDictionary
{
{ "controller", "Home" },
{ "action", "Index" },
{ "hSearch", hName.ToString() }
});
}
and I still receive the same warning about object reference.