没有注册 bean 解析器 [英] Getting No bean resolver registered

查看:27
本文介绍了没有注册 bean 解析器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

今天从Spring boot 1.2.5升级到1.3.0 BUILD-SNAPSHOT后调用@PreAuthorize 失败:

After upgrading today from Spring boot 1.2.5 to 1.3.0 BUILD-SNAPSHOT Calling @PreAuthorize fails:

示例:

@PreAuthorize("@defaultSecurityService.canDoSomething(authentication.principal.id, #objId)")
Result doSomething(@P("objId")String objId);

其中 defaultSecurityService 定义为:

@Service
public class DefaultSecurityService implements SecurityService {
    ...
    public boolean canDoSomething(String userId, String objId){
        return true; // 
    }
}

堆栈跟踪

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'

我尝试过的:

make SecurityService 扩展 [PermissionEvaluator][1] 并注册一个 bean在Application.java`

make SecurityService extend [PermissionEvaluator][1] and register a bean atApplication.java`

 @Bean
 @Lazy
 public PermissionEvaluator permissionEvaluator(){
     return securityService;
 }`

但我仍然遇到同样的错误

But i'm still getting the same error

阅读 spring security 4.0.2 文档没有发现任何有关重大更改的相关材料

Reading the spring security 4.0.2 documentation didn't reveal any relevant material about breaking changes

推荐答案

这似乎是一个 bug/springframework/boot/autoconfigure/security/oauth2/OAuth2AutoConfiguration.java" rel="noreferrer">OAuth2AutoConfiguration.具体来说,它引入了 OAuth2MethodSecurityConfiguration 使用没有 BeanResolver 的 OAuth2MethodSecurityExpressionHandler 覆盖 DefaultMethodSecurityExpressionHandler 设置.

This appears to be a bug in the newly added OAuth2AutoConfiguration. Specifically it brings in OAuth2MethodSecurityConfiguration which overrides the DefaultMethodSecurityExpressionHandler with a OAuth2MethodSecurityExpressionHandler that does not have a BeanResolver set.

如果您没有使用 OAuth2,那么最简单的解决方案是从您的类路径中删除 Spring Security OAuth.

If you are not using OAuth2, then the easiest solution is to remove Spring Security OAuth from your classpath.

或者,如果您使用 @SpringBootApplication,您可以使用以下内容排除 OAuth2AutoConfiguration:

Alternatively, you can exclude the OAuth2AutoConfiguration using the following if you use @SpringBootApplication:

@SpringBootApplication(exclude=OAuth2AutoConfiguration.class)

或者,如果您直接利用 @AutoConfiguration,您也可以使用以下内容:

alternatively you can use the following if you leverage @AutoConfiguration directly:

@AutoConfiguration(exclude=OAuth2AutoConfiguration.class)

更新

你也可以这样使用:

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);
}

我们必须将它包装在 DelegatingMethodSecurityExpressionHandler 中,因为 Spring Boot 的自动配置将用损坏的配置替换 DefaultMethodSecurityExpressionHandler 的任何子类.

We have to wrap it in the DelegatingMethodSecurityExpressionHandler because Spring Boot's auto config will replace any subclass of DefaultMethodSecurityExpressionHandler with the broken configuration.

这篇关于没有注册 bean 解析器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆