0

I'm very new to the Spring Security Framework and I have a little problem here to solve.

I've already managed to use the @PreAuthorized("hasPermission('#person', Permission) annotation for service and controller methods. This works fine for me, but this only works for the whole Domain class.

In my case there are some fields which should be shown to users despite they haven't the permission to read this Person.

A quick example:

  1. A user logs in.
  2. He'd like to visit the profile page from Jon Doe.
  3. But the user did not have the right to read Jon Doe.
  4. The System should notice the user that he hasn't the rights and shows the Name like: You doesn't have the permission to read the profile from Jon Doe."

This is a very simple example, there are more fields a user could see.

Hopefully you'll understand what I'm asking for.

(I´m sorry my english is not that good.)

EDIT

PersonController

 @RequestMapping("/{id}")
 public String get(@PathVariable("id") Long personId, Model model,HttpSession session) {

    Person person = personService.findById(personId);

    /* DO STUFF HERE */

    return "person.show";
}

PersonService

@PreAuthorize("hasPermission('#personId', <domainClass>, 'read')")
public Person findById(Long personId) {
    return personRepository.findOne(personId);
}

1 Answers1

0

You could do it explicitely by no using @PreAuthorized("hasPermission('#person', Permission) annotation at all and instead doing it by hand in your code ... but that would partially defect the interest of using Spring Security framework !

I would suggest :

  • use the @PreAuthorized("hasPermission('#person', Permission) annotation in service class layer => it should throw an AccessDeniedException is user is not allowed to read that profile
  • add a handler for AccessDeniedException in the calling controller. As exception will be thrown during the execution of a method of the controller, that handler will be given a chance to process it. Call a non protected method from the relevant service class that will only return public fields and forward to a view indicating You doesn't have the permission to read the profile from Jon Doe

In that configuration, the exception handler should take parameters equivalent to original controller method to have access to :

  • the Principal executing the request
  • the id for the requested profile

But this should not be a problem since an exception handler can accept almost the same parameters that a @RequestMapping method does in addition to the exception itself.

Per your edit, you get the personId from a path variable, which would be hard to get from the exception handler. So you should save it as a request attribute before calling the protected service method to get it in the exception handler :

 @RequestMapping("/{id}")
 public String get(@PathVariable("id") Long personId, Model model,HttpSession session, HttpServletRequest request) {

    request.setAttribute("personId", personId);
    Person person = personService.findById(personId);

    /* DO STUFF HERE */

    return "person.show";
} 

@ExceptionHandler(AccessDeniedException.class)
 public ModelAndView accessDeniedHandler(HttpServletRequest request) {
    ModelAndView mav = new ModelAndView("accessDeniedView");
    Long personId = request.getAttribute("personId");
    // populate your model
    return mav;
}
Serge Ballesta
  • 143,923
  • 11
  • 122
  • 252
  • thank you for your answer, if I get you right this Exception Handling would be used when ever a `AccessDeniedException` caused by the controller? I only need this for some specific methods, the other `@RequestMapping` methods should show the AccessDeniedPage. Also I didnt know how to get the additional parameters like the id from the profile into the `@ExceptionHandler` method – Dennis Bukowski Apr 23 '15 at 12:11
  • @DennisBukowski : As you didn't show how you get it in you controller method, I cannot tell you how to get it in the exception handler ... May be you should edit your question to show some code – Serge Ballesta Apr 23 '15 at 13:08
  • I recently added some Code to my question – Dennis Bukowski Apr 23 '15 at 14:16
  • Thank you very much, I'll try it tomorrow. I would vote you up but my reputation is not high enough... – Dennis Bukowski Apr 23 '15 at 18:02