AbstractSecurityInterceptor 必须提供一个非空的 AccessDecisionManager

AbstractSecurityInterceptor must provide a non-null AccessDecisionManager

自从 Spring 安全升级到 5.6.2 我有问题 运行 我的应用程序不断收到:

Caused by: java.lang.IllegalArgumentException: AbstractSecurityInterceptor must provide a non-null AccessDecisionManager
    at org.springframework.util.Assert.notNull(Assert.java:201) ~[spring-core-5.3.16.jar:5.3.16]
    at org.springframework.security.web.access.DefaultWebInvocationPrivilegeEvaluator.<init>(DefaultWebInvocationPrivilegeEvaluator.java:54) ~[spring-security-web-5.6.2.jar:5.6.2]
    at org.springframework.security.config.annotation.web.builders.WebSecurity.getRequestMatcherPrivilegeEvaluatorsEntry(WebSecurity.java:338) ~[spring-security-config-5.6.2.jar:5.6.2]
    at org.springframework.security.config.annotation.web.builders.WebSecurity.performBuild(WebSecurity.java:305) ~[spring-security-config-5.6.2.jar:5.6.2]
    at org.springframework.security.config.annotation.web.builders.WebSecurity.performBuild(WebSecurity.java:90) ~[spring-security-config-5.6.2.jar:5.6.2]
    at org.springframework.security.config.annotation.AbstractConfiguredSecurityBuilder.doBuild(AbstractConfiguredSecurityBuilder.java:305) ~[spring-security-config-5.6.2.jar:5.6.2]
    at org.springframework.security.config.annotation.AbstractSecurityBuilder.build(AbstractSecurityBuilder.java:38) ~[spring-security-config-5.6.2.jar:5.6.2]

直到现在我都不需要 AccessDecisionManager bean,一切都像这样运行得很好:

@Configuration
@EnableWebSecurity
open class OpenApiSecurityConfig() : WebSecurityConfigurerAdapter() {

    override fun configure(http: HttpSecurity) {
        http.requestMatchers()
            .antMatchers("/docs")
            .and()
            .addFilter(OpenApiFilter(authService))
    }

    open class OpenApiFilter(private val authService: AuthService) : FilterSecurityInterceptor() {
        override fun doFilter(request: ServletRequest, response: ServletResponse, chain: FilterChain) {
            if (userAuthorized()) {
                chain.doFilter(request, response)
            } else {
                throw AccessDeniedException("Forbidden.")
            }
        }
    }
}

所以我想这只是某种新要求。我将配置添加为:

@Configuration
@Import(AccessManager::class)
@EnableWebSecurity
open class OpenApiSecurityConfig() : WebSecurityConfigurerAdapter() { … }
… 
@Configuration
open class AccessManager : AccessDecisionManager {
    override fun decide(authentication: Authentication, `object`: Any?, configAttributes: MutableCollection<ConfigAttribute>?) {}
    override fun supports(attribute: ConfigAttribute?): Boolean = false
    override fun supports(clazz: Class<*>?): Boolean = false
}

但是没有效果。

  1. 是否可以避免 AccessManager 的需要?
  2. 正确的实例化方法是什么?

此问题源于创建自定义 FilterSecurityInterceptor
此过滤器不打算在过滤器链中替换。
最好创建不同类型的自定义过滤器并将其插入 FilterSecurityInterceptor 之前。例如,它可以扩展 OncePerRequestFilter 而不是抛出 AccessDeniedException 如果用户未经授权,它可以简单地 return.