I'm looking to implement a membership system where there a several different levels of membership.
Something along the lines of:
Administrators
Bob
Organisations
Organisation members
Fred
Owners
Supporting users
Wilma
I'd like the Administrator to be able to add an organisation and from then on the person assigned to as the admin/owner of the organisation will be delegated the task of setting up membership/roles etc only within that sub-group (of course administrator would be able to override/change this as well)
So in this example Bob could add an organisation with fred as its administrator and fred could assign a new user say 'Thelma' as a member of his organisation.
From what I've seen this doesnt really seem to fit into the model of membership/roles that asp.net uses unless I'm thinking about it in the wrong way.
Is there a way to make this work with the inbuilt providers or would the best approach to be to ditch them and implement something custom?
You can keep the inbuilt providers and solve it with a relation between the organization and the membershipUser so you can say that a membershipUser "owns" an organization.
After that, you have a membershipUser Foreign Key on your organization that you can use to query the organizations that a user owns.
Shure you can implement a custom provider but it could take time to code and debug. I used the aproach I mention years ago and saved me from implementing the custom provider.
Related
Is it possible to manualy update user roles with Symfony2?
In my application, users are able to handle many companies. For each of them, they have different rĂ´les.
At login time, I'd like to give them the roles of their default company and when they switch of company, I'd like to remove the previous roles and add the ones of the new company.
Yes it is possible. But i wouldn't advise you to dynamically remove and add roles on an company switch as it could lead to an security issue. If you want to use the basic role system you could create roles prefixed by company name (this is an bad idea if you have many companies). Or upgrade your security context to use ACLs. Maybe the simplest solution is to create an user for each company with the same credentials (or no creadentials if you manage the user switch) and different roles.
As far as I can see you should consider developing an own role system that meets your multi company requirement.
I am starting a new ASP.Net MVC 3 app and I'm hoping to be able to use the built in Membership provider.
The issue I have is that my application can be used by various organizations and it is important that the information shown is only applicable to the organization the user is working for.
The no brainer approach would be to insist all users use their email addresses as their username so everyone is unique and can be associated with their respective organizations. The problem is, some users don't have email addresses so there is no reliable way of ensuring unique names and I don't want people to know the Usernames already in use by different organizations. (USernames should only be unique to the Organization, not the entire app)
Ideally, I would want the User to enter their organization name in one field, then their username in another (and then the password!)
So we could have Jane login from one organization.....
Organization Company1
Username Jane
Password ********
and then someone else also called Jane could login from a different organization..
Organization Company2
Username Jane
Password ********
So my question is, what is the best way of modifying the Membership system to allow for this extra field?
I'd go about writing a custom MembershipProvider to suite the requirement.
http://msdn.microsoft.com/en-us/library/f1kyba5e.aspx
The provider pattern used by membership is designed so that you can extend it. You can inherit from the default provider and from the default membership use class to add the fields you need. This saves you from having to write a provider from scratch. As #mare pointed out, there are potential pitfalls though.
I would overcome these by perhaps having a login form that prompts for organisation, username & password, but behind the scenes combine the org & username & use that as the internal username.
The built-in (default ASP.NET) membership provider does not provide a concept of an Organization/Company/Firm or Department. You will have create your own tables in the database for those with a foreign key to the aspnet_users table to be able to store that additional information (I wouldn't go changing the default aspnet_users table because it might make it incompatible with the current default provider or future ones). You will then need to use the default provider for the default functionality and create a Service class to support the extended functionality. I know, I have done it. It gets complicated and dirty, takes time but it's completely doable.
Most likely you will end up creating your own provider and that starts with the requirement to support Users in Companies. In case you thought that changing the default provider to support that wouldn't be necessary. The requirement about uniqueness within the company is another one you will have to implement.
I think there is a built in option in the membership. look into the APPLICATION field in table my_aspnet_users.
reference here:
http://msdn.microsoft.com/en-us/library/system.web.security.membership.applicationname.aspx
From what i have read from this paper
I understand that a role based access control system is one where users can be assigned to roles where roles specify permissions to perform operations on objects
But in asp.net we do not specify "Operations on objects", what i mean here is that how can we specify "All users in Role R can perform a delete on object O"
Where is the Object Part in ASP.Net
The security model is asp.net is pretty limited. In essence you only have control at the Role level. Which means that for any operation you have to test to see if the user is any of the roles that you want to allow that operation to be performed.
We took the path of defining our own model that gives much more granularity. Basically we define operations and assign those operations to various roles. This way we can test if they have a "delete account" right versus testing if they are in "Admin", "Account Admin", or any number of other roles. It's very similar to how Active Directory works. Further it allows us to reconfigure roles as needed.
There is a piece called Authorization Manager (AzMan) that ships with windows. It can work with your membership provider to provide operation level control. Some people have had success with it, but others have complained that it's difficult to get working. We used it about 5 years ago on a project and at that time it worked about 95% of the time. The other 5% it had communications issues with our AD controller.
Which leads us to your question: Is the built in ASP.Net membership provider a true role based access control system? No. It allows you to define Roles, not operations.
Check out rhino security if you need something more fine grained.
As suggested in previous posting, to achieve more granularity you would need to build up on the existing ASP.net membership and role providers. There are third party controls such as http://www.visualaccesscontrol.com that provide role based Module Access Security and Data Access Security as well. With Visual Access Controls you can add administrative functionalities to your ASP.net web application to dynamically restrict the users to the activities they are allowed to perform and the subset of data they are allowed to see based on their respective roles.
You are implementing the delete operation, so it is up to you to check if the logged in user has permission to delete the object. For example, you might create a role "CanDeleteOs". Then, your code would look like this:
if ( !Roles.IsUserInRole("CanDeleteOs") )
throw new Exception("User does not have permission to delete O's.");
I am faced with a security model problem when migrating my code to ASP.NET.
In the application:
There are multiple roles. (Role A, Role B etc)
There are multiple input/output fields. (Field A, Field B etc)
There are multiple permission levels controlling access to each field. (Read, Direct Edit, Edit With Approval, None)
Each role has its own permissions to fields. (Role A has Read Permission to Field A; Role B has Direct Edit permission to Field A etc)
Every role can be assigned to users and they are assigned by Geographic information. (User A is assigned to Role A for Continent: Europe - Country: Germany; User B is assigned to Role A for Continent: Europe - Country: France; User A is assigned to Role B for Continent: Europe - Country: France etc)
Users can have multiple roles
User identity is coming from Windows Authentication.
So my question/problem is: is it possible to represent this type of kind of multi-layered security model using ASP.NET internal membership/role providers?
If so, what should my starting point be? Creating only custom role provider with custom methods and fields be enough?
Even with the built in features of ASP.NET, the Membership Provider, and user controls, you will still have to write and manage the custom behaviors and interactions.
As example, the Membership Provider has easy ways for your to create roles and check for the existence of roles. But you will have to create the business specific dashboard call the features of the API that are appropriate to expose for your application. As example, at many of the organization that I have worked with role creation was a database only activity. User controls or site behaviors based on role were a code only activity. Managing which roles were assigned to users was a feature exposed via an admin page in the application. If a need for a new role was identified, it had to be first created by a DBA, then code/controls that were responsive to that role had to be written. After these items were deployed, application administrators could assign or remove roles to users.
To address you comment to your question, if you have Europe_Germany_RoleA, the Membership API provides methods for you to create that role, map it to a user, and to check for its existence on a particular user. like...
if(User.Roles.Contains("Europe_Germany_RoleA")) {
//your code here
}
but you would need to map that particular role to information or features specific to your application.
In retrospect, maybe what you really want to look at is the Profile Provider. Still part of the Membership set (Membership, Roles, Profiles), it is more designed to carry information. You could customize the Profile object to meet the needs of your application. For example, if you looked at this as Sectors (for lack of a better term) that could be loaded when the user logged in, you could do queries like...
if(Profile.Sectors.FirstOrDefault(sd=> sd.Name == "Europe_Germany_RoleA") != null) {
//bind to a grid, show a control, do something significant
}
and that might fit your problem better. Roles are truly only meant to act as flags (Does he have this role or not, then do something or dont), but the Profile object is designed to be customized to carry pertinent data for a user.
You can always extend it. The ASP.NET Membership model uses GUIDs as IDs for users and roles. You can add new tables that represent the added functionality and have them reference the original Membership tables.
Your problem is not in the role provider, or the membership system. This system is suitably flexible enough for your needs, and allows you to assign multiple roles to individual users. You can either use a SQL table to store these roles, or you can use Active Directory, AD is probably easier to manage the users with.
Your primary problem is going to be how you assign permissions to the fields and other objects. This means you can't just use standard drag and drop web forms, but will have to build your fields dynamically.
It's easy enough to check whether a user is in a role, this is a one-line call. But, your roles will likely not be hard coded, so you need a way to store fields and the roles associated with them, and a way to build the fields based on the users privileges.
EDIT:
Another option is to build the forms as if there was no security, then in your pre-render event go through and apply your security to each field, disabling and/or hiding fields you don't want the users to see. This may require relaying out the fields if you choose to hide them.
Okay,
I know I'm doing something wrong - but can't figure out a better way.
I am developing a website which is going to allow users to setup their own mini-websites.
Something like Ning.
Also, I have only 1 basic login and access to each mini website is provided (right now) via roles.
So the way I am doing this right now is:
Everytime a new mini website is created - say blah, I create 2 roles in my application.
blah_users and blah_admin
The user creating the mini website is given the role - blah_admin and every other user wanting to join this mini website (or network) is given the role - blah_user.
Anyone can view data from any website. However to add data, one must be a member of that mini site (must have the blah_user role assigned)
The problem that I am facing is that by doing a role based system, I'm having to do loads of stuff manually. Asp.Net 2 controls which work on the User.IsAunthenticated property are basically useless to me now because along with the IsAuthenticated property, I must also check if the user has the proper role.
I'm guessing there is a better way to architect the system but I am not sure how.
Any ideas?
This website is being developed in ASP.Net 2 on IIS 6.
Thanks a tonne!
I afraid standard roles-related stuff of ASP.NET is not what you need. You can try to change authentication module so it will:
Log you in with cookie.
Determine what roles does your visitor have. Perhaps you will use some special table that corresponds user and site.
Make custom principal with user roles enumerated and assign Identity and Principal to the current request.
I also don't think that making special roles for each site is good idea. When you would have hundred sites, you would also have two hundred roles. Pretty unmanageable, I afraid.
When we were solving similar task, we were just not using standard controls. We had single set of roles used on all sites. Membership of concrete user is determined according to current site and his relations to this site.
Addition: Another possibility to investigate is Application that exists in ASP.NET authentication system. Maybe it's possible to isolate each subsite into separate application?
Update: Method that works for our application.
Do not make a lot of cloned roles. Use only two: users and admin. If your sites are public then "users" role could be just global - user on one site doesn't differ from user on another site. If "users" and "everyone" are different roles, then of course "users" should also be bound to a site.
Use standard ASP.NET Membership users, but do not use standard role mechanism.
Make a mechanism for storing relation between site and user. It could be simple table that holds site id, user is and role.
What you have to override is IsInRole method. (Methods to be exact, i'll cover it later). This method is in IPrinciple interface, so you have to make your own principal object. It's quite simple.
Method IsInRole of this type should look take current site (from HttpRequest) look into the site-user table and get roles
Then you have to associate your principal with a request. Do it in PostAuthenticateRequest event.
There is also RoleProvider. Honestly I'm not sure when is it used, but it also have IsInRole method. We can override it in the same way. But other methods of this provider are harder. For example AddUsersToRoles. It accepts array of user names and roles, but to what context (site) should it be added? To current? Not sure, because I don't know when this method is called. So it requires some experiments. I see (Reflector helps) that RopePrincipal by itself uses RoleProvider to fetch list of roles, so maybe it's implement only RoleProvider, using standard principal. For our application this is not a case, so I can't say what problems could be hidden here.