How can I write a "user can only access own profile page" type of security check in Play Framework? - security

I have a Play framework application that has a model like this:
A Company has one and only one User associated with it.
I have URLs like http://www.example.com/companies/1234, http://www.example.com/companies/1234/departments, http://www.example.com/companies/1234/departments/employees and so on. The numbers are the company id's, not the user id's.
I want that normal users (not admins) should only be able to access their own profile pages, not other people's profile pages. So a user associated with the company with id 1234 should not be able to access the URL http://www.example.com/companies/6789
I tried to accomplish this by overriding Secure.check() and comparing the request parameter "id" to the ID of the company associated with the logged in user. However, this obviously fails if the parameter is called anything else than "id".
Does anyone know how this could be accomplished?

You could have a simple #Before function, or if it is only on the view page that you want to apply the security, then you could have a simple bit of code at the beginning that checks the user's id (I assume from the session), and checks that they are allowed to access the page, by getting the User form the id in the session, and the Company from the id passed in, and checking against each other.
If security fails, then either return a badrequest instead of render, or call an action that shows a notAuthorised custom page.

You could make a SecureProfileController class that extends Controller, has a method that does the checkCompanyId-that-is-to-be-viewed against users companyId, and let the controllers that need that logic extend the SecureController.
If the method is an #Before function, like Codemwnci says, then it can intercept all the action methods in the inherited classes.
Alternatively you could have a look at Deadbolt, where you can setup roles for users and restrict access based on those roles: http://www.playframework.org/modules/deadbolt-1.0/home
Hope that helps :)

Related

symfony user login restrict to subsite

I've got a Symfony application that has multiple subsites.
Each site has it's own set of users, but all users are stored in the same table. All users are linked to 1 subsite, never 2 or more.
Allowing a user to use a single account on multiple sites is not an option given the use-case of this website.
I've got a RequestSubscriber which figures out what site is currently being requested (based on hostname) and pushes some extra information into the Request object attributes.
When a user attempts to login Symfony should only attempt to load users from the current subsite, not all users.
I've got a Doctrine Repository class that implements the loadUserByUsername method, but this only receives the requested username.
What would be the best way to adjust my UserProvider so only users from the current site are attempted to be loaded?
Can I configure the security in such a way additional information is passed?
One possible solution I've already got is to inject the RequestStack into the Repository class, and use that to add additional parameters to my query.
I would need to write a decorator for the Doctrine EntityManager to make sure it is injected when the Repository is requested, but that is not really a problem.
I don't really like this solution, so I'm looking for better alternatives (if any).

Symfony2 - handle HTTP/Entity user access restrictions

We have a little discussion in my team how to handle http restriction in our app.
In our app a user can create products. So we have routes like /products and /product/1/show to list and show products of a user. A user can not see products of another user. The app uses a REST endpoint to fetch the data. The API call looks like this /api/product/1/ to fetch a single product.
We have more routes/API endpoint for other kinds of entities.
The question is how to protect a route/API request against other users?
We have two solutions:
use the firewall and voters. The voter gets the current url /product/1/show and checks if given product is owned by the current logged in user.
use a voter without the firewall: http://symfony.com/doc/current/cookbook/security/voters_data_permission.html
use the role system: http://jmsyst.com/bundles/JMSSecurityExtraBundle/master/annotations
I prefer solution 1. because all information we need (who is the owner of the product) still exist. We only need to fetch the entity and do a check.
In solution 2. we have to spread the voter logic over several controllers.
Are there recommendations or experiences on this problem?
If i have to choose between those three it would be 1. But i suggest a different route. I assume that the digit 1 in /product/1/show stands for the user number? If that is the case i suggest that you make new routes without the numbers e.g. /my-products/show . The controller must then use the id of the currently logged in user.

Kentico ECommerceContext.CurrentShoppingCart for guest and authenticated user

Is it possible to have the same ECommerceContext.CurrentShoppingCart object returned irrespective of whether the user is logged into Kentico or not ? Currenty the object and consequently the contents of the of the shopping cart changes when the user logs in or out.
There is no out of the box functionality to override this behavior. I definitely wouldn't recommend to override UserInfo.IsPublic(). You'll have to create your own class and re-implement the CurrentShoppingCart property. Have a look in the source code or use some .NET reflector to see the actual implementation. As far as I can see there are no private members that you wouldn't be able to access so it should be piece of cake.
You can set or clear the CustomerID associated with the Cart on log in/log out respectively if you want to synchronise the state of the cart with the identity of whoever is/isn't authenticated.

how can I create a user session for a specific private resource group on the frontend?

I have a full website with two contexts for two different languages. The only public page is the landing page of both languages. The rest should be private/protected. This I have achieved with resource groups and limits on the anonymous users.
On the landing page all the menu entries that are protected should be seen by the anonymous user and if clicked a popup with two login-forms should be displayed. These login-form are from other sites and will return if the users has permission or not when they've entered their credentials. And as long as this session exists the user should be able to view all pages if the user was approved of course.
My guess as a non modx- or php- pro is that I should check if a session exists when the landing page is loaded (and all sub-pages). If no user is logged in all links will point to the popup. The user then logs in, sends info to the external server and is redirected to the private/protected landing page if successful. And this is what I can't find any info about, probably because I'm not entirely sure what to look for.
I need one snippet that checks if a valid session exists for the protected pages, if not display the logins.
The other code I would need is something that creates the session for the user if the external login was successful. Should this be a snippet or just a php document on the server. And how can I start a session for the protected pages?
You could do this in two different ways:
Make a user-system that is not connected to Modx. I find this the easies and I've done this several times before. You'll need to make a table for users with usernames and password, and make an object out of it, so you can use xpdo to do the queries. With this system up and running, it would be no problem to include a snippet in every template to make sure the user is indeed logged in. If not, just redirect him to the correct frontpage/landingpage. This will require some coding, but as I said, it works like a charm.
Download the snippet http://modx.com/extras/package/login (by Spittingred, a true legend), and look at the code. I haven't used this Extra before, but I am pretty sure it uses the same user-system as Modx, and therefor you should be able to achieve what you want. I can't give you any more help than "look at the source and figure out how Spittingred did it".
MODX Revolution checks if the user is logged in when trying to access a protected page, but if you would like to check it manually this snippet would do:
if (!$modx->user->hasSessionContext($modx->context->get('key'))) {
$modx->sendUnauthorizedPage(); // redirect to the informative page for non-logged users
}
If you need to check for the user being logged in and display a login popup if not, then using the output modifier with simple user id check may work:
[[+modx.user.id:if=`[[+modx.user.id]]`:eq:=`0`:then=`Not logged in`:else=`logged in`]]
When it goes to the session creation for the users authenticated from outside of MODX site, I would suggest to write a snippet which checks the status from the eternal page and logs user in. This way the session checking will be ommited but still, the functionality goal should be achieved.

Grails acegi plugin user recommendation

I'm about to add security to my Grails App, and I'd like to know from your experiences what's the best approach:
To add fields to the Person Domain class (such as phone, address, etc.)
To create an independent Domain class and map it one to one to the Person class
We are using a data model that has separate domain classes for Phone, Address and other related properties and associate them to the User domain using lazy loading. This accomplishes the accessibility that we needed while keeping the object size under control.
I suggest you use the http://grails.org/plugin/acegi plugin and add properties to the User class if they are directly related to the concept of an account and where it makes sense to have them loaded every time you access the user.
Remember that the user object is going to exist in the session for as long as a user is logged in and this means that it will become disconnected from the hibernate session (you can't just call save on it) and will also need to be serializable if you cluster the app.
I would not add phone number or address to my user object but I might add email address (you'll probably have to search users by email at some point) or a link to a profile picture (as you might be displaying this all over your site and not want to keep loading it).
I like to keep the user object small and avoid the temptation to add accessors for every table that contains a user id.

Resources