In a Spring web / ws project I have a requirement that says that based on the granted authorities of current user authentication, a user can see more information of a person. In this case email. In my jsp I have solved this as followed:
java:
jsp:Code:@Controller public class PersonsController { @RequestMapping("person") public ModelAndView viewPerson(@RequestParam Long id) { // method stripped for clarity; person is Hibernate Entity Person person = new Person("John", "john@example.org"); ModelMap model = new ModelMap(); model.addAttribute(person); return new ModelAndView("view-person", model); } }
Code:<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <%@ taglib prefix="security" uri="http://www.springframework.org/security/tags" %> name: ${person.name}<br/> <security:authorize ifAllGranted="ROLE_CAN_ACCESS_EMAIL"> email: ${person.email}<br/> </security:authorize>
Similar functionallity is also exposed through a webservice (spring-ws/jaxb). But how to do this is an Endpoint?
Code:@Endpoint public class PersonsEndpoint { @PayloadRoot(localPart = "GetPersonRequest") public GetPersonResponse getPerson(GetPersonRequest request) { // method stripped for clarity; person is Hibernate Entity Person person = new Person("John", "john@example.org"); GetPersonResponse response = new GetPersonResponse(); response.getPerson().setName(person.getName()); // How to secure this line? response.getPerson().setEmail(person.getEmail()); } }
I looked around and found the following options:
a) create a second wrapper method getEmail and annotate it with @Secured("ROLE_CAN_ACCESS_EMAIL") and catch AccessDeniedException
b) create a second wrapper method getEmail and annotate it with @PreAuthorize("hasRole('ROLE_CAN_ACCESS_EMAIL')") and catch AccessDeniedException
c) loop manually over SecurityContextHolder.getContext().getAuthenticati on().getAuthorities() and test for presence of the GrantedAuthority.
Example A:
Code:public interface PersonHelper { @Secured("ROLE_CAN_ACCESS_EMAIL") String getEmail(String email); } @Component public class PersonHelperImpl { @Secured("ROLE_CAN_ACCESS_EMAIL") public String getEmail(String email) { return email; } } @Endpoint public class PersonsEndpoint { @Autowired private PersonHelper helper; @PayloadRoot(localPart = "GetPersonRequest") public GetPersonResponse getPerson(GetPersonRequest request) { // method stripped for clarity; person is Hibernate Entity Person person = new Person("John", "john@example.org"); String email = null; try { email = helper.getEmail(person.getEmail()); } catch(org.springframework.security.access.AccessDeniedException e) { // no access } GetPersonResponse response = new GetPersonResponse(); response.getPerson().setName(person.getName()); response.getPerson().setEmail(email); return response; } }
Right now I settled for A, but it doesnt feel right.. (Actually, pretty sure it isn't)
It is not that the user is denied access to the whole function, but more limited in amount of information he can retrieve. (or maybe in other cases allowed to retrieve more info) .
Any thoughts or suggestions?


)
Reply With Quote