I am trying to use a custom permission based authentication where i have the users-Roles-Permissions tables defined. I need to restrict access based on the permissions - CustomerEdit,CustomerView,CustomerDelete etc.
I have already read about role based access using custom attributes
The problem I see with this is I have to decorate each controller action with the attribute.
Is there another method to do this?
Could look at Fluent Security http://www.fluentsecurity.net/getting-started It is configurable in code
Related
I've been reading up on how to implement Role Based Access Control (RBAC), with the intention to implement it within a Spring based microservice API.
It appears that when implementing RBAC, you should check permissions, rather than roles. The following posts seem to agree on this point:
Role Based Access Control (RBAC) cares about permission or roles?
https://hackernoon.com/role-based-access-control-design-for-micro-services-dg1233079
https://softwareengineering.stackexchange.com/questions/299729/role-vs-permission-based-access-control
https://heap.io/blog/engineering/structure-permissions-saas-app
The selected answer in the 1st link above says "Spring security and many other prominent access control mechanisms propagate this security anti-pattern" [of checking roles instead of permissions]. Although there are only 3 upvotes so I'm not sure if this statement would be widely accepted.
So I'd like to know, how best to approach RBAC within a Spring based API, so that I check permissions rather than roles.
Take the following scenario:
A user in my app can have the Role PLAN_MANAGER, which may have the permissions VIEW_PLAN, CREATE_PLAN, EDIT_PLAN, DELETE_PLAN. Within our app, we would allow some users to change permissions associated with roles, so for example, an admin user may edit the permissions on the PLAN_MANAGER role to remove the DELETE_PLAN permission.
Within spring, I would have a deletePlan method. I want to know how to allow users to execute this method only if they have the DELETE_PLAN permission. It looks like PreAuthorize checks are the standard way to check if a user has access to a method in spring, however it seems that hasRole, rather than hasPermision, is most commonly used with the PreAuthorize annotation.
I can't find examples/tutorials of using a PreAuthorize check that only references the permission, instead it seems to be more common to reference the role (however, the following example shows using both role and permission check https://www.dontpanicblog.co.uk/2012/08/19/protecting-service-methods-with-spring-security-annotations/).
Most examples I find seem to just do something like:
#PreAuthorize("hasRole('PLAN_MANAGER'))
But if I use that approach, and an admin user removes the DELETE_PLAN permission from the PLAN_MANAGER role, then we would incorrectly allow the user to execute deletePlan.
So should I instead be using something like:
#PreAuthorize("hasPermission('DELETE_PLAN'))
So that even if the permissions associated with roles change, this check will always be valid for this particular method, and the code won't need to be changed. So new roles could be added to the app with the DELETE_PLAN permission, and we wouldn't need to add new explicit role checks in the code for those new roles.
Thanks.
Update
I've found what looks to be someone else trying to do the same thing as me here https://stackoverflow.com/a/60251931, and it looks like he's put together a repo at https://github.com/savantly-net/spring-role-permissions
There's an example shown in the readme, pasted below, which looks to be exactly what I want to achieve - so it seems I need to use hasAuthority rather than hasRole or hasPermission (hasPermission requires an object target argument, which I don't want to specify, as that would seem to go beyond RBAC into ABAC, I simply want to specify a permission/privilege, which is why hasAuthority looks appropriate):
#PreAuthorize("hasAuthority('CREATE')")
#RequestMapping("/create")
public String create() {...}
(also found an older post detailing another custom approach which looks to allow for checks on privilege/permission rather than role - https://stackoverflow.com/a/22612076/14147607)
I want to implement Role based authorization in mvc 5, i am using asp.net identity 2.0 for user authentication.
Please suggest how to implement this by using authorize attribute or any other possible way.
I also want to store user rights after login and do not want to fetch again and again from database while authorizing on controller action. (Don't want to use Session).
[![Role Permissions stored in DB][1]][1]
I probably am not understanding the depth of your question, but I see that your Authorize statement is slightly incorrect.
Try [Authorize(Roles="admin")]
It uses Microsoft.AspNetCore.Authorization;
There's also a Policy Based Authorization. [Authorize(Policy = "Seniors")]
I also found an answer here that may be of interest to you, it speaks of customizing Role Permissions:create custom authorize attribute
The trick will be to assign the User a role, then use the 'Authorize' on the action methods or on the page, or even in the view HTML by testing if the user IsInRole like:
#if(User.IsInRole"admin"){ Add HTML Here }
And if you do use 'Roles', remember that you can add multiple roles to the 'Authorize' tag something like [Authorize(Roles="admin, staff, user")] etc.
I'm using Spring Security which works great to make sure that a user has a certain role before accessing a resource. But now I need to verify something a little different:
`/product/edit/{productId}`
What is the best way to verify that the logged in user "owns" productId? My business mappings handle the relationship (a user has a list of products). I need to verify this product belongs to the user and hence, they can edit it.
I know how to gain access to productId and the logged in user in both the controller and an interceptor. I don't believe this logic belongs in the controller at all. The interceptor seems better but I wondered if Spring Security had an "accepted" way of handling this situation.
Yes, in Spring you can implement this by implementing Access Control Lists. ACL declaration specifies permissions for individual objects per user. Once you have everything setup like acl entries in your database and logic, you can use SpEL and #PostFilter annotation to control the list of objects returned to a user.
Spring Security Documentation
Related:
I'm using a global authorization filter on my MVC app to ensure that users are authenticated before they access my app, but I'd like to take it one step further. I have three AD groups that the users can potenially be a member of and I'd like the global filter to check for one of those three groups as well.
I do not want to add three authorize attributes to every controller in my application. How would I write the global filter to include role authorization?
Thanks!
You can configure a Role-Based membership provider , which essentially will call an Authorize service with your custom logic and you can mention the roles in a config file you need to check against. This entire logic can be encapsulated inside an attribute , decorated over the Routes.
I am using the default membership authorization that is created when you start a new project in VS for MVC 3. When a user is registered (either if I do it for them in the Administration page or if they register themselves through the Register page created in the application), there is an email field for instance. But where is this stored? Shouldn't I be able to access that e-mail somehow? I can't find it in the User object...
Also, is it possible to add more fields when they register, and to access those as well? For instance address, phone number, etc?
1. Getting the e-mail
You can access the property from the current user by using the Membership object.
Membership.GetUser().Email
2. Extra Fields
The best way to add more fields to the register process is to make another model called UserDetail or something. And make a relationship between User and UserDetail.
Or you throw away the default membership authorization and make a custom one. Here are some handy links:
http://msdn.microsoft.com/en-us/library/f1kyba5e.aspx
http://www.asp.net/learn/videos/video-189.aspx
http://www.15seconds.com/issue/050216.htm
http://davidhayden.com/blog/dave/archive/2007/10/11/CreateCustomMembershipProviderASPNETWebsiteSecurity.aspx
For the extra user fields you can use the ASP.NET profile provider.
here is a good article about how to implement it:
http://ashuthinks.wordpress.com/2012/01/08/asp-net-mvc-profile-provider/