10

I'm trying to access a bean reference in a @PreAuthorize annotation as follows:

@PreAuthorize("@testBean.getTestValue()")
public String testSpEL() {
    ....
}

I have a test bean configured as follows:

@Component(value="testBean")
public class TestBean {
    public boolean getTestValue() {
        return true;
    }
}

When I try to access the testSpEL() method however, I'm confronted with the following exception:

Caused by: org.springframework.expression.spel.SpelEvaluationException: EL1057E:(pos 1): No bean resolver registered in the context to resolve access to bean 'testBean'
    at org.springframework.expression.spel.ast.BeanReference.getValueInternal(BeanReference.java:45)
    at org.springframework.expression.spel.ast.CompoundExpression.getValueInternal(CompoundExpression.java:52)
    at org.springframework.expression.spel.ast.SpelNodeImpl.getTypedValue(SpelNodeImpl.java:102)
    at org.springframework.expression.spel.standard.SpelExpression.getValue(SpelExpression.java:97)
    at org.springframework.security.access.expression.ExpressionUtils.evaluateAsBoolean(ExpressionUtils.java:11)

I have thoroughly done my research but I can't find anywhere what I need to change in my configuration to get this to work. Any pointers?

Thanks!

Kind regards, Jonck

P.S. I'm using Spring 3.0.5. The following seems to indicate this type of functionality should work:

https://jira.springsource.org/browse/SPR-7173

Jonck van der Kogel
  • 2,983
  • 3
  • 23
  • 30
  • I never have seen something like: `@testBean.getTestValue()` in @PreAuthorize. Can you please attach an comment with an URL to an example or documentation of this feature. – Ralph Apr 21 '11 at 12:48
  • 1
    Look here: http://static.springsource.org/spring/docs/3.0.x/reference/expressions.html at 6.5.12 Bean references In the Spring Security docs it says it allows SpEL, therefore something like this should be possible. – Jonck van der Kogel Apr 21 '11 at 13:22
  • did you ever tryed the same expressions in a @Value annotation – Ralph Apr 21 '11 at 14:21
  • @Ralph: Good question! I have rewritten my test case so that: @Value("#{ @testBean.getTestValue()}") private String testValue = "foo"; Where testBean.getTestValue() returns "bar". And indeed Spring changes the value of testValue to "bar". So I guess this proves the syntax "#{ @testBean.getTestValue()}" is correct, but just that it's not working in combination with Spring Security. (sorry about the formatting, no idea how I format these comments correctly) – Jonck van der Kogel Apr 21 '11 at 14:45
  • 1
    In my case, setting `ApplicationContext` solved the problem. See Rob's answer here: https://stackoverflow.com/a/29374842/2893542 – John Smith Dec 08 '20 at 00:33

3 Answers3

6

I have posted a similar question at SpringSource, it turns out that indeed the above feature is not yet supported in Spring Security 3.0.5. Luckily version 3.1.0.RC1 does support it, though with non-standard SpEL syntax:

@PreAuthorize("testBean.getTestValue()")
public String testSpEL() {
    ....
}

Here is the url of the thread at SpringSource forum: SpringSource forum thread

Hope this helps someone!

Jonck van der Kogel
  • 2,983
  • 3
  • 23
  • 30
  • I also wrote a blog post about this subject in case you want to read more about it: http://blog.42.nl/articles/spring-security-accessing-spring-beans-from-your-security-annotations – Jonck van der Kogel Apr 29 '11 at 21:03
  • nice blog post. Looks like they are at the standard syntax now based on page 2 of the linked forum thread. – digitaljoel Nov 20 '11 at 05:55
  • Blog post was moved here should anyone be interested: http://dontpanic.42.nl/2011/04/spring-security-accessing-spring-beans.html – Jonck van der Kogel Jun 01 '16 at 07:50
2

In Spring Security 3.1 (since 3.1.RC2)

@PreAuthorize("testBean.getTestValue()") 

doesn't work - instead you must write

@PreAuthorize("@testBean.getTestValue()")

See https://jira.springsource.org/browse/SEC-1723

zaplitny
  • 416
  • 4
  • 19
0

For anyone stuck on Spring Security 3.0.x I have a somewhat simple workaround. Add this class in your application-securityContext.xml (or whatever):

https://gist.github.com/3340059

It injects a BeanFactoryResolver into the Spring Security code, which is all the Spring Security 3.1.x fix has. Support for the syntax is already in 3.0.x. It allows you to use the syntax from 3.1.x, ala:

@PreAuthorize("@controller.theProperty")

Nick Spacek
  • 4,717
  • 4
  • 39
  • 42