I'm developing a fairly standard web application with Wicket, Spring & Hibernate. I've been using wicket-auth-roles and spring-security to authenticate users, and now want to add more fine grained authorizations to my applications.
In my applications users are members of groups, and groups have access to a subset of Hibernate objects that I use as wicket IModel objects. As such the decision whether or not a user may view certain page does not depend on the page path, but on the page model. (Most implementations of authorization for Wicket I've seen either grant access to a url or restrict it; they do not perform any checks on the model object.)
At present I've implemented this restriction as a custom IAuthorizationStrategy like this:
#Override
public boolean isActionAuthorized(final Component component, final Action action) {
if (!(component instanceof GenePage))
// We only check access to the GenePage for now
return true;
// Figure out from component what Gene the user is trying to view
Gene gene = (Gene) component.getDefaultModelObject();
User user = MySession.get().getUserModel().getObject();
return geneDAO.hasAccess(user, gene);
}
The problem with this implementation is that it fully composes the page and only in Page#onConfigure throws an uncaught UnauthorizedActionException. So far I've been unable to catch this exception, so it's logged as a problem even though it's part of the normal program flow. Fully composing the page also triggers a few actions in my page constructor and Page#onInitialize that I would only like to run if the user may actually view the Page.
Can anyone recommend me a better approach to restrict page access based on whether users have access to the Model object?
Solutions that tie in anywhere along the stack using Hibernate, Spring, Spring Security, Wicket and/or Wicket-Auth-Roles would be preferred. I know there are other wicket auth-integrations out there, so if you feel those could help in this instance, please let me know!
I feel that you expect a weird behaviour. This authz mechanism is designed to protect against Insecure Direct Object Reference Vulnerabilities. So you should not use it as a "part of the normal program flow". If you have kind of valid use cases then such kind of "hasAccess" failures should be handled somehow differently as valid behaviour, you should use some other mechanism, probably something custom built, as in most cases it will be very specific to your application.
Related
I am a relatively inexperienced programmer.
I have managed to build a web api which uses basic authentication as per the following:
https://weblog.west-wind.com/posts/2013/Apr/18/A-WebAPI-Basic-Authentication-Authorization-Filter which is working very nicely (forced over ssl obviously). Inside the OnAuthorizeUser i check the un/pw against an mssql database, via a call to an internal class called "DB" where all my database interaction occurs.
So all Controller methods are filtered by the Basic Authentication ("decorated" at the Controller level) however, access to certain Controller Methods also needs to be limited depending on the user - so there is a need to understand the user permissions. Based on my limited former ASP.NET experience I think I would have stored the relevant user details in a Session (or possibly cache) however I have so far steered clear of this based on wanting to stick to the concept of having a RESTful application etc
Rightly or wrongly, in playing around I realised I could use a private static (instance?) of my User class inside my internal DB class and populate it at the time of initial authorisation. I also added a public method (public User getThisUser()) to return the private User. From within my Controller methods I create an instance of DB and am able to check the values etc.
I was very worried that I would have issues with the "scope" of this "static" User, so to test, I created a Controller method to simply return the User information from DB.getThisUser(). In doing so I have found that I can log in as multiple different users (using different browsers concurrently for example) and each one consistently returns the correct user information (as logged in).
I'm still not entirely convinced this is "safe" however reading through the details of implementing something like ASP.NET Identity as a possible alternative makes my head spin and really seems like massive overkill in this case - I'm not using Entity Framework and after much searching I could not find a single example of NOT using an ORM (I need a solution to work with an existing DB).
Is this destined to fail? Do I go back to considering session or cache? Something else? I would really appreciate any feedback / advice on this from all of you who are more experienced than me. Thanks in advance for any help.
i think you're getting a bit confused.
an API is supposed to be stateless, meaning no session. Yes, you have a controller which translates into an endpoint.
You can hit an endpoint with all the information required to satisfy the request and this is it. Don't think of an API as an actual application where all requests are linked somehow. Instead, think of it at an application where each request is separate and can come from anywhere and any user.
How does the application know which user sent a request? Well, it doesn't unless you pass that information in.
You don't fire a request saying GetMeUserDetails. The api has no idea what you want. Instead you would say GetMeUserDetails for userId 12345. Now, since your request contains all the information required to satisfy the request, the API can now give you what you expect.
If some calls require authentication, you might use some sort of tokens to identify the user, but again, the information is passed in via the token.
You probably realize what static means and how it works. you are not going to see problems until you try to send two or more requests at the same time and then you'll realize that the first call now contains the details of the second request because well, static ...
I have been looking at BreezeJS and I want to try it but I searched a lot and still cannot understand how security is handled while using Breeze. Here is what I know:
According to a post on IdeaBlade forums (creators of BreezeJS), we only need a single Api Controller for all of our entities. The Api controller will contain one MetaData method, one Get method for each entity, one Save method, one Delete method. So this way we only need one EntityManager on client side configured with one service endpoint.
My questions:
My understanding of "single controller for all entities" is correct?
If my understanding is correct then how can we apply security on our controller? If I want a user with certain role to access only certain entities, I obviously cannot put an Authorize filter on my controller or method. May be I want a certain user to have read-only access while other users having read-write access on a certain entity. May be I only want to return aggregated data to user while restricting access to full details.
Please help. Thanks.
I've been doing a lot of tutorials for different MVC frameworks, and it seems very typical for Authorization to take place in the Controller. Why?
My thought is the Controller should only be used to orchestrate Model actions, to handle redirection and to handle error events. These are the things that are dependent on the specific request. Putting Authorization in the Controller seems like you're going to have to duplicate the authorization whenever you're using the same Model action in different Controller actions or different Controllers. If Auth is in the Model, you have consistent requirements for carrying out an action or state change on the data.
I've been googling and looking at other questions such as Should authorization be part of the model or controller? but I don't really see why it's the accepted convention.
Is there a specific reason I'm missing for putting Authorization in the controller over the model?
To sum up points in the comments:
Controllers are responsible for altering the state of the model layer and the current view. Nothing else.
Authorization belongs where an action is being carried out, if you're following a strict MVC pattern this would most likely be the model, and a Controller is certainly not responsible for authorizing the use of model actions.
Cookies should be treated like any other datastore: abstracted and used within the models, not directly by controllers.
Authentication and Authorization are separate issues, though they both usually go in the model layer, because they usually involve checks against values in datastores (such as cookies).
Is there a specific reason I'm missing for putting Authorization in the controller over the model?
Well, the most common reason I can imagine is laziness. I don't mean that morally, it's just far easier to flunge some authorization concept on top into a layer that is more close to the concrete request then to have differentiated access on the model layer. To have authorization with the models is a much higher design.
To add some more practical advice to the answer, I think you should analyse for each program where and for what you would want to introduce authorization. The needs for that can be (extremely) different.
Then only in the next step you should think about which design is most beneficial to introduce authorization and authentication to fulfill these needs.
In an MVC approach, you need to put security in a location where:
it cannot be circumvented
it can be configured, managed and updated easily
This applies - as a matter of fact - to any architecture / type of application.
Specifically, in MVC, imagine you put authorization in the view. For instance you decide to control who can approve a transaction by enabling / disabling a button. A user of your view will not be able to approve a transaction if he/she is not allowed. Imagine now that you expose your controller over an API rather than a view. The approve authorization check now needs to be reimplemented in the API layer.
This example shows you are better off moving authorization away from the view / the different end-points and into a common, central point - your controller.
Similarly, if you want to control access to large sets of data (e.g. medical records), you ideally want to put the authorization in the model. This is both for performance reasons and for security reasons: you'd rather have the controller handle less data and you should always strive to protect as close as possible to the source of the sensitive data.
Note that having authorization hooks / checks in the view, controller, and model at the same time may lead to an altogether enhanced experience. See authorization in the view as a "safety / usability" mechanism whereby a user is only presenetd with those relevant menus and widgets on screen based on their permissions. If they were malicious and knew their way around the UI to the controller, authorization there would still kick in.
Finally, generally speaking, you want to decouple non-functional requirements / logic from functional requirements / logic. Much like you do not implement logging in code but use a configurable framework (e.g. Log4J) or you rely on the container for authentication (e.g. HTTP BASIC in Apache Tomcat), you want to use an externalized authorization framework such as Claims-based authorization in the Microsofct MVC4 world, Spring Security in Java, CanCan in Ruby, or XACML, a standard part of the same body as SAML (OASIS) and which will let you apply authorization to any type of application and any layer.
Authorization as an entire process should be involved in both: Controller and Model layers.
But, all the logc (SQL queries, etc) should definitely happen in the model.
Controller is kind of an intermediate layer between the view (representation) and the Model.
But, you simply cannot throw away the Controller from this scheme, because Controller is responsible for handling Sessions and Cookies. Without these two things all your Authentication/Authorization logic is useless, because it is stateless by its nature. Sessions and Cookies bring state to it.
Moreover, as you correctly mentioned, Controller is responsible for redirects.
We have Implemented REST Based Architecture for our ASP.NET MVC3 App.
We are pondering over the architectural decision to implement a custom Authorization for the contracts we are exposing through our service.
e.g. Any valid authenticated user may get access to a particular Method implementation of the contract and might want to access some other user's info (getting a list of items from the data through Stored Proc) , we need to check after we get back this Items list that whether this authenticated User has proper permissions to access this. The permission check is based on a heavy business logic , hence Attribute based authorization might not be helpful in this scenario as only after getting back the data we might decide the access permission check.
Please advice how to implement this security model inside our REST Service.
Since attribute based auth seemingly won't work for you, then you'll need to determine if they fit the role you need:
HttpContext.Current.User.IsInRole()
After that your controller simply returns an HttpUnauthorizedResult which is an ActionResult.
So check your business logic, if they aren't authorized, then return HttpUnauthorizedResult and you are done.
http://msdn.microsoft.com/en-us/library/system.web.mvc.httpunauthorizedresult.httpunauthorizedresult(v=vs.98).aspx
I'm writing a web application with some ACL requirements: a user can make changes to some items, some items may be editable by several users, administrator can edit anything and a manager can edit everything within her organization etc.
I'm using the Play! framework, and by the looks of the Secure module, it seems that the place to put authorization concerns is in the Controllers. However, it seems to me that the authorization issues are part of the business logic, and therefore should be in the model. Furthermore, I'm starting to see duplicated logic in the controllers that I need to refactor out.
On the other hand, adding authorization to the model means that I'd have to have some way of getting the current user from within the model, which doesn't seem right. Alternatively, I could add a "current_user" parameter to every model method, but that seems even worse.
So what is the common practice? Can/should I put authorization code in the model, or keep it in the controller?
I think this is a grey area. One could argue that the user access is part of the mapping between the HTTP world and the Object-Oriented world. This is what the controller is intended for (hence the heavy use of statics), to transform the incoming request, ready to process the business rules on the domain model.
I would suggest that the controller logic is absolutely the right place for controlling the access to the model, especially as this is managed largely at an annotation level, and the authentication is abstracted off to a Security class.
Authorization should neither be part of controller or domain model.
Instead it should be in the service layer.
Controller should just act as dispatcher and delegate between HTTP and application service.
It's the application service where the orchestration takes place. This is the best place for placing authorization.
Suppose user A is authorized to access data from domain X, but not authorized for even a read access for data from domain Y. If authorization is placed in the controller, then user A gets authorized in the controller X, and via the service calls can access data from domain Y, which is not what we expected.
Since domain models communicate with each other on service layer, hence it best to place the authorization on the same level.
In most cases, the security should be one (or more) layer above the Model. Security is a domain on it's own, restricting access to a lower level layer.
I don't think the security should be done at the controller level.
In my opinion, this should look like that:
View -> Controller -> Security -> Model
The security layer could be a façade or a proxy over the model, protecting access, but be transparent to the controller.
However, if the views are to be modified depending on the access rights of the user, some checks might have to happen at the controller level (like setting the value of a CanEdit boolean property on the ViewModel).
I personally really like the way the Play! Secure module handles this (the tutorial is ever-helpful here). If you don't mind using the #Before annotation, it's pretty painless.
I am at this stage and intending to handle this in the following way:
No form validation by JS, instead via HTTPS ajax
An Ajax php class
Form data sent to a model as its data for concrete validation for
common type such as email and password (likely assoc array validation will be reused by other classes so this is definately a model area).
if no error a lookup in a User table for the credentials email /
password credentials passed to a Controller with the authentication
type such as login / signup / password reset
the controller then produces the required output view or sets user logged in session etc
This is based in Laravel but I have my own library as want it independent of laravel and just loosely based for this vital requirement.
The point being that the Model looks up the required credentials as data, then sends to the Controller as it does not care how it should be processed. I think this is the only way to make this area a definitive responsibility between each of the components.
From my personal experience with MVC frameworks I would say:
Model is an object that is representing database table it should be
pure and should not contain any additional logic.
Controller is the place where are made the decisions and other
custom logic, so the authorization should be in the controller. It
could be designed some hook that can check if the user is authorized
or not in all needed places so you wont have a code repetition DRY.
The best way to give permission to user if you are using a typical
REST architecture is to make a token , save it in the databse and on
client side and verify this token on every request. If you are using
web browser app you can use server-side sessions for authorization (
Its much more easier).
So my propose is to keep the authorization logic in the Controller.
I'll use Rails as an example. The authorization library, pundit, places authorization firmly within the "model" domain - this is enforced through their helper methods.
Suppose you have a ShoppingBag model. You might want to create a ShoppingBag
class ShoppingBagController
def create
authorize ShoppingBag.new, current_user
end
end
It works really well if you have a 1-1 mapping between a model and a controller. But what if you need a second controller on the same model? Now you're stuck!
class DiscountedShoppingBagController
def create
authorize ShoppingBag.new, current_user # does not work for us. we want a slightly different authorization, on the same model.
end
end
It's for that reason I dislike pundit, and CanCanCan. Authorization at the controller level, for me, is ideal. Doing so on the model level limits me too much, without any commensurate gain.