I was wondering (and I know it depends on the project and what not) what is the best/proper way of developing a custom access table where the admin can fine grain access to the site. Is it basically creating a bunch of roles dynamically and checking for those roles using the [Authorize] attribute? one problem I see with this (and I might be wrong since I just started learning the asp.net MVC architecture) is that in order to modify access I would have to change and recompile the whole site.
What I'm looking for is to present the admin with a set of actions and have them pick and choose what each user (and/or role, where role can be something different than the simplemembership roles if that would be better) can and can not do in the site (anywhere from accessing a particular action to making a change to the name property of entity1 for example)
Anyone has a suggestion of a tutorial or some sort of plugin or even a way I can achieve this?
You have misunderstood the authorization pattern: upon authentication a users id AND her assigned roles are to be attached to the thread context in an iprincipal. This principal is then checked against your software when you do security checks in your code.
There is therefore nothing that needs to get recompiled, unless you want to change which roles are allowed to do what. And then only for the places you have done programmatic checks. Access to url paths can be defined in the web.config.
Related
I´ve started development on a new ASP.NET MVC-App and I want to use ASP.NET Identity 2 for user-management. I want to get rid of the role-thing because I think this is absolutely not needed, especially if I think of the way, ASP.NET Identity handle roles behind the scenes: As claims. (please correct me if I´m wrong here)
I have two information regarding this issue: This official Microsoft-Documentation points out, that one only needs to implement the features needed, if the out-of-the-box-approach not meet all requirements. The other information is, that one have to derive the custom User from Microsoft.AspNet.Identity.EntityFramework.IdentityUser. But IdentityUser implements IdentityUser<string, IdentityUserLogin, IdentityUserRole, IdentityUserClaim>, IUser, IUser<string>
From my perspective, these information are not really compatible, because if I derive from this IdentityUser, I will take all this stuff into my CustomUser-Implementation whether I need it or not.
There is one more thing I wonder about: As I understood the Identity-Architecture, there are mainly two segments: Stores and Managers. The Manager is coupled to the Application and the Store, while the Store is coupled to the Manager and the Storage.
The storage-Interfaces are as flexible as I expected. Maybe I should start here - but I still don´t know, how to create a customUser as an entity, which derives from IdentityUser, without any reference to Roles. Can anyone tell me what my problem is?
The only stackoverflow question I found regarding this issue is
here. But I won´t believe, that this is an approach to follow.
Well, first and foremost, you can't truly get rid of roles. You can choose not to use them, but you're still going to have an AspNetRoles table. There is no way to get rid of that as the role functionality is baked in. Identity is extensible in that you customize and extend the role, but the relationship is not removable. The Microsoft documentation is not wrong, here, per se; it's just perhaps not entirely clear. You don't have to implement any role-based functionality if you don't want to use roles. In other words, you don't have to create functionality to manage roles, assign roles to users, or to verify that users are in particular roles. However, that doesn't mean that the core role functionality ceases to be present in Identity: only that you may simply choose not to use it.
Second, roles are actually kind of needed, at least if you have any desire to have permission-based access controls. If every logged in user can do everything any other logged in user can, then roles are probably not necessary, but if there's any functionality that's specific to a subset of users, then you need roles. Also, roles are not claims, though they function much as claims do. Identity has a separate concept of "claims", though.
I am working on an app (MUD game API) and have started looking in to Role based permissions. I've done some searching (including on SO) and have not quiet found an answer that matches my particular question.
So I've seen Claim Based security and Users/Group based security. Since this is a Mud, there could potentially be several hundred Commands that the user enters through telnet. I thought about creating an IRole interface, implementing it for each Role the API supports. 3rd party developers can implement their own roles as well. Then providing each Role with a collection of Commands that they are allowed to use at server start up. Handing a reference to that role to the users based on authentication permissions. That seems like it introduces to much tight coupling between the commands and roles.
Another option was to use an attribute at the class level for Types implementing ICommand. Again, this sounds like to much tight coupling.
What happens if a 3rd party developer decides they want to implement a Role in between User and Admin (like "QuestEditor" for a role allowed to edit/create quests). The developer would have to either edit the commands to add the required attribute, or build a collection in the constructor of the Role of all commands it can use. If a new command is introduced, then all roles have to be updated which is a pain.
I also thought about a relational implementation, where roles are related through a hierarchy. So I can specify that a Command is required to have a minimum role of "QuestEditor" but any role related up the hierarchy is allowed to use the command as well, but not any role related down the hierarchy. This allows Admins to use the command without editing their role, yet disallow StandardPlayer roles from using it. The issue is that every time a command is used, the hierarchy has to be crawled until the command finds the minimum role required. If QuestEditor is required, and the user is an admin, it can't infer that the user has the rights unless it crawls the hierarchy. I'm not sure that this is a big issue, but one down side.
I'm looking for input on what the best solution would be. I don't want to add update several hundred commands everytime a new role is created, nor do I want to update every role when a new command is created. I'd like something generic that can be used. If you could share your experience or any patterns that exist I'd appreciate it!
Thanks!
I have a website that's sort of a Craiglist type app.
In my Database, should I create a table called UserRoles, and assign the UserRoleID as a Foreign Key to every user created? 1 for Admin(Complete Priveledges), 2 for Moderator, 3 for Normal User, etc.
Also, inside of my ASP.Net application, say I have a UserControl. Inside of that user controls method, should I ask if User.ID = "1" make a button X.Visible = True?
Say if the currently logged in user is an Admin, make a little red X appear so the Admin can easily delete a listing, etc.
Or is there a more established way to do this?
You have the right general idea of a roles provider there. Role providers give a user some level (or perhaps multiple levels) and then in your code you can validate the current user's level when displaying content and evaluating inputs.
If you are using your own system then what you have described above is a perfectly reasonable approach to authentication and authorization. However, if you are using the ASP.NET built-in MemberShipProvider and RoleProvider (which you probably should be!) then there are many tutorials on getting those up and running. Personally, I would recommend using an existing provider over reinventing the wheel, but that's just me. You'll find that the built in providers are very comprehensive and simple to use.
Roughly speaking that is how you would do it.
You should probably take a look at .Net Membership as it already provides most of the leg work to get this done.
Also rather than writing user.RoleID == 1, all over the place consider writing some methods/properties to answer the question for you.
e.g.
if(myuser.IsAdmin)
{
....
}
or
if(myuser.HasRightsTo(Rights.DoX))
{
....
}
ASP.NET 2.0 introduced Membership. It makes maintaining users, roles, and profiles rather simple. I would recommend using the default SQL implementations.
I have a multi-user ASP.NET MVC application. The users are not supposed to see or do anything with each other's data.
One of my controller actions is the obligatory POST to /Edit to edit a record (e.g. a contact). Now here is my problem: What if somebody forges a simple POST to /Edit (which automatically model-binds to my contact class) and edits somebody else's information? As each record is identified by Id, all that would have to be done is make a fake POST with Id XXX and then record # XXX would be overwritten with whatever the attacker supplied. How can I stop this?
The only thing I thought of is fetching the original instance every time first from the DB, check that it is in fact within the user's scope of editable objects (the ones he'd usually see to edit) and only if that check passes to proceed with UpdateModel and committing the update changes.
Is there a better way?
Edit: This is not a Cross Site/CSRF attack. Another logged in user can do this.
Authorization for the view/page and authorization for the particular object are really two separate concepts. The best approach is problem to use an Authorize attribute in conjunction with the ASP.NET roles system to either grant or deny access to a given page. Once you have verified that the user has access to the page, then you can verify whether he has the permission he is requesting for the object on which he is requesting it. I use this approach in my application, and it works great. By using the Authorize filter first, it significantly improves performance since the actual object permission checking is a much heavier operation.
Also, I use a home brewed rules system to actually set and determine whether the user has access to the object. For example, in my system, administrators have full access to every object. (That's a rule.) The user who creates the objects has full access to the object (also specified by a rule). Additionally, a user's manager has full access to every thing his employees have access to (again specified by a rule.) My application then evaluates the object to see if any of the rules apply--starting with the lest complex rules first and then moving on to the more complex rules last. If any rule is positive, I discontinue rule evaluation and exit the function.
What you could do is exclude the ID in the model binding with this syntax:
public ActionResult Edit([Bind(Exclude="Id")] User userToEdit)
and then fetch the ID from the current logged in user instead, so that it is only the logged in user that can edit his own items and noone elses.
Loading the original record first and checking the owner sounds like a good approach to me. Alternatively you could add a hidden field containing the record ID and cryptrographically sign that field to make sure it can't be changed, or take the record ID, hash it using the user ID as a salt and check that (assuming you're using the membership providers you should use the provider unique ID, not the login name)
This question reminded me of an article that covers a similar issue (in light of URL manipulation attacks) that i had bookmarked. They deal with an authenticated user messing with the data of another user. You might find it useful:
link text
Edit: This link should be correct:
Prevent URL manipulation attacks
I am looking into building an authentication in my ASP.NET application with the following requirements.
A user has exactly one Role (i.e. Admin, SalesManager, Sales, ....)
A role has a set of permissions to CRUD access a subset of existing objects. I.e.
"Sales has CREAD, READ, WRITE permission on object type "Products" but not DELETE"
Somehow I like the permissions to be in a hierarchy with inheritance so that I for i.e. Admin don't need to specify all available objects.
The system must quickly be able to answer the question "Does user X have permission to do Y to object Z"
All database managed (MSSQL), implemented in C#/ASP.NET
I would like to get feedback on these requirements? Any ideas how to implement this using ASP.NET framework(as much as possible)? (However, I'm also interested to know how this can be achieved without Memberships)
I think what you need to do here is implement a set of permissions query methods in either your business objects or your controller. Examples: CanRead(), CanEdit(), CanDelete()
When the page renders, it needs to query the business object and determine the users authorized capabilities and enable or disable functionality based on this information. The business object can, in turn, use Roles or additional database queries to determine the active user's permissions.
I can't think of a way to declaratively define these permissions centrally. They need to be distributed into the implementation of the functions. If you want do improve the design, however, you could use dependency injection to insert authorizers into your business objects and thus keep the implementations separate.
There's some code that uses this model in Rocky Lhotka's book. The new version isn't in Google yet.
I think one of the best implementations that I think will fulfill your requirements is documented here. The only issue is that this hooks into NHibernate, but you can use this as a template to create your own permissions implementation and simply hook into your own event model rather than that of NHibernates Interceptors.
I am working on such a system myself and will blog it once I am happy with it.
The membership API provided since ASP.NET 2.0 should suit your requirements well. The only thing I'm afraid it doesn't directly support is hierarchical roles. However you can easily use normal role based security with another manually written hierarchical roles table to achieve the required things.
You can read on how to set up ASP.NET Membership here: http://msdn.microsoft.com/en-us/library/yh26yfzy.aspx
It allows you to group folders / pages etc into Groups / Users. I think you will find this sufficient!
The hiarchy is easily managed by extending the generated databases and procedures.
I would build the user/role relationship so users can have more than 1 role. I see a 1-1 relationship and I get nervous because I know that even if we don't see a need for it now, someone is someday going to want someone to be both a Sales user and a Customer Service user.
In our customer system, we use roles to layer on stuff like "delinquentCustomer." That way, the original permissions are still valid--as soon as they pay their bill. Worth considering this approach.