[英]Getting No bean resolver registered
After upgrading today from Spring boot 1.2.5
to 1.3.0 BUILD-SNAPSHOT
Calling @PreAuthorize
fails: 今天从Spring boot 1.2.5
升级到1.3.0 BUILD-SNAPSHOT
调用@PreAuthorize
失败:
example: 例:
@PreAuthorize("@defaultSecurityService.canDoSomething(authentication.principal.id, #objId)")
Result doSomething(@P("objId")String objId);
where defaultSecurityService
is defined as: 其中defaultSecurityService
定义为:
@Service
public class DefaultSecurityService implements SecurityService {
...
public boolean canDoSomething(String userId, String objId){
return true; //
}
}
Stack trace 堆栈跟踪
Caused by: java.lang.IllegalArgumentException: Failed to evaluate expression '#oauth2.throwOnError(defaultSecurityService.canDoSomething(authentication.principal.id, #objId))'
at org.springframework.security.access.expression.ExpressionUtils.evaluateAsBoolean(ExpressionUtils.java:14)
...
Caused by: org.springframework.expression.spel.SpelEvaluationException: EL1057E:(pos 8): No bean resolver registered in the context to resolve access to bean 'defaultSecurityService'
what i've tried: 我试过的:
make SecurityService
extend [PermissionEvaluator ][1] and register a bean at
Application.java` 使SecurityService
扩展[PermissionEvaluator ][1] and register a bean at
Application.java`中][1] and register a bean at
@Bean
@Lazy
public PermissionEvaluator permissionEvaluator(){
return securityService;
}`
But i'm still getting the same error 但我仍然得到同样的错误
Reading the spring security 4.0.2 documentation didn't reveal any relevant material about breaking changes 阅读spring security 4.0.2文档并未透露任何有关重大更改的相关资料
This appears to be a bug in the newly added OAuth2AutoConfiguration . 这似乎是新添加的OAuth2AutoConfiguration中的错误 。 Specifically it brings in OAuth2MethodSecurityConfiguration which overrides the DefaultMethodSecurityExpressionHandler
with a OAuth2MethodSecurityExpressionHandler
that does not have a BeanResolver
set. 具体地说,它带来了OAuth2MethodSecurityConfiguration将覆盖DefaultMethodSecurityExpressionHandler
与OAuth2MethodSecurityExpressionHandler
不具有BeanResolver
集。
If you are not using OAuth2, then the easiest solution is to remove Spring Security OAuth from your classpath. 如果您不使用OAuth2,那么最简单的解决方案是从类路径中删除Spring Security OAuth。
Alternatively, you can exclude the OAuth2AutoConfiguration
using the following if you use @SpringBootApplication
: 另外,您也可以排除OAuth2AutoConfiguration
使用下列如果你使用@SpringBootApplication
:
@SpringBootApplication(exclude=OAuth2AutoConfiguration.class)
alternatively you can use the following if you leverage @AutoConfiguration
directly: 或者,如果直接利用@AutoConfiguration
则可以使用以下内容:
@AutoConfiguration(exclude=OAuth2AutoConfiguration.class)
UPDATE UPDATE
You can also use something like this: 你也可以使用这样的东西:
public class DelegatingMethodSecurityExpressionHandler implements
MethodSecurityExpressionHandler {
private final MethodSecurityExpressionHandler delegate;
public DelegatingMethodSecurityExpressionHandler(
MethodSecurityExpressionHandler delegate) {
super();
this.delegate = delegate;
}
public Object filter(Object filterTarget, Expression filterExpression,
EvaluationContext ctx) {
return delegate.filter(filterTarget, filterExpression, ctx);
}
public ExpressionParser getExpressionParser() {
return delegate.getExpressionParser();
}
public EvaluationContext createEvaluationContext(
Authentication authentication, MethodInvocation invocation) {
return delegate.createEvaluationContext(authentication, invocation);
}
public void setReturnObject(Object returnObject, EvaluationContext ctx) {
delegate.setReturnObject(returnObject, ctx);
}
}
Then in your configuration use: 然后在您的配置中使用:
@Autowired(required = false)
List<AuthenticationTrustResolver> trustResolvers = new ArrayList<>();
@Autowired(required = false)
List<PermissionEvaluator> permissionEvaluators = new ArrayList<>();
@Bean
public MethodSecurityExpressionHandler securityExpressionHandler(ApplicationContext context) {
OAuth2MethodSecurityExpressionHandler delegate = new OAuth2MethodSecurityExpressionHandler();
delegate.setApplicationContext(context);
if(trustResolvers.size() == 1) {
delegate.setTrustResolver(trustResolvers.get(0));
}
if(permissionEvaluators.size() == 1) {
delegate.setPermissionEvaluator(permissionEvaluators.get(0));
}
return new DelegatingMethodSecurityExpressionHandler(delegate);
}
We have to wrap it in the DelegatingMethodSecurityExpressionHandler because Spring Boot's auto config will replace any subclass of DefaultMethodSecurityExpressionHandler
with the broken configuration. 我们必须将它包装在DelegatingMethodSecurityExpressionHandler中,因为Spring Boot的自动配置将使用损坏的配置替换DefaultMethodSecurityExpressionHandler
任何子类。
I had the same problem than you, my bean in charge of managing security on a REST controller wasn't found: 我遇到了与你相同的问题,我找不到负责管理REST控制器安全性的bean:
org.springframework.expression.spel.SpelEvaluationException: EL1057E:(pos 8): No bean resolver registered in the context to resolve access to bean 'communitySecurityAuthorizer
Rob's reply pointed me in the right direction (I thought I was doing it wrong, not that it was a bug in the standard Spring OAuth2). Rob的回复指出了我正确的方向(我认为我做错了,而不是标准Spring OAuth2中的错误)。
I don't use springboot as I'm making a webapp and I found the answer that solved my problem here: https://github.com/spring-projects/spring-security-oauth/issues/730#issuecomment-219480394 我不使用springboot,因为我正在制作一个webapp,我找到了解决我问题的答案: https : //github.com/spring-projects/spring-security-oauth/issues/730#issuecomment-219480394
The problem comes in fact from the bean resolver which is null so here is the solution (retranscription of the link above): 问题来自于bean解析器,它是null,所以这里是解决方案(上面链接的重新转换):
Add a @Bean with OAuth2WebSecurityExpressionHandler that explicitly sets the application context 使用显式设置应用程序上下文的OAuth2WebSecurityExpressionHandler添加@Bean
@Bean
public OAuth2WebSecurityExpressionHandler oAuth2WebSecurityExpressionHandler(ApplicationContext applicationContext) {
OAuth2WebSecurityExpressionHandler expressionHandler = new OAuth2WebSecurityExpressionHandler();
expressionHandler.setApplicationContext(applicationContext);
return expressionHandler;
}
In the ResourceServerConfigurerAdapter, configure the resources and pass in the Bean above. 在ResourceServerConfigurerAdapter中,配置资源并传入上面的Bean。
@Autowired
private OAuth2WebSecurityExpressionHandler expressionHandler;
@Override
public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
resources.expressionHandler(expressionHandler);
}
Hope this'll others ! 希望这个别人!
As Almiriad has said, generate the OAuth2MethodSecurityExpressionHandler
instance as a bean. 正如Almiriad所说,生成OAuth2MethodSecurityExpressionHandler
实例作为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 ! 希望这个别人!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.