Symfony2 Role Confusion; how to NOT store them in the database? - symfony

I'm working on a Symfony app that will have some basic roles that can be assigned to users. Note, I'm not using the FOSUserBundle because I don't need more than half the features in it.
I have my users defined in the database, but I'd like to keep the role definitions out of the database. But several examples and other tutorials I've found keep the roles in the database, and use a ManyToMany relationship to assign them to users. This seems odd to me, since the actual use of the roles is hardcoded into the app.
For example, if I have a custom role ROLE_EDITOR, I have several routes and controllers that I may restrict to ROLE_EDITOR. Why would I "define" this role in the database? That means when developing my application and I add a new user role, I have to either write a script to programmatically insert a new role into the DB or do it manually, before the code is deployed that makes use of the role. I don't want admins to be able to add/edit/delete roles. It should be a design decision done programmatically.
In Drupal, there's a concept of Roles and Permissions. You define permissions in code and check against those, and then roles are defined in the database and are assigned permissions. But it seems that Symfony just has the concept of Roles.
I'm hoping someone can fill in a missing piece of information for me or something. How can I implement a system where the role assignments are done in the database, but the roles themselves are managed via code only?
My instinct is to just create a single entity that relates to User and has a string field for the ROLE_NAME. But this seems to go against the paradigm of having a real Role entity.

Related

ASP.NET Identity - How to manage claims?

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?

How to get the entities of an user usign ACL in Symfony

I'm trying to create a pretty simple application: I'm using FOS user bundle and ACL.
I have an entitie called Site, the users can create sites. When they do so I assign the use as owner of the site.
Now I'd like to have a page where I list the domains the users owns or he has read permissions. I've been searching but I couldn't find anything to solve it.
Why don't you set up a normal entity relation between user and site? Then you just do $user->getSites() or write a custom query and there you get all of this user's sites.
Then for security you can use voters, as stated in the comment above, or you can also just use a security annotation with an expression like #Security("user.getSites().contains(site)").

Dynamically add new roles to Symfony2 users

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.

Symfony2: Multi tenant roles in FosUserBundle

So I'm delevoping an application with multiple clients. Users could access more than one client with different roles in each case. For instance, User A has ROLE_XX for Client C1, but ROLE_YY for Client C2.
As far as I know, FosUserBundle stores the roles for a user in the column roles (default table fos_user), so this structure is not suitable for my needs.
I've read the documentation realated with roles management, but there is nothing related, so I guess it's a feature beyond the scope of FosUserBundle?.
So I was thinking about creating an addional table which relates them (client, user, role), but since I'm no FOS expert at all, I really don't know if this is the correct way to go. Or maybe I'm missing something. Any tip is appreciated!
Your requirements exceed what Symfony's security roles system provides. You will need to either maintain an ACL or encapsulate your access control logic in a custom security voter. I recently wrote about the latter approach here:
http://kriswallsmith.net/post/15994931191/symfony2-security-voters

ASP.NET Custom Role Provider - Additional Fields

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.

Resources