Asp.Net Forms Authentication with Groups and Roles
I found this great post from Rob Convery on creating a FilterAttribute that can be used to authorize specific controller actions against roles. I’d always wanted to implement a Group strategy and had made several attempts. They all seemed like kluges and I was never really happy.
One small change to Rob’s code and I can do grouping in a simple manner. Note: If you have a large number of roles and groups, this will probably not work for you. Also, this uses Asp.Net MVC.
ok, Rob’s code basically checked for a single role and you could use a constant to supply the role name. Something like
[RequiresRoleAttribute(RoleToCheckFor = ApplicationRoles.AdminRole)]
public ActionResult Edit(int id)
My change just allows you to pass more than one role into RoleToCheckFor. Basically, I split RoleToCheckFor using a comma.
[RequiresRoleAttribute(RoleToCheckFor = ApplicationRoles.ChangeClientsGroup)]
public ActionResult Edit(int id)
public class ApplicationRoles
{
public const string AdminRole = "Admin";
public const string EntryRole = "Entry";
public const string ManagementRole = "Management";
public const string SecurityRole = "Security";
public const string ChangeClientsGroup = Admin + "," + Entry;
}
public class RequiresRoleAttribute : ActionFilterAttribute
{
public string RoleToCheckFor { get; set; }
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
//redirect if the user is not authenticated
if (!String.IsNullOrEmpty(RoleToCheckFor))
{
if (!filterContext.HttpContext.User.Identity.IsAuthenticated)
{
//use the current url for the redirect
string redirectOnSuccess = filterContext.HttpContext.Request.Url.AbsolutePath;
//send them off to the login page
string redirectUrl = string.Format("?ReturnUrl={0}", redirectOnSuccess);
string loginUrl = FormsAuthentication.LoginUrl + redirectUrl;
filterContext.HttpContext.Response.Redirect(loginUrl, true);
}
else
{
bool isAuthorized = false;
string[] roles = this.RoleToCheckFor.Replace(" ", string.Empty).Split(',');
foreach (string role in roles)
{
isAuthorized = filterContext.HttpContext.User.IsInRole(role);
if (isAuthorized) { break; }
}
if (!isAuthorized)
{
ApplicationError appEevent = new ApplicationError();
appEevent.Caller = Thread.CurrentPrincipal.Identity.Name + ":" + filterContext.Controller.GetType().Name + ":" + filterContext.HttpContext.Request.Path;
appEevent.ErrorMessage = "Unauthorized access attempt";
ApplicationManager.RecordEvent(appEevent);
FormsAuthentication.SignOut();
filterContext.HttpContext.Response.Redirect("/SecurityViolation.htm", true);
}
}
}
else
{
throw new InvalidOperationException("No Role Specified");
}
}
}
Hopes this works for you!
Comments