Reputation: 3566
It was easy to hide fields in JSP/JSTL according to user privileges defined implementing Spring Security. One could easily write something like this:
<%-- Assume message.title requires no privilege -->
<c:out value="${message.title}" />
<%-- Assume message.text requires PRIV_READ_MESSAGE -->
<security:authorize ifAllGranted="PRIV_READ_MESSAGE">
<c:out value="${message.text}" />
</secrurity:authorize>
My question is how to do this if we do not use JSP. In my future projects, I want to use plain HTML files with Angular JS, AJAX requests, and JSON responses.
For example, I may create an API to return a message like this:
GET /api/v1/message/{msgId}
If user do not have the privilege PRIV_READ_MESSAGE, the JSON response of this API will be like:
{
"messageId": 123,
"title": "Sample Message 101"
}
If the user have that privilege, the JSON response of this API will be the following:
{
"messageId": 123,
"title": "Sample Message 101",
"text": "Message Body will be included..."
}
Assuming that I've implemented the following Spring controller:
@RequestMapping(value = "api/v1/message/{messageId}", method = RequestMethod.GET)
public ResponseEntity<Message> getMessage(@PathVariable Long messageId) {
// use some magic code to fetch Message from DB
Message message = null;
return new ResponseEntity<>(message, HttpStatus.OK);
}
I do not want to add if/else to my Controller methods in order to check if the logged in user have sufficient privileges or not. Can I filter JSON response fields somewhere according to user privileges?
You may assume that a ThreadLocal variable is used to store current user's privileges.
Upvotes: 2
Views: 157
Reputation: 3733
If you can use Jersey (2.16+), then there is out-of-the-box solution for your problem: https://jersey.java.net/documentation/latest/entity-filtering.html#ef.security.annotations http://blog.dejavu.sk/2015/02/04/jerseys-entity-filtering-meets-jackson/
I haven't tried it yet but it looks promising...
How about Spring (without Jersey)? I haven't seen any information about similar mechanism in Spring Security / MVC yet... Spring Security filters (by default) can't be applied to your entities because they are not managed by Spring. However, you could try to implement this using AOP and AspectJ:
https://stackoverflow.com/a/31522654/1545775
There was a github issue for that kind of feature but i don't know what is the status:
https://github.com/spring-projects/spring-security/issues/3250
What you can do now with Spring Security (without any extra configuration) is entities lists filtering (based on Spring Security roles). Just use @PostFilter
annotations on your secured methods (e.g. Repository methods). But if you decide to use this solution, you should be aware about performance issues when using bigger data sets.
Upvotes: 1