簡體   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