In Symfony2, how to handle dynamic access / rights? - symfony

I'm trying to find the best way to handle a "complex" security / privacy system using Symfony2.
I read a lot of documentation about the ROLES and the ACLs but I'm looking for something different.
I need the rights to be calculated based on the properties of the objects.
In my case, I have a User object and multiple other objects (Project, Task, Label, and more...).
I need to check if a User can read or write any kind of object without storing the rights in the database (like the ACL system is doing). The rights should be "calculated" based on the relation between the User and a given object.
For example, the User(1) can write on the Task(2) because he is a member of the Project(3) and the Task(2) is in the Project(3).
The Roles of the security service can't handle that. The ACL could handle it but I don't want to store the rights in my database because I know that they are going to change a lot during the life of the product.
Is there a known good practice for that kind of needs or should I write my own system?
Thanks.

"that they are going to change a lot during the life of the product" -> IMO, storing in database is the best, and ACLs are a good way to do that.
In your example above, ACLs would be great to manage rights between User and Projects, and rights on Tasks are depending on this Project Rights.
These rights would be accessible in your controllers and you views with respectively isGranted() and is_granted() if you implement your own aclVoter: http://symfony.com/doc/current/cookbook/security/voters.html

Related

How to handle complex authorization in an ASP.NET MVC 4 / EF application?

The ability to add, update, and delete various entities in my application is often determined by the relationships defined between the various users involved. Here is an example:
A basic user or his supervisor can create tasks associated to the user, but only his supervisor can lock down the task so that the basic user will not longer be able to add/update/delete it. Until locked down, both individuals will be able to update the task.
What is the best approach to implement these kind of complex and advanced rules that deal with the relationship of users and the state of the entities (new, existing), as well as other things like maybe a user-defined status associated to the entity?
Thanks
What is the best approach to implement these kind of complex and advanced rules that deal with the relationship of users and the state of the entities (new, existing), as well as other things like maybe a user-defined status associated to the entity?
You want to use an authorization standard, namely XACML, the eXtensible Access Control Markup Language. XACML is:
a standard developed by OASIS, just like SAML is
a standard that focuses on fine-grained access control: access control that takes into account user information, resource information, state, and contextual information
a standard that implements the attribute-based access control (ABAC) model: the user information, resource data, and state can all be seen as attributes
a standard that uses policies and rules to structure the attributes and grant / deny access: XACML is policy-based
a standard that can be applied across multiple layers e.g. across the presntation tier, the data tier, the business tier of an MVC application
a standard that can be applied to multiple technologies and languages e.g. C# (MVC4 and more), Java, Python...
With XACML, you can easily implement relationships e.g.: an employee can approve a transaction if and only if the transaction amount < employee approval limit AND the transaction is not locked.
Where to go from here?
Check out NIST's page on ABAC.
Check out OASIS XACML's page and spec
Check out existing implementations (open-source and vendor such as the one I work for, Axiomatics.)
At a bank I worked for, we had a loan management system that allowed the entire bank hierarchy to see loans in their reporting structure. For instance, a Market exec could see the loan portfolio of all of his/her reports at once. Additionally, s/he had the ability to select from a list of all reports' (direct or indirect) names to view the portfolio of that employee.
It was complex, but we had to maintain an HR database of the reporting structure. Once we had that, we built user functions (could be done as stored procs, too, but user functions worked well in our LINQ to SQL backend) that allowed us to check whether user x supervises user y.
So, in your example, as long as you know who owns the task, and have access to a method that can be used to determine if the task owner reports to the currently-logged-in user, you should be able to easily enable/disable the "lock" button on the page.
The legwork lies in creating that reporting structure DB, and keeping it up to date!

Storing a staff hierarchy in active directory e.g. staff > manager relationships

Is it possible to store user (and therefore use in e.g. asp.net) a staff hierarchy in active directory e.g. staff > manager relationships.
My active directory install is relatively flexible, so I could add additional information.
It's certainly possible to extend the AD schema to support what you want to do, but I would seriously consider why you want to do it, and how many changes you might make down the road (not to mention how unhappy your system administrator might be after these changes).
The presence of AD is not a prerequisite to using built-in Asp.net authentication methods (although it makes integrated authentication much easier). If this kind of data is application specific, I would recommend looking into maintaining the data in an application-specific database. In doing so, you could pull the current user's FQDN from the HttpContext.Current.User, and key on the Name property of the associated Identity. For example:
HttpContext.Current.User.Identity.Name
From that point, you simply create a UserProfile table with associated organizational structures (i.e. a column for ReportsTo that acts as a reference to another UserProfile.

In SAAS architecture, how do I handle db schema and MVC user logins for multi-tenants

Our requirement is something like this.
We are building a multi-tenant website in ASP.NET MVC, and each customer should be able to create their own users as per predefined user roles.
We are thinking about to create a schema for few tables which would be common for customers. So customer can login to system according to their schema logins and we need not to alter any queries to serve all of them.
We are referring http://msdn.microsoft.com/en-us/library/aa479086.aspx Shared Database, Separate Schemas.
Can someone suggest on following
1. After creating schema how to authorize user against a particular schema
2. Is this possible that without any changes in queries db can serve multi-tenants
Thanks in advance
Anil
After much research, I can say that, although it takes more development up front and more checks along the way, shared database and shared schema is the way to go. It puts a little bit of limits on how easily you can cater to a client's specific needs, but from my point of view SAAS isn't about catering to a single client's weird needs. It's about catering to the majority of clients. Not that it's a SAAS but take iPhone as an example. It was built to cater to the masses. Rather than focusing on doing everything it's built to be one-size fits all just by its simplicity. This doesn't help your case when it comes to authoriztion but it'll save you dev hours in the long run.
If you are asking this in the context of SQL Server authentication/authorization mechanism, i can asnwer this question with saying that every user has a default schema which helps query engine to find out required object in the database.
SQL Query Engine will look at the user's default schema first to find the required object (table). If it founds the object in user's schema then use it, otherwise goes to system default schema (dbo) to find it.
Check this article's How to Refer to Objects section to find out how it works. The article also has some information about security concepts related to schemas.

To use or not to use the user module

We are currently transitioning our website to Drupal 6.x from a non Drupal source. One of the first issues we need to deal with is that of authentication. We have a central database where we keep member information. We will create a module to authenticate against this database however a question of whether or not to create users in the drupal is needed.
I'm worried that if we do not add user to the user tables and have our module keep sync that with the other database, then we will not be able to take advantage of other modules that may use the user module
My colleague on the other hand believes that this is not an issue we can add all necessary attributes to the global $user at authentication with our module.
Is there a standard way of dealing with this problem?
Thanks!
David
Look at the LDAP_integration module, they do something similar. When logging in and a local user cannot be loaded, a user is searched for in another application and when user&pass are equal, the user is copied in the Drupal usertable.
If you want any Drupal functionality (read: core and modules) to be associated with that user account, then you will need to use that user table.
This is especially true for anything node-related, so if you want people to be able to create nodes with referenced data you will need it. uids are stored in the nodes table in order to show who authored the node. Storing a uid in the nodes table with a something that doesn't exist as a relational key to somewhere else will only return an empty object. For instance, if a person wants to see the author of X node they will get an empty user object. Keep it. There's no sense in working harder just to remove it. Besides, you can store as little or as much as you want in the user object for each account.
I'd also suggest looking at the LDAP module. I was able to use it as a jumping in point to interface with a custom WSAPI authentication method for an external database that we have at my company.
Do you need to have both sites running in parallel? If not, then you don't need to sync the user tables. A conversion will be enough then.

Database Authentication for Intranet Applications

I am looking for a best practice for End to End Authentication for internal Web Applications to the Database layer.
The most common scenario I have seen is to use a single SQL account with the permissions set to what is required by the application. This account is used by all application calls. Then when people require access over the database via query tools or such a separate Group is created with the query access and people are given access to that group.
The other scenario I have seen is to use complete Windows Authentication End to End. So the users themselves are added to groups which have all the permissions set so the user is able to update and change outside the parameters of the application. This normally involves securing people down to the appropriate stored procedures so they aren't updating the tables directly.
The first scenario seems relatively easily to maintain but raises concerns if there is a security hole in the application then the whole database is compromised.
The second scenario seems more secure but has the opposite concern of having to much business logic in stored procedures on the database. This seems to limit the use of the some really cool technologies like Nhibernate and LINQ. However in this day and age where people can use data in so many different ways we don't foresee e.g. mash-ups etc is this the best approach.
Dale - That's it exactly. If you want to provide access to the underlying data store to those users then do it via services. And in my experience, it is those experienced computer users coming out of Uni/College that damage things the most. As the saying goes, they know just enough to be dangerous.
If they want to automate part of their job, and they can display they have the requisite knowledge, then go ahead, grant their domain account access to the backend. That way anything they do via their little VBA automation is tied to their account and you know exactly who to go look at when the data gets hosed.
My basic point is that the database is the proverbial holy grail of the application. You want as few fingers in that particular pie as possible.
As a consultant, whenever I hear that someone has allowed normal users into the database, my eyes light up because I know it's going to end up being a big paycheck for me when I get called to fix it.
Personally, I don't want normal end users in the database. For an intranet application (especially one which resides on a Domain) I would provide a single account for application access to the database which only has those rights which are needed for the application to function.
Access to the application would then be controlled via the user's domain account (turn off anonymous access in IIS, etc.).
IF a user needs, and can justify, direct access to the database, then their domain account would be given access to the database, and they can log into the DBMS using the appropriate tools.
I've been responsible for developing several internal web applications over the past year.
Our solution was using Windows Authentication (Active Directory or LDAP).
Our purpose was merely to allow a simple login using an existing company ID/password. We also wanted to make sure that the existing department would still be responsible for verifying and managing access permissions.
While I can't answer the argument concerning Nhibernate or LINQ, unless you have a specific killer feature these things can implement, Active Directory or LDAP are simple enough to implement and maintain that it's worth trying.
I agree with Stephen Wrighton. Domain security is the way to go. If you would like to use mashups and what-not, you can expose parts of the database via a machine-readable RESTful interface. SubSonic has one built in.
Stephen - Keeping normal end users out of the database is nice but I am wondering if in this day and age with so many experienced computer users coming out of University / College if this the right path. If someone wants to automate part of their job which includes a VBA update to a database which I allow them to do via the normal application are we losing gains by restricting their access in this way.
I guess the other path implied here is you could open up the Application via services and then secure those services via groups and still keep the users separated from the database.
Then via delegation you can allow departments to control access to their own accounts via the groups as per Jonathan's post.

Resources