Announcement Announcement Module
Collapse
No announcement yet.
Security on Endpoints: how to enforce roles? Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Security on Endpoints: how to enforce roles?

    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:
    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", "[email protected]");
    		
    		ModelMap model = new ModelMap();
    		model.addAttribute(person);
    		return new ModelAndView("view-person", model);
    	}
    }
    jsp:
    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", "[email protected]");
    
    		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", "[email protected]");
    	
    		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?

  • #2
    Did you look into using @PostFilter? This is similar to what you want, but you will probably need to create a new implementation of MethodSecurityExpressionHandler (the provided one, DefaultMethodSecurityExpressionHandler, only works on collections).

    Comment


    • #3
      Thanks for your suggestion.

      In the meantime I also had a look at http://www.infoq.com/presentations/Spring-Security-3. And it seems to me that the thing I'm trying to achieve, is quite uncommon to do by using Roles in such way. These seem to be about fully allowing or denying access to an object.

      I take a look at @PostFilter.

      Comment

      Working...
      X