Announcement Announcement Module
Collapse
No announcement yet.
@PreAuthorize with Spring Data Repositories Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • @PreAuthorize with Spring Data Repositories

    Hi,

    I'm wondering if someone out there could assist...?

    I'm trying to configure a Spring Data CrudRepository with method level security.

    It all seems to work okay with @PostAuthorize & @PostFilter. But I'm having problems with I try to attach a @PreAuthorize annotation to the save method and reference the parameter using SPEL:

    Code:
    @Transactional
    public interface TestRecordRepository extends CrudRepository<TestRecord, Long>{
    	
    	@PreAuthorize("hasPermission(#record, 'write')")
    	<S extends TestRecord> S save(S record);
    }
    The error I'm getting is:

    Code:
    5:04:32,469 WARN   [MethodSecurityEvaluationContext] Unable to resolve method parameter names for method: public abstract uk.co.twofiveone.app.domain.TestRecord uk.co.twofiveone.app.repository.TestRecordRepository.save(uk.co.twofiveone.app.domain.TestRecord).
    So, it would appear that there is a parameter discoverer involved somewhere (localvariabletableparameternamediscoverer?) that can't resolve the SpEL parameters to the variable names within my class.

    I've checked the forums and made sure that my sts config is okay (preferences > java > compiler > classfile generation are all ticked);

    I've checked my maven config to make sure that I'm compiling with debug:

    Code:
    <plugin>
           	<artifactId>maven-compiler-plugin</artifactId>
    	<version>2.3.2</version>
    	<configuration>
                 <source>1.6</source>
                 <target>1.6</target>
                 <debug>true</debug>
           	</configuration>
    </plugin>
    I've got my global-method-security configured

    Code:
    <global-method-security pre-post-annotations="enabled">
            <expression-handler ref="expressionHandler"/>
    </global-method-security>
    I'm only trying this from a test case, not within a servlet environment.

    I thought it might be something to do with the way the repository was being injected into the test case (I'm just using @Autowired), but I've tried constructing the repository from the entity manager factory using the JpaRepositoryFactory but that just seemed to stop all security methods from working.

    Really scratching my head.

    I appreciate this may be a spring data issue, as much as a security one.

    My test is pretty trivial, and is based on the contacts sample:

    Code:
        @Test
        public void testRod(){
        	makeActiveUser("rod");
            TestRecord record = repository.findOne(new Long(1));
    	record.setDescription("Rod changed this!");
    	record = repository.save(record);
    	Assert.assertEquals("Rod changed this!", record.getDescription());
        }
    I have the contacts sample working (within the same project), and that all seems to work fine, using the same kind of annotations, but in that case it is securing a more traditional service layer (spring wired interface and implementation).

    I have thought about adding a layer above the CrudRepository, but ultimately I was planning on exposing the methods using the Spring Data Rest Exporter, so would really rather not have to do this...!

    Any ideas...?

    Thanks so much !

  • #2
    So, having spent the evening debugging this...

    from what I can tell - the LocalVariableTableParameterNameDiscoverer does indeed get involved - and it tries to inspect the annotated class (TestRecordRepository) using org.springframework.asm.ClassReader and a ParameternameDiscoveringVisitor (which appears to be correctly configured with my class name, and a map to hold the parameter names)…

    Unfortunately when I try to debug this any further I end up with the rather nasty looking error:

    - Invalid memory access of location 0x8 rip=0x10a1805ed

    If I don't try to follow the debugger process into this class then I can see that in the end the method returns but the map never gets populated…

    So - this would appear to be at (or near) the root of the problem…?

    And I'm still unclear as to why this issue only presents itself with my annotated Spring Data CrudRepository, yet it works with the contacts sample (ContactManager)

    Hmmm
    Last edited by AshleyB; Mar 19th, 2013, 07:06 PM.

    Comment


    • #3
      I created https://jira.springsource.org/browse/SEC-2151 for this

      Comment


      • #4
        Hi Rob

        Great, thanks - will keep an eye on the issue...

        Ash

        Comment

        Working...
        X