ASP.NET MVC Controller / Action Protection

If I want only an administrator to be able to access an action called "ManagerUser", I know that I can do this:

[Authorize( Roles = Constants.ROLES_ADMINISTRATOR )] public ActionResult ManageUser( string id ) { } 

What if I want to give everyone access only to the administrator? I do not want to write all the roles there by function: |.

Any recommendations / ways out?

+4
source share
3 answers

You can create your own authorization attribute, for example, "AuthorizeAllExceptAdmin". Inside this class, you just need to check if the current user was an administrator, and if they rejected it, otherwise accept it.

Here's a good tutorial , but you will probably get something like:

 public class AuthorizeAllExceptAdmin : AuthorizeAttribute { protected override bool AuthorizeCore(HttpContextBase httpContext) { return !httpContext.User.IsInRole(Constants.ROLES_ADMINISTRATOR); } } 

Then your controller method will look like this:

 [AuthorizeAllExceptAdmin] public ActionResult SomethingOnlyNonAdminsCanDo() { } 

Here is an example of a user attribute that accepts roles for failure.

 public class DoNotAuthorize : AuthorizeAttribute { private IEnumerable<string> _rolesToReject; public DoNotAuthorize(IEnumerable<string> rolesToReject) { _rolesToReject = rolesToReject; } protected override bool AuthorizeCore(HttpContextBase httpContext) { foreach (var role in _rolesToReject) { if (httpContext.User.IsInRole(role)) return false; } return true; } } 

Then your controller method will look like this:

 [DoNotAuthorize(new [] {Constants.ROLES_ADMINISTRATOR})] public ActionResult SomethingOnlyNonAdminsCanDo() { } 

I would have thought before choosing one of the options above. If you think that you will have several methods (or entire controllers) with similar authorization requirements (i.e., several actions that the administrator cannot perform), I would stick with a non-parameterized user attribute. This way you can develop them all together (only by changing the user attribute) later. For example, perhaps later you want admins to switch to a special mode where they can perform these actions.

Alternatively, if authorization is more diverse among actions, then using a parameterized list makes sense, since they will develop relatively independently.

+11
source

Besides creating the custom AuthorizeAttribute attribute suggested by manu, you can use PrincipalPermission with Deny-SecurityAction:

 [PrincipalPermission(SecurityAction.Deny, Role="Administrator")] 
+5
source

In my application, I do not use roles, so I have to query the database to determine if the user has access or not. The benefits of the code below are that you can easily redirect the user to a specific action. I explained the code in my blog post http://blog.athe.la/2009/12/implementing-permission-via-windows-authentication-in-asp-mvc-using-action-filters/

 public class DatabaseRepository() { private readonly DatabaseDataContext db = new DatabaseDataContext(); public bool UserHasPermission(string userLogon) { return (from permission this.db.Permissions where permission.HasPermissionSw == true select permission).Contains(userLogon); } } public class UserHasPermission: ActionFilterAttribute { private readonly DatabaseRepository databaseRepository = new DatabaseRepository(); private readonly string redirectAction; public UserHasPermission(string redirectTo) { this.redirectAction = redirectTo; } public override void OnActionExecuting(ActionExecutingContext filterContext) { string userLogon = filterContext.HttpContext.User.Identity.Name; if (!this.databaseRepository.UserHasPermission(userLogon)) { string routeController = filterContext.Controller.ControllerContext.RouteData.Values["controller"]; filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary(new { controller = routeController, action = this.redirectAction })); } } } 

Then your controller will look something like this:

 [UserHasPermission("NoAccess")] public ActionResult SecretArea() { // run all the logic return View(); } public ActionResult NoAccess() { return View(); } 
+1
source

Source: https://habr.com/ru/post/1301853/


All Articles