I've some RESTful services, implemented with Spring MVC, exposing a set of resources. I already use authentication, based on HTTPBasicAuthentication and HTTPS. Some of the resources must be accessible only to some users.
For example, I want that all sub-resources in the URI /users/{userid}/photos
are accessible only to the user userid
. Actually in my application they are accessible to all authenticated users. How can I protect them from other users except userid
?
And what if I want to allow access to this resources only to a subset of users (like, for example, userid
's friends)?
you could do something like this on your method:
@ResponseBody
@RequestMapping(value = "/users/{userid}/photos", method = RequestMethod.GET)
@Secured(value = {"userid"})
public ResponseEntity<ModelMap> getPhotos(....) throws Exception {
you can add more users if you want in the future by just doing
@Secured(value = {"ROLE_ADMIN", "userid"})
I would strongly suggest to use Spring Security. Using Spring security you can restrict access to a specific URL endpoints to principals owning specific roles.
See spring security intercept url roles
You can also use JSR-250 annotations: see http://forum.springsource.org/showthread.php?126395-How-to-secure-Spring-MVC-controllers-using-Spring-Security-annotations
--
I do not think you need to restrict the URL /resource/{user} to that specific user. You should deduct the user name from the security context and not let someone inject a specific use name by forging the URL...
You can use custom security expression.
<security:intercept-url pattern="/users/{userid}/photos" access="getUserIdUrlPathParameter() == principal.userId"/>
See this post for how to do it.
I solved it by using @PreAuthorize("authentication.name == #userId")
, instead of @Secured(value = {"userid"})
or @Secured(value = {"#userid"})
like suggested, that were not working.
Note it's necessary to add <security:global-method-security pre-post-annotations="enabled"/>
to the servlet context configuration file.