繁体   English   中英

没有注册bean解析器

[英]Getting No bean resolver registered

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

例:

@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'

我试过的:

使SecurityService扩展[PermissionEvaluator ][1] and register a bean at Application.java`中][1] and register a bean at

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

但我仍然得到同样的错误

阅读spring security 4.0.2文档并未透露任何有关重大更改的相关资料

这似乎是新添加的OAuth2AutoConfiguration中错误 具体地说,它带来了OAuth2MethodSecurityConfiguration将覆盖DefaultMethodSecurityExpressionHandlerOAuth2MethodSecurityExpressionHandler不具有BeanResolver集。

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

另外,您也可以排除OAuth2AutoConfiguration使用下列如果你使用@SpringBootApplication

@SpringBootApplication(exclude=OAuth2AutoConfiguration.class)

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

@AutoConfiguration(exclude=OAuth2AutoConfiguration.class)

UPDATE

你也可以使用这样的东西:

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

然后在您的配置中使用:

@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任何子类。

我遇到了与你相同的问题,我找不到负责管理REST控制器安全性的bean:

org.springframework.expression.spel.SpelEvaluationException: EL1057E:(pos 8): No bean resolver registered in the context to resolve access to bean 'communitySecurityAuthorizer

Rob的回复指出了我正确的方向(我认为我做错了,而不是标准Spring OAuth2中的错误)。

我不使用springboot,因为我正在制作一个webapp,我找到了解决我问题的答案: https//github.com/spring-projects/spring-security-oauth/issues/730#issuecomment-219480394

问题来自于bean解析器,它是null,所以这里是解决方案(上面链接的重新转换):

使用显式设置应用程序上下文的OAuth2WebSecurityExpressionHandler添加@Bean

@Bean
    public OAuth2WebSecurityExpressionHandler oAuth2WebSecurityExpressionHandler(ApplicationContext applicationContext) {
        OAuth2WebSecurityExpressionHandler expressionHandler = new OAuth2WebSecurityExpressionHandler();
        expressionHandler.setApplicationContext(applicationContext);
        return expressionHandler;
    }

在ResourceServerConfigurerAdapter中,配置资源并传入上面的Bean。

@Autowired
    private OAuth2WebSecurityExpressionHandler expressionHandler;
    @Override
    public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
        resources.expressionHandler(expressionHandler);
    }

希望这个别人!

正如Almiriad所说,生成OAuth2MethodSecurityExpressionHandler实例作为bean。

而是这样做:

@EnableGlobalMethodSecurity(prePostEnabled = true)
public class OAuth2ResourceServerConfig extends GlobalMethodSecurityConfiguration {

        @Override
        protected MethodSecurityExpressionHandler createExpressionHandler() {
             return new OAuth2MethodSecurityExpressionHandler();
        }

        ....
}

做这个:

@EnableGlobalMethodSecurity(prePostEnabled = true)
public class OAuth2ResourceServerConfig extends GlobalMethodSecurityConfiguration {

        @Override
        protected MethodSecurityExpressionHandler createExpressionHandler() {
             return getOAuth2MethodSecurityExpressionHandler();
        }

        @Bean
        public OAuth2MethodSecurityExpressionHandler getOAuth2MethodSecurityExpressionHandler() {
             return new OAuth2MethodSecurityExpressionHandler();
        }

        ....
}

希望这个别人!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM