I'm trying to determine authorisation based on the current request, so I've decided to use a custom bean to accomplish that. Here's my minimal configuration:
@Configuration
@EnableResourceServer
public class OAuth2ResourceServerConfig extends ResourceServerConfigurerAdapter {
@Autowired
private TokenStore tokenStore;
@Override
public void configure(HttpSecurity http) throws Exception {
http.csrf().disable();
http.authorizeRequests().antMatchers(HttpMethod.GET, "/posts/**").access("@security.hasPermission(authentication, 'SOME', 'VALUES')");
// more here
http.authorizeRequests().anyRequest().authenticated();
}
@Override
public void configure(final ResourceServerSecurityConfigurer resources) throws Exception {
resources.tokenStore(tokenStore);
}
}
The exception I'm getting is org.springframework.expression.spel.SpelEvaluationException: EL1057E:(pos 8): No bean resolver registered in the context to resolve access to bean 'security'.
I've looked for this and found that this is supposedly fixed in Spring Boot 1.4.0.M1 (which I'm using). My spring-security-oauth2 version is 4.0.3.RELEASE.
For completeness, my security bean is defined as:
@Component("security")
public class SecurityService {
public boolean hasPermission(Authentication authentication, String param, String anotherParam) { ... }
}
I've also tried to make the SecurityService implement PermissionResolver or make it a PermissionResolver bean, but without any success.
I know that in theory this should work, as it actually does in practice if I put the same rules (as in configure(HttpSecurity http)) in another WebSecurityConfigurerAdapter. I then, however, have other issues which I've tried to explain the the following StackOverflow post.
Seems like the default OAuth2 Expression Handler's Bean Resolver is null. At least it was for me in 2.0.9.
Is there a way to override the expression handler? It seems to always overwrite with the default no matter what.
After some investigation I managed to workaround this issue by doing the following:
@Bean with OAuth2WebSecurityExpressionHandler that explicitly sets the application context @Bean
public OAuth2WebSecurityExpressionHandler oAuth2WebSecurityExpressionHandler(ApplicationContext applicationContext) {
OAuth2WebSecurityExpressionHandler expressionHandler = new OAuth2WebSecurityExpressionHandler();
expressionHandler.setApplicationContext(applicationContext);
return expressionHandler;
}
@Autowired
private OAuth2WebSecurityExpressionHandler expressionHandler;
@Override
public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
resources.expressionHandler(expressionHandler);
}
Hope this helps someone in the future!
i was try to add a param to path : antMatchers("/admin/{userId}/**").access("@security.meAsUser(authentication,#userId)")
getting #userId value null
and related to this post : https://github.com/spring-projects/spring-security/issues/3781
i was using spring-boot-starter-security instead of security:spring-security-web:4.1.1.RELEASE
Hope this helps someone in the future :)
You can resolve this generating the OAuth2MethodSecurityExpressionHandler instance as a bean.
Instead do that:
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class OAuth2ResourceServerConfig extends GlobalMethodSecurityConfiguration {
@Override
protected MethodSecurityExpressionHandler createExpressionHandler() {
return new OAuth2MethodSecurityExpressionHandler();
}
....
}
do this:
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class OAuth2ResourceServerConfig extends GlobalMethodSecurityConfiguration {
@Override
protected MethodSecurityExpressionHandler createExpressionHandler() {
return getOAuth2MethodSecurityExpressionHandler();
}
@Bean
public OAuth2MethodSecurityExpressionHandler getOAuth2MethodSecurityExpressionHandler() {
return new OAuth2MethodSecurityExpressionHandler();
}
....
}
Hope this'll others !
@danito8905 indeed it helped ;-)
Great! It helped me a lot!. Thank you guys!
很不错,搞定了
在5.0.7版本需要把OAuth2WebSecurityExpressionHandle换成DefaultWebSecurityExpressionHandler,可以解决这个问题,在ResourceServerConfig中添加就可以了。
If your spirngsecurity is 5.0.7,could use DefaultWebSecurityExpressionHandler replace OAuth2WebSecurityExpressionHandle.
https://github.com/spring-projects/spring-security/issues/4903
完美解决了,nice!
在5.0.7版本需要把OAuth2WebSecurityExpressionHandle换成DefaultWebSecurityExpressionHandler,可以解决这个问题,在ResourceServerConfig中添加就可以了。
If your spirngsecurity is 5.0.7,could use DefaultWebSecurityExpressionHandler replace OAuth2WebSecurityExpressionHandle.
https://github.com/spring-projects/spring-security/issues/4903
还需要把ApplicationContext设置进去
You also should set ApplicationContext in this DefaultWebSecurityExpressionHandler
It works!Great
Most helpful comment
Seems like the default OAuth2 Expression Handler's Bean Resolver is null. At least it was for me in 2.0.9.
Is there a way to override the expression handler? It seems to always overwrite with the default no matter what.
After some investigation I managed to workaround this issue by doing the following:
@BeanwithOAuth2WebSecurityExpressionHandlerthat explicitly sets the application contextHope this helps someone in the future!