How to set a privilege inside a role in ASP.NET MVC? - asp.net

I currently have a system where there is a user table, a role table, and a user-roles association table, where one user can be associated to multiple roles (like Admin, BasicUser, etc.). I am able to authorize action methods based on these roles. This is from the Identity framework.
Now I want to add support for privileges so that action methods can be restricted based on those as well, rather than just by roles. For example, in a Controller, I may have an HTTPPost action that only someone with a "Write" privilege should be able to perform successfully.
What changes do I need to make so that I can assign privileges to roles? I.E., I want to select the "Admin" role to have the "Write" and "Read" privileges, while a "BasicUser" role will only be assigned a "Read" privilege. This way, an Admin can access any method that is allowed by the Write privilege, while the BasicUser can not.
If I were to create another table called "Privilege" and an association table between that and roles, and the code to set privileges in a role, how can I use the privilege as a filter? So for example, the below action should only be allowed to be performed by a user in a role that has the "Write" privilege attributed to it.
[Write]
public ActionResult Create()
{
return View();
}
Thank you.

The same way the AuthorizeAttribute works, you can create a custom authorization attribute inheriting from it:
public class AuthorizePrivilegeAttribute : AuthorizeAttribute
{
// Custom property
public string Privilege { get; set; }
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
// Reusing default authentication.
var isAuthorized = base.AuthorizeCore(httpContext);
if (!isAuthorized)
{
return false;
}
return YourCustomCode.HasPrivilege(this.Privilege))
}
}
Then using it on top of your method:
[AuthorizePrivilege(Privilege = "Write")]
public ActionResult Create()
{
return View();
}

Related

how to add specific role to an action that has a global authorization on controller

I have Controller that has a Authorization for Specific Role.
[Authorize(Roles = "admin")]
public class PanelController : Controller
{
}
Now I want One my Actions have been also accessible for role user
but i doesnt work when I do this
[Authorize(Roles = "admin")]
public class PanelController : Controller
{
public ActionResult Index()
{
return View();
}
[Authorize(Roles = "admin,user")]
public ActionResult MyAction()
{
return View();
}
}
in MyAction Method the user with role user have no access.
I use asp.net mvc5 and identity 2.
I would be very pleased if someone would help me.
The effect of Authorization attributes when applied to both Controller and Action is to AND the roles. Hence in this case your User role will not work as your Controller attribute is going to invalidate the AND operation being carried out.
You could use User role on the Controller and apply Admin role to all other Actions. This will work provided your Admins have the User role assigned to them.

Net core custom user property

I'm using the default authorization in my .NET Core project. I want to check if an user is admin so in ApplicationUser.cs model I've added this:
public class ApplicationUser : IdentityUser
{
public bool admin { get; set; }
}
I migrated these changes into my SQL database and I can see the 'admin' property inside the AspNetUsers table. How do I check the 'admin' property of the currently logged in user?
You can access the current user instance through the UserManager<T> object, which can be injected into your controller as a constructor parameter. The method GetUserAsync takes a ClaimsPrincipal, which in this case is the User of the HttpContext.
private readonly UserManager<ApplicationUser> _userManager;
public HomeController(UserManager<ApplicationUser> userManager) {
_userManager = userManager;
var user = _userManager.GetUserAsync(HttpContext.User);
}
I agree with the above answer by Peter to just use the user variable and check for user.admin, however, I strongly suggest extending your project to use a simple Role-based Authorization to simplify things in the long run. You can achieve this with the following documentation: https://learn.microsoft.com/en-us/aspnet/core/security/authorization/roles

Automatically load model on each request

Note: Not sure if the following is the right way of doing what I want.
Background: I have a forum (php) and I am creating a asp.net MVC web application that is sort of independent from the forum, except the login data. The user registers and logins through the forum but the app needs to check the login status by reading the session hash from the cookie and comparing it with the forum's database of logged in users.
Objective: I to include my UserModel class on every request to see if the user has certain permissions to do what he's requesting to do. Also for my views to display User related data.
Do I need to manually add something like this to every controller's action in my application?
public ActionResult Index()
{
UserRepository userRep = new UserRepository();
UserModel user = userRep.GetUserBySession(Request.Cookies["userHash"].Value);
//do stuff with user
...
return View(myViewModel);
}
Look at ValidationAttribute. You can roll your own, and have your own custom logic in it:
public class CustomAttribute : ValidationAttribute
{
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
UserRepository userRep = new UserRepository();
UserModel user = userRep.GetUserBySession(Request.Cookies["userHash"].Value);
if (user == null) {
// Redirect to login?
}
}
}
Then you can decorate your methods like this:
[CustomAttribute]
public ActionResult Index()
Or if you will be needing to apply it to every HTTP method in your class, you can decorate it at class level:
[CustomAttribute]
public class MyClass

Need to restrict AD users - Windows Authentication in ASP.NET

I have a website which uses Windows Authentication. I need to restrict access to only a few users, who are present in a local database. How can I achieve it? Example DB has "domain\user1", only user1 should be allowed. "domain\user2" should not be allowed.
Thanks in advance
in your controller class, you can use the [Authorize] attribute to restrict access.
If you use it by itself, then you restrict the entire controller to only authenticated users.
If you want specific users to access a controller, you can add parameters to the Authorize attribute, such as:
[Authorize(Roles ="Administrators")]
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
In the example above, I'm restricting the use of the homecontroller to administrators only, I can also give access only to specific users:
[Authorize(Users = "user1")]
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
You can also apply this to specific methods in your controller

Securing ajax calls in a ASP.NET MVC application

I have an ASP.NET MVC based application that allows different levels of access depending on the user. The way it currently works is when a user accesses a page, a check is done against the database to determine the rights that user has. The view is then selected based on the level of access that user has. Some users see more data and have more functionality available to them than do others. Each page also makes a variety of ajax calls to display and update the data displayed on the page.
My question is what is the best way to ensure that a particular ajax call originated from the view and was not crafted manually to return or update data the user does not have access to? I would prefer not to have to go to the database to re-check every time an ajax call is made since that was already done when the user initially loaded the page.
Check out the Authorize Attribute, you can put it on an entire controller or just specific methods within your controller.
Examples:
[Authorize(Roles = "Administrator")]
public class AdminController : Controller
{
//your code here
}
or
public class AdminController : Controller
{
//Available to everyone
public ActionResult Index()
{
return View();
}
//Just available to users in the Administrator role.
[Authorize(Roles = "Administrator")]
public ActionResult AdminOnlyIndex()
{
return View();
}
}
Alternately, you can write a custom Authorize attribute to provide your own logic.
public class CustomAuthorizeAttribute : AuthorizeAttribute
{
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
IPrincipal user = httpContext.User;
var validRoles = Roles.Split(',');//Roles will be a parameter when you use the Attribute
List<String> userRoles = GetRolesFromDb(user);//This will be a call to your database to get the roles the user is in.
return validRoles.Intersect(userRoles).Any();
}
}
To use:
[CustomAuthorizeAttribute(Roles = "Admin,Superuser")]
public class AdminController : Controller {
}
If iyou are using a post use
[Authorize]
[ValidateAntiForgeryToken]
If iyou are using a get use
[Authorize]
You can also use this custom attribute
public class HttpAjaxRequestAttribute : ActionMethodSelectorAttribute
{
public override bool IsValidForRequest(ControllerContext controllerContext, System.Reflection.MethodInfo methodInfo)
{
if (!controllerContext.HttpContext.Request.IsAjaxRequest())
{
throw new Exception("This action " + methodInfo.Name + " can only be called via an Ajax request");
}
return true;
}
}
Then decorate your action as below
[Authorize]
[HttpAjaxRequest]
public ActionResult FillCity(int State)
{
//code here
}
Remember to "Mark/Tick" if this solve your problem.
It depends on what type of session mechanisam you are using . Are you using default membership provider ? If not than you can pass user's id and sessionid make sure that user session is valid and user has required permission to make that call .
Along with the Authorize attribute, you can also allow only Ajax requests using custom attributes as shown here.
Thanks

Resources