Spring security @PreAurhorize hasRole() properties injection
Spring security @PreAurhorize hasRole() properties injection
assuming that my spring security and properties are configured properly, I would like to use role name from property like
@PreAuthorize("hasRole('$role.rolename')")
public void method()
I have tried like in above code sample but it does not work ( it takes '$role.rolename' String as role to compare)
if I switch to
@PreAuthorize("hasRole('ROLE_ADMIN')")
public void method()
it works just fine.
My motivation to such usage is better flexibility in application tests on various environments.
@Configuration
@Bean PropertySourcesPlaceholderConfigurer
@Value("$role.rolename") private String ROLE_NAME;
3 Answers
3
Try to remove '' signs:
''
@PreAuthorize("hasRole($role.rolename)")
public void method()
EDIT. I am sure that there is a better way, but as a workaround you can call some method on some bean:
@Component("appVariablesHolder")
public class AppVariablesHolder
@Value("$role.rolename")
private String someRole;
public String getSomeRole()
return this.someRole;
@PreAuthorize("hasRole(@appVariablesHolder.getSomeRole())")
public void method()
When I removed
'' signs, I got: Caused by: org.springframework.expression.spel.SpelParseException: EL1043E:(pos 9): Unexpected token. Expected 'rparen())' but was 'lcurly({)' property name replacement changed nothig– Paweł Kaczorowski
Aug 13 '13 at 11:43
''
Caused by: org.springframework.expression.spel.SpelParseException: EL1043E:(pos 9): Unexpected token. Expected 'rparen())' but was 'lcurly({)'
Try to replace
$ by # : @PreAuthorize("hasRole(#role.rolename)")– Maksym Demidas
Aug 13 '13 at 12:02
$
#
Again I'm getting the same error...
– Paweł Kaczorowski
Aug 13 '13 at 12:11
it's clear from this answer that the single quotes are wrong, but it would seem that we should be able to reference the properties with $, but it doesn't seem to work :( -- stackoverflow.com/questions/19836387/…
– chrismarx
Jun 24 '15 at 15:46
I've found that you can just grab the propertyResolver and pull values directly from that, instead of writing your own class as was suggested by @Maksym.
Exammple:
@PreAuthorize("hasRole(@environment.getProperty('role.rolename')")
public void method()
` org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'propertyResolver' available`
– jbx
May 5 '18 at 10:01
@jbx - You need to use the bean name of whatever your property resolver is. So if you’ve named yours something else, swap that in instead.
– Ben L.
May 6 '18 at 11:40
And how is that different from writing your own class?
– jbx
May 7 '18 at 14:11
Spring provides a property resolver, without having to write one. You just need to make sure you use the bean name that spring assigns to it (whatever that is, or if you've renamed the bean). This works for me. I use it on all of my controllers that need security.
– Ben L.
May 25 '18 at 18:07
So maybe you need the configuration part which initialises the property resolver as a
@Bean, and you have it somewhere else in your code? On its own this line doesn't work.– jbx
May 28 '18 at 14:38
@Bean
Building on other answers here, one thing that tripped me up was not setting the context on the OAuth2MethodSecurityExpressionHandler.
OAuth2MethodSecurityExpressionHandler
Make sure that in your MethodSecurityConfig you're loading the context for the answers above to work.
MethodSecurityConfig
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class MethodSecurityConfig extends GlobalMethodSecurityConfiguration
@Autowired
private ApplicationContext context;
@Override
protected MethodSecurityExpressionHandler createExpressionHandler()
OAuth2MethodSecurityExpressionHandler handler = new OAuth2MethodSecurityExpressionHandler();
handler.setApplicationContext(context);
return handler;
Then you can successfully access
@PreAuthorize("hasRole(@environment.getProperty('role.rolename')")
public void method()
Thanks for contributing an answer to Stack Overflow!
But avoid …
To learn more, see our tips on writing great answers.
Required, but never shown
Required, but never shown
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
We have some
@Configurationwhere@Bean PropertySourcesPlaceholderConfigureris configured, but I'm pretty sure that property is wired properly because when I define in the same class where secured method:@Value("$role.rolename") private String ROLE_NAME;Correct value is present– Paweł Kaczorowski
Aug 13 '13 at 12:30