As Azman is now on its way out of support, we need to need to find a new way of configuring the access control for our applications.
Currently, in Azman, we have a list of "Operations", e.g. CanReadForm, CanEditForm. These operations can be mapped to one or more roles, so you can build up a set of "things a role can do". Users generally are assigned a single role and so they have a list of operations, or "things a user can do"
This worked well because on logging in, Azman would know what role they had, and pass a list of operations. The code could then be configured for example:
if(currentUser.HasOperation("CanEditForm"))
{
//allow editing of form
}
For ADFS I'm struggling to understand how we can have a list of operations that we can map to a role. Presumably you could have a list of claims, that could be like azman operations, but these only map to a user - right??? Can you map a list of claims to an Active Directory group for example? If you could then the Active Directory group would act as the "role" If so, would you need to create a new claim list for each AD group?
Can anyone offer any advice?
Azman doesn't really translate to claims-based authentication but here is my take:
Claims : Azman in the new claims-based world .
It works but it's not as "clean".
Related
I would like to implement claims based authorization in a Web Api project. I understand the idea of claims and can manually add a claim to a user and authorize a request based on it. However, I don't know how I should manage the claims, assign them to users and update them in future.
For example, say I have a Product entity and ProductCreate, ProductRead, ProductUpdate and ProductDelete claims for the CRUD operations on this entity. So I have a few questions:
I can store the claims in the DB, but what is the best way to add the "default" claims to a user on registration?
If I add new functionality to list the products which is only authorized if the user has the ProductList claim - new users would get this claim, but how would I add this claim to all existing users in the system?
Should there be a limit on the number of claims associated with a user? In a larger system with many entities, a user could end up with hundreds of claims
As I said, I know how to physically add the claims to the user etc., but it's more the bigger picture of the process of how you would manage claims and users in a real world example.
Thanks!
UPDATE
Thanks Brendan, I appreciate your help! I don't know if I'm misunderstanding something fundamental or if the answer is staring me in the face - either way, I'm not getting it.
So I have web api and would like to give granular access to the different controller methods. As the Admin, I want to be authorized on all calls so I should have all claims. Registered users should have read access to some methods and you as a moderator should have update and create access to some. My understanding is that these claims should be stored in a DB (SQL server in my case) somewhere and "assigned" to the user when they register. Using Asp.Net Identity, each user's claims would be stored in the AspNetUserClaims table, so when they login they get all their claims in the token by default. Simples!
What I am missing is the process of how you would handle the claims that should be assigned to a user when they register, what claims should a Moderator get etc. and how would you add / remove privileges. It doesn't seem right to me to have this in the code as adding a new claim in the system would require a rebuild and new deployment.
Also, if I add new functionality which requires new claims for different types of user, how would I make sure that the next time an existing user logs in they get the new claims as well as the ones they were assigned when the first registered.
I hope I am making sense, I may be mixing up some of the Role-based thinking with some of the Claims-based thinking which could be the source of my confusion. I just haven't seen any examples of how you would manage an application with many, many claims in the real world.
Thanks again!
That's exactly the same question and issue i'm running into. All I found is info on how to create a claim using the manager classes but nothing on where to manage these claims.
There can be different combination of access to give to a user and if my UI is a disconnected UI from my API, I don't think i would want the ui to manage these claims for me.
Other than mucking and creating a claims manager class with a claims table did you figure anything built in that can be used?
ASP.NET 4.5 / C# / SQL 2012
I already have a well defined database with a users table and a roles/permissions column. The column contains a delimited list of roles. I was hoping to use ASP.NET's built in features on the back-end so I can be lazy and use things like the and filter by role. I'd like to read my roles from the database and tell ASP these are the roles my user is in. Custom...but hopefully simple. Here is what I have so far:
//create an identity
GenericIdentity objIdentity = new GenericIdentity("Matt"); //this would actually be the username/email of the newly authenticated user
//get roles for user
string[] strRoles = { "ADW", "USR" }; //this will get read from the database on authentication
//add identity and roles to a principal
GenericPrincipal objPrincipal = new GenericPrincipal(objIdentity, strRoles);
//add to current user
HttpContext.Current.User = objPrincipal;
//add the principal to the current context of the current thread
Thread.CurrentPrincipal = objPrincipal; //not sure what this does, doesn't affect my results/tests
If I execute the code above and then run the following:
Response.Write(User.IsInRole("ADW"));
Response.Write(User.IsInRole("xxx"));
I get a True/False as expected. However, this doesn't persist to the next page. I did a fair amount of reading on custom membership/role providers, but I can't find this specific use case. Most talk about setting up a DB specifically for this task. I also saw mention of the newer Simple Membership, but couldn't get any love from that end either. I'm hoping there is a solution that involves what I'm already doing. I'd love to execute this code when the user authenticates, but be able to reference this user in other pages. I could always call to the database for every page. I'm assuming that would suck, and that's not what the built in provider does.
Thanks all.
You are approaching it from the wrong side. You don't have to create identity and principal manually, assuming you are not creating a custom authentication module.
In any other case, you only choose the persistence mechanism and the corresponding authentication module sets the identity/principal according to the persistence.
A commonly used persistence mechanism is Forms Authentication, where you issue forms cookies. The forms authentication module makes sure the identity/principal is set early in the pipeline and takes the cookie as the source of information.
If you want to replace the cookie by your custom cookie (in other words - replace forms authentication with your own) - you have to think of a way to persist the security info, to the cookie for example.
Note, however, that this is probably not necessary. The very same forms authentication can be used with any custom membership and role providers. This is because these two have different responsibilities - membersip provider is for actual authentication whereas forms authentication module is for persisting the information for consecutive requests.
Edit: to add a role for a user so that it is persisted in the user database:
Roles.AddUsersToRoles( ... );
But first, you'd have to create users in the user database:
Membership.CreateUser( ... );
Note that Roles and Membership are facades for actual role and membership providers. While default providers use the membership database, you can easily create custom providers that persist the information anywhere at the server side.
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.
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.