1

In my spring config file I have <global-method-security pre-post-annotations="enabled"/>

In my spring @Controller I have a @RequestMapping that has an @PreAuthorize on it as follows:

@PreAuthorize("true == false")
@RequestMapping(value="/image", method=RequestMethod.GET )
@ResponseBody
public ResponseEntity<byte[]> getImage(
        @RequestParam(value="imageSet", required=false) Long imageSetKey
        , @RequestParam(required=false, defaultValue="70") Integer size
        , @RequestParam(required=false) Unit unit
        , @RequestHeader( value="if-none-match", required=false ) String etag 
)
{
    // use the latest and greatest for the unit if they specify the unit, otherwise use the imageSetKey they pass in.
    if ( unit != null )
    {
        return getUnitImage( unit, size, etag );
    }
    // more code to do other stuff
}

Now this @PreAuthorize is evaluated and working correctly. If I put a PreAuthorize on the getUnitImage method, then it is not evaluated and I get into the method just fine. Here is the method on which the @PreAuthorize is NOT evaluated.

@PreAuthorize("true == false")
public ResponseEntity<byte[]> getUnitImage( Unit unit, int size, String etag )
{
    // do stuff, I get into breakpoints here.
}

Thoughts on why the PreAuthorize would be invoked on one method with the RequestMapping, but not on others in the same class?

Spring 3.0.5, Spring Security 3.0.3

digitaljoel
  • 26,265
  • 15
  • 89
  • 115

2 Answers2

6

This is caused by the way Spring AOP & CGLIB work. Specifically, a proxy class is created that extends your actual class, and that is what provides the implementation of the @PreAuthorize behavior. When you call a method from the same class, it doesn't go through the proxied class, and thus the desired behavior isn't executed.

One way to deal with this is to use AspectJ instead, by adding mode="aspectj" to your global-method-security element in your Spring config.

This also happens with @Transactional, and another question specifically about @Transactional has some more details regarding this issue:

Spring @Transaction method call by the method within the same class, does not work?

Community
  • 1
  • 1
Spencer Uresk
  • 3,730
  • 26
  • 23
  • Thanks for this info. With some wrangling, a lot of testing, and an upgrade to spring 3.1 I got everything working. Thanks also for the heads up on the @Transactional. – digitaljoel Jan 07 '12 at 07:35
1

How is the getUnitImage method being called?

Make sure that the way you're calling it allows the proxy (that is, the proxy that's created for the annotations) to intercept the call.

jtoberon
  • 8,706
  • 1
  • 35
  • 48