I'm writing a multiuser application in which requests for a given resource (say, /people/4) will return differing levels of detail depending on the user performing the request (for example, user 4 or a support representative would see the entire resource, while other users would not see certain fields such as the user's e-mail address).
Spring HATEOAS has thorough support for building links, but the main ResourceAssember interface only provides a single adapter method that takes a domain object and returns a resource object, with no provision for additional parameters (such as the current Spring Security user), and neither ResourceSupport nor Resource<T> provides facilities for filtering the fields returned.
The approach I'm currently leaning toward is having the implementation of toResource for ResourceAssembler<Customer, CustomerResource> manually dig out the current Spring Security credentials and apply filtering at that point, essentially hand-writing a multi-stage copy constructor that will add public fields, then for-friends fields, then private fields to the resource object.
Is there a more integrated, especially declarative, way to handle the task, or is this the best solution available now? Will this approach integrate with the Spring Data REST controller, or will I have to reimplement paging and so forth if I want to handle the assembly myself?
Related
I do not understand Java annotations with retention policy as RUNTIME that well. What I'm trying to do is create an annotation named #Authorize and use it on methods which needs user authorization in order to perform some action( the user is already authenticated at this point).
eg. I have an order service with a getOrder() method. I want only the user who created this order to access it.
`
public void getOrder(User user) {
//current code does something like this
if(order.getCreatedBy().equals(user)) {
//then proceed.
}
}
`
I do not want to mix this logic with business logic. Instead, I'm looking to have something like this-
`
#Authorize
public void getOrder(User user) {
//business logic
}
`
There are several methods but not all of them would need such authorization. Could someone please explain me how can I fit the pieces together here?
What I don't understand at this point is that how AnnotationProcessor would help me here since it does its magic at compile time. As far as I understand, it will help me generate some code at compile time but I have no clue how to use that generated code. I went through numerous examples on AnnotationProcessors but I'm still missing something.
These links helped me a bit to understand annotation processing so far-
http://hannesdorfmann.com/annotation-processing/annotationprocessing101
https://equaleyes.com/blog/2017/09/04/annotation-processing/
Even if I go with reflections, where should I place the reflection logic? and is it counter productive of what I'm trying to achieve?
At this point, I'm open to other solutions as well which do not involve annotations but will help me separating out business logic with such resource specific authorization.
To implement authorization controls on methods in Java, I highly recommend Spring Security with an eXtensible Access Control Markup Language (XACML) implementation that has a Spring Security API.
Spring Security
Spring Security provides two main means to protect access to methods:
Preauthorization: this allows for certain conditions/constraints to
be checked before the execution of the method is allowed. Failure to
verify these conditions will result in the failure to call the
method.
Postauthorization: this allows for certain conditions/constraints to
be checked after the method returns. This is used less often that
preauthorization check, but can be used to provide extra security
around complex interconnected business tier methods, especially
around constraints related to the object returned by the method.
Say for example, that one of the access control rule is that the user has have the ROLE_ADMIN authority before being able to invoke a method getEvents(). The way to do that within the Spring Security framework would be to use the PreAuthorize annotation as below:
public interface Sample { ...
#PostAuthorize("hasRole('ROLE_ADMIN')")
Event getEvent(); }
In essence Spring Security uses a runtime Aspect Oriented Programming (AOP) pointcut to execute before an advice on the method and throw an o.s.s.access.AccessDeniedException if the security constraints specified are not met.
More can be found about Spring Security's Method Level Security in section 27.3 of this documentation.
eXtensible Access Control Markup Language (XACML) - a policy language for ABAC
Spring Security does a great job of implementing access control with its expression based access control, but attribute based access control (ABAC) allows more fine grained control of access and is recommended by the National Institute of Standards and Technology.
To address the limitations of Role Based Access Control (RBAC), NIST came up with a new model called ABAC (Attribute Based Access Control). In ABAC, you can now use more metadata / parameters. You can for instance consider:
a user's identity, role, job title, location, department, date of
birth...
a resource's type, location, owner, value, department...
contextual information e.g. time of day the action the user is
attempting on the resource
All these are called attributes. Attributes are the foundation of ABAC, hence the name. You can assemble these attributes into policies. Policies are a bit like the secret sauce of ABAC. Policies can grant and deny access. For instance:
An employee can view a record if the employee and the record are in the same region
Deny access to reading records between 5pm and 8am.
Policies can be used to express advanced scenarios e.g.
segregation of duty
time-based constraints (see above)
relationship-based access control (see above)
delegation rules delegate Bob access to Alice's document.
There are 2 main syntaxes available to write policies:
the Abbreviated Language for Authorization (ALFA), which is based on XACML
the eXtensible Access Control Markup Language (XACML)
ABAC also comes with an architecture to define how the policies will get evaluated and enforced.
The architecture contains the following components:
the Policy Enforcement Point (PEP): this is the component that
secures the API / application you want to protect. The PEP intercepts
the flow, analyzes it, and send an authorization request to the PDP
(see below). It then receives a decision (Permit/Deny) which it
enforces.
the Policy Decision Point (PDP) receives an authorization request
(e.g. can Alice view record #123?) and evaluates it against the set
of policies it has been configured with. It eventually reaches a
decision which it sends back to the PEP. During the evaluation
process, the PDP may need additional metadata e.g. a user's job
title. To that effect, it can turn to policy information points (PIP)
the Policy Information Point (PIP) is the interface between the PDP
and underlying data sources e.g. an LDAP, a database, a REST service
which contain metadata about users, resources, or other. You can use
PIPs to retrieve information the PDP may need at runtime e.g. a risk
score, a record’s location, or other.
Implementations of XACML
Full disclosure - I am on the XACML Technical Committee and work for Axiomatics, a provider of dynamic authorization that implements XACML.
Axiomatics provides a Spring Security SDK for their Axiomatics Policy Server and it provides four expressions that can be used to query the PDP as a part of protecting a method invocation
xacmlDecisionPreAuthz, called with #PreAuthorize
xacmlDecisionPostAuthz, called with #PostAuthorize
xacmlDecisionPreFilter, called with #PostFilter
xacmlDecisionPostFilter, called with #PreFilter
The exact signatures for these methods are as follows:
xacmlDecisionPreAuthz(Collection<String> attributeCats,
Collection<String> attributeTypes, Collection<String> attributeIds,
ArrayList<Object> attributeValues)
xacmlDecisionPostAuthz(Collection<String> attributeCats,
Collection<String> attributeTypes, Collection<String> attributeIds,
ArrayList<Object> attributeValues)
xacmlDecisionPreFilter(Collection<String> attributeCats, Collection<String>
attributeTypes, Collection<String> attributeIds, ArrayList<Object>
attributeValues)
xacmlDecisionPostFilter (Collection<String>
attributeCats, Collection<String> attributeTypes, Collection<String>
attributeIds, ArrayList<Object> attributeValues)
For an entire list of XACML implementations, you can check this list on Wikipedia.
In Spring-Data-Rest an object's ID is the URI returned with the object. For example, if I have a User, it might have a URI like:
http://example.com/users/1
In an authentic REST api, this URI is the id of the object, you are not supposed to use just '1' as the id.
Give that, how do I search for all Orders that belong to that User?
http://example.com/orders/search/findByUser?user={{XXX}}
Specifically, what do I use for {{XXX}}?
I know I could do the opposite search:
http://example.com/users/1/orders
But in my case I need to search for matching jobs so I can add additional parameters which are also keys.
I can export /orders/search/findByUser by creating this function definition on OrderRepository:
List findByUser(User user);
and findByUser will be exported by Spring-Data-REST, but how do I specify the User as a GET parameter?
Again, I'm specifically looking for the pure REST solution, since the Spring Data Rest project is trying to encourage purity.
You might take a look at the Query annotation of Spring Data. It enables you to execute custom queries without the need of a custom controller.
Edit:
Query parameters are a good way to filter a resource by simple properties. As SDR serializes all complex types as relations, it is even clearer that filtering only applies to the remaining (simple) properties.
If you have only one relation, you correctly mentioned the way of doing the 'inverse' search as you called it by using /users/1/orders.
If you want to search by multiple relations I suggest you define a seperate search (sub-)resource and perform the search by issuing a POST-request to this resource.
For example:
POST /orders/search
{
"user": "http://example.org/users/1",
...
}
This way, SDR will correctly translate the URIs into entities. However, I think you will need to use a custom controller here but it should be possible to still use the Spring Data repository and provide the user and additional entities as parameter.
For further information, see the following SO-questions:
How to design RESTful search/filtering?
RESTful URL design for search
Edit2:
Addressing the point that using a POST for searching violates the REST spec:
REST was designed to be simple. One of the key advantages of REST is that you are not forced to do anything. You can adapt the spec until it fits your needs. Of course, this could mean that your API is less RESTful but you should consider if it is worth it to strictly stick to the spec if it introduces an unnecessary overhead for the consumers of your API.
Of course you can design the above the idea to fully meet the REST spec. This would involve creating a seperate search entity, persisting it to the database and later retrieve the result of the search with a call to a subresource like /result or something like that. However, the question is, if it is worth it.
In your concrete example, I would just require the client to parse the ID out of the link and provide it as query parameter. If you are scaling up your application later, you could introduce a feature like named searches and apply the above mentioned solution.
If you use a controller, like it seems to be your case, you can pass it any parameter(s) you consider necessary. Take a look at this question:
Spring Data REST custom query integration
See https://jira.spring.io/browse/DATAREST-502
Depending of your version of Spring Data, it would work as you want or not.
By the way, I still think the POST should be an option too, it would be much cleaner.
What is the difference between the push & pull models of MVC?
Is Struts2, Spring MVC Pull based?
According to Struts2 Interview Questions and Answers
Struts2 is a Pull-MVC based architecture, in which all data is stored in Value Stack and retrieved by view layer for rendering.
Specifically:
In case of Push-MVC the data (Model) is constructed and given to the
view layer by the Controllers by putting it in the scoped variables
like request or session. Typical example is Spring MVC and Struts1.
Pull-MVC on the other hand puts the model data typically constructed
in Controllers are kept in a common place i.e. in actions, which then
gets rendered by view layer.
The concept of push and pull refers to what the server does in relation to the client. In a "push" application, a server is pushing or sending data to clients at it's own initiation. In a "pull" application, the server is pulling or waiting for and receiving messages initiated by clients.
A good explanation is given here mvc-pattern-its-importance-push-pull and here pull-vs-push-mvc-architecture
Struts1 and Spring both use Push MVC. This question might be helpful spring-mvc-complex-model-population-from-multiple-sources Struts2 uses Pull
Struts2, Play! and so on are all kinds of pull model implementations of the MVC pattern.
Terms "push" and "pull" refer directly to the type of implementation of the observer pattern used between View and Model. As stated in GoF Observer pattern explaination, we have:
At one extreme, which we call the push model, the subject sends observers detailed information about the change, whether they want it or not. At the other extreme is the pull model; the subject sends nothing but the most minimal notification, and observers ask for details explicitly thereafter.
This means that the implementation of push model requires that View and Model are implemented using the same language and they are executed in the the same environment. Good examples of this kind of implementation are Javascript single page applications, in which View and Model components execute inside the browser and a framework, i.e. Backbone, provides MVC (a.k.a. Observer) mechanism. Often, Model component interacts with some kind of server API, to persist and get persisted datas.
On the other hand, pull model lets you implement MVC using different technologies for View component, and Controller / Model components. In this kind of MVC, there is not an explicit use of the Observer pattern and View interacts exclusively with Controller. View component, which usually executes into the browser, sends to Controller component request of model's updates or model's state. Usually requestes are implemented using HTTP protocol. This kind of implementation requires the use of some type of "augmented HTML scripting language", such as JSP, which allows to create automatically the link between View and Controller.
Sorry .. I dont think that struts 1, struts 2 and spring MVC can be taken as PUSH MVC ..
as both of all frameworks use a front controller[Filer class for Struts , And Controller Listener for Spring ] defined in their respective deployment descriptor. Now both of all these frame work save the form data in their respective bean[Or model] object using that controller by reflection.
Now from our Action Controller we can receive the bean object and will get the values but in the front controller where the bean object[or model] is actually generated set the value in their resperctive field by using request.getParameter(param) or request.getParameterValues(param) methods internally.. So this can be considered as PULL.
So as per my thinking we can say that These framework can use two layers namely PULL layers used by end programmer and PUSH layers used by framework base classes.
I am exposing a couple domain objects via a SOAP based web service. Some of my domain objects have a large number of fields. I do not want to include values in my web service request/response unless they are needed.
For example, if I have a Book domain object with fields title, genre, and isbn, if I wanted to use my web service to update the name of a book, I want my request to only include the title field (omitting the other two fields that aren't being updated).
Likewise, I want my web service clients to be able to specify which fields they want to be returned when they load books.
This would allow clients to load the title field thereby reducing the size of the data going across the wire because the fields that aren't needed would not be included in the response.
Does anyone know of any patterns or best practices to deal with this type of requirement?
You touched multiple problems where each deserves separate explanation:
Reducing traffic - reducing traffic usually means reducing roundtrips not reducing payload. Reducing traffic is achieved by implement better operations which do multiple actions instead of exposing CRUD operations.
Reducing payload - if you don't want to transfer whole entity you should use Data transfer objects. Special object transferring only data required for given operation.
Dynamic response - web services are not supposed to do that. Web service has fixed interface defined by WSDL where each message payload is specified by XSD. If you want dynamically change returned data structure you will break this. It doesn't mean it is not possible - you can define that your service operation returns xsd:any = any XML and it will be your duty to prepare returned XML and duty of your client to parse XML.
You can either make the fields optional in the XSD data type, or you can specify that in the changeTitle request you don't expect a Book, but only an ID and a string.
When you invent the changeAttributes request and you have optional fields, you have to decide what a missing field means. It could be clear this field or leave this field untouched.
In my Spring MVC application I am using DTO in the presentation layer in order to encapsulate the domain model in the service layer. The DTO's are being used as the spring form backing objects.
hence my services look something like this:
userService.storeUser(NewUserRequestDTO req);
The service layer will translate DTO -> Domain object and do the rest of the work.
Now my problem is that when I want to retrieve a DTO from the service to perform say an Update or Display I can't seem to find a better way to do it then to have multiple methods for the lookup that return different DTO's like...
EditUserRequestDTO userService.loadUserForEdit(int id);
DisplayUserDTO userService.loadUserForDisplay(int id);
but something does not feel right about this approach. Perhaps the service should not return things like EditUserRequestDTO and the controller should be responsible of assembling a requestDTO from a dedicated form object and vice versa.
The reason do have separate DTO's is that DisplayUserDTO is strongly typed to be read only and also there are many properties of user that are entities from a lookup table in the db (like city and state) so the DisplayUserDTO would have the string description of the properties while the EditUserRequestDTO will have the id's that will back the select drop down lists in the forms.
What do you think?
thanks
I like the stripped down display objects. It's more efficient than building the whole domain object just to display a few fields of it. I have used a similar pattern with one difference. Instead of using an edit version of a DTO, I just used the domain object in the view. It significantly reduced the work of copying data back and forth between objects. I haven't decided if I want to do that now, since I'm using the annotations for JPA and the Bean Validation Framework and mixing the annotations looks messy. But I'm not fond of using DTOs for the sole purpose of keeping domain objects out of the MVC layer. It seems like a lot of work for not much benefit. Also, it might be useful to read Fowler's take on anemic objects. It may not apply exactly, but it's worth thinking about.
1st Edit: reply to below comment.
Yes, I like to use the actual domain objects for all the pages that operate on a single object at a time: edit, view, create, etc.
You said you are taking an existing object and copying the fields you need into a DTO and then passing the DTO as part of the model to your templating engine for a view page (or vice-versa for a create). What does that buy you? The ref to the DTO doesn't weigh any less than the ref to the full domain object, and you have all the extra attribute copying to do. There's no rule that says your templating engine has to use every method on your object.
I would use a small partial domain object if it improves efficiency (no relationship graphs to build), especially for the results of a search. But if the object already exists don't worry about how big or complex it is when you are sticking it in the model to render a page. It doesn't move the object around in memory. It doesn't cause the templating engine stress. It just accesses the methods it needs and ignores the rest.
2nd edit:
Good point. There are situations where you would want a limited set of properties available to the view (ie. different front-end and back-end developers). I should read more carefully before replying. If I were going to do what you want I would probably put separate methods on User (or whatever class) of the form forEdit() and forDisplay(). That way you could just get User from the service layer and tell User to give you the use limited copies of itself. I think maybe that's what I was reaching for with the anemic objects comment.
You should use a DTO and never an ORM in the MVC layer! There are a number of really good questions already asked on this, such as the following: Why should I isolate my domain entities from my presentation layer?
But to add to that question, you should separate them to help prevent the ORM being bound on a post as the potential is there for someone to add an extra field and cause all kinds of mayhem requiring unnecessary extra validation.