MVC custom groups for authorization - c#

I've done some searching but it doesn't look like a very commonly-asked or answered question. I need to implement a custom group authorization policy in an MVC application I am developing. It sort of follows the "classic" example:
Group
A user can create a group. A group exists as an object in a database with an Id, Name, and, among other things, a List of Users who belong to this group.
Role
A user can hold a role in many groups. For example, the creator of the group instantly becomes the administrator of the group. Different roles can access different things within the group.
I know it's very easy with pre-defined groups, but what about when I want to make the groups dynamic and each group be an object in the database?
A simple example of this in the real world would be groups on facebook, which have Admins, moderators, content-creators, etc. And only members can see them, edit them, or post to them.
Any ideas?

This is a very subjective design question and there is probably no single "right" answer.
I tend to use the aspnet Roles for application-level roles, like for Sysadmins and normal users and has to do with application-level permissions - ability to add new users to the application, ability to delete records, ability to edit records, etc.
It sounds to me more like this is something you want users to be able to do themselves without oversight.
Create a Groups table, and have a many to many relationship with a Users table that defines which groups users are a part of.
If you only want 1 admin per group, you could make the Group table have an AdminUserId column. Otherwise have a many-to-many relationship table, GroupAdmins (I'd go for this option as it allows extensibility).

You could inherit AuthorizeAttribute to create any security scheme you like. But since you said it is not about authorization I am not sure if that is the right approach.
The AuthorizeAttribute does 2 different things:
Checks if the current user can access the current controller/action.
Executes a handler to take an action when they are not authorized.
Both of these things can be customized by subclassing AuthorizeAttribute. It is unclear from your question what action is supposed to be taken if the user doesn't belong in a Group or Role.
In any case, the best option for cross-cutting concerns (which this appears to be) is to implement either IActionFilter or IAuthorizationFilter (which is implemented by AuthorizeAttribute).
NOTE: Microsoft hasn't implemented this feature very well (or at least they tend to favor ActionFilterAttribute in their marketing, which are attributes that have behavior) for those of us using dependency injection. See passive attributes for the best option if you happen to be using DI in your application. See a couple of examples here and here.

Related

Customize IdentityUser without Roles

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.

Permissions & Role patterns

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!

Is there a way i can give permissions based on the groups of active directory in my asp.net web application?

I am trying to achieve the following:
Authenticate users against Active directory.
If the user belongs to group "A" i want to limit user rights
If the user belongs to group "B" i want to have some other logic in my code.
I am able to achieve the first one in the above list.
I am using forms authentication in my web application(Intranet).I did some research and there are various suggestions to use Microsoft Active Directory Application Mode (ADAM) which i m completely unaware of.Is there a way i can achieve the above with out using ADAM? Say suppose get the group list into the code and based on that can i make a call if user belongs to some group and so on..
Is is that i am thinking only on group level which limits my options?
Or is there a way other than giving user access rights from group level
or am i completely not understanding the concept of Active directory authentication ?
Check this question, it is the same problem though differently described: Validate a username and password against Active Directory?
Either way ActiveDirectory is fully supported within C#, no need for additional systems (I am not aware what ADAM is either).
To check the groups of a username, use this code:
UserPrincipal p = UserPrincipal.FindByIdentity(
domainContext, IdentityType.SamAccountName, userName);
var groups = p.GetGroups();
foreach (GroupPrincipal g in groups) { /* do something */ }
If you are asking about a general architectural or best practices question, I would suggest looking at Claims Based Authentication. In particular Active Directory Federation Services (ADFS).
Basically, it seems that you need to control what a user can do at a more granular level than based only groups. Group membership can sometimes be very broad. For example, not every one in the "Users" might have the same right, not everyone in the "Sales" would have the same access. But then you don't want to create groups such as "Sales - Managers", "Sales - Employees", "Sales - Executives" etc. etc. This quickly becomes unwieldy. And no matter how much time you put into designing the perfect distribution of groups, in a few years it will all change because some subset of the sales managers will be allowed to do something, which other sales managers cannot.
To get around this problem, Claims based authentication is used. Rather than specifying rights at the group membership level you just check in your code whether a user has a certain "Claim". You can go nuts and create as many claims as makes sense for your application. You can have claims like "Can Change Birth Date", "Can Authorize Payment More Than $1000" etc. etc.
The claims are just attached to your user's identity, which is available via the thread's current principle.
Now, how does the user get assigned these "Claims" you ask? Well, if you are using ADFS, anyway you want. You can obviously do it based on AD group memberships. You can do it based on database look ups. You can do it on the time of the day or the month of the year if you so wish.
The point is, now your claim issuing and claim enforcement are completely independent and can change independently without affecting each other. Your code just says "Hey, this guy has a claim that lets him make more than $1000 payments, so I will let him do that. Why he has that claim, I don't know or care". Then your ADFS can issue claims based on any criteria that it sees fit. For example "If user is member of Managers group or has an entry in SuperUsers table in the security Database or is named 'Tim Timsky', he is allowed to spend more than $1000"
So to answer your question about "thinking only on group level which limits my options", it most certainly doesn't have to. If you are starting a new, green fields project, new tools like ADFS would give you a lot of options more easily.
But of course it comes with a caveat, which is that all abstraction has a cost of increased complexity. It is another part you are introducing into your system. You can decouple your application and introduce higher layers of abstraction and functionality. But whether or not that layer is worth introducing depends on how you plan to use the application. If you think that the application will never ever ever have to distinguish between a "Manager" and a "User" then, claims based authentication is an over kill. But if you feel that as time goes on, you will have different bits and pieces of functionality in your application that will need to be assigned to different users based on vague and ever changing rules, then claims based authentication will make your solution much neater.
As always, the net advantage of decoupling two parts depends on how often one changes independent of the other.

What is the recommended way to handle different user roles in a C# application?

I'm going to make a small application for a business that will be used locally for scanning, and storing documents in a database located on the local machine or on a machine located in the same LAN.
I could create a table called Users with username and password and according to the usertype ID show a form, or another form. But I'm more interested in the recommended approach by seasoned programmers.
Any advice?
Edit: I'm looking for something that will be secure enough, but also extensible enough.
If it's just a simple application, don't use a spaceship to cross the road.
Create the following DB schema:
Users : username and hashed password
Roles : RoleName, RoleID, RoleStrength(int)
RolesMembership : Rolemembership table that contains userid and roleid to allow for future multiple membership.
When setting up roles, give them a numeric weight. ie: Admins = 1000, Power-users = 500, guests = 10. This way, on your forms, you can say, if user level is 500 or above, set full view, otherwise, view only or no access.
Better yet, abstract it out with a security class with methods like IsPowerUser, or IsAdmin.
It's simple, readable and reusable.
Even I cannot consider myself "seasoned", I would give my answer since I'm facing the same problem in these weeks.
I would define a permission mask in order to identify allowed operations, associate it to role groups, and then associate users to the groups. More complete is the permission mask, more granularity is allowed in the group definition.
In this way there is one permission definition for multiple users, which is better than define the role using a per-user type basis, since the permission mask can be modified and extended.
More complex schemes could be possible, which could allow per-user permission overriding group permission, or hierarchy permission masks in order to define supervisor users able to manage group permissions.
The application of these models depends by the required scalability and by the number of users of the system.
I could create a table called Users
with username and password and
according to the usertype ID show a
form, or another form.
Sounds like a reasonable way to go to me. Just remember to hash the passwords.
I would also componentize the common controls in the forms, so you can reuse the common parts.
If you are using Visual Studio, I would just use the built in Membership providers. That would take care of your database and everything automatically. No need to reinvent the wheel.
Although orientated towards ASP.NET, I'd thoroughly recommend checking out this article: https://web.archive.org/web/20211020202857/http://www.4guysfromrolla.com/articles/120705-1.aspx
You can use the in-built Membership and Roles objects (even in a desktop application) to define your own schemas of privilege. Using this feature takes the hassle out of creating your own database entries for the Users (and Roles) tables, while also handling password hashing for you (leading to more secure applications).
Lastly, official MSDN articles you might want to read:
On "Membership": http://msdn.microsoft.com/en-us/library/yh26yfzy.aspx
On "Roles": http://msdn.microsoft.com/en-us/library/ff647401.aspx

ASP.NET: Permission/authentication architecture

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.

Categories

Resources