Description

When using @EnableReactiveMethodSecurity the "ReactiveAuthorizationManagerMethodSecurityConfiguration" is loaded. This contains a @Bean which defines a DefaultMethodSecurityExpressionHandler. This class defines a default DenyAllPermissionEvaluator.

This appears to be result in all methods which use the permission evaluator to be denied.

To Reproduce

@EnableReactiveMethodSecurity
@Configuration
class WebFluxAclConfiguration {

    @Bean
    fun aclPermissionEvaluator(aclService: AclService): AclPermissionEvaluator {
        return AclPermissionEvaluator(aclService)
    }
}

@Service
class TestService {

    @PostAuthorize("hasPermission(returnObject, 'read')")
    fun getDocument(id: Int): Mono<Document> {
        return Mono.just(Document(id))
    }
}

Expected behavior The DefaultMethodSecurityExpressionHandler should find the AclPermissionEvaluator as an available bean and use it

Sample

https://github.com/grantlittle/security-demo

Comment From: grantlittle

As a workaround, I've had to add the following configuration

@Configuration
class WebFluxPermissionEvaluatorConfiguration(
    @Autowired(required = false)
    private val methodSecurityExpressionHandler: DefaultMethodSecurityExpressionHandler?, // Injecting existing handler
    private val aclService: MutableAclService
) {
    @PostConstruct
    fun configureExistingMethodSecurityExpressionHandler() {
        if (methodSecurityExpressionHandler != null) {
            val permissionEvaluator = AclPermissionEvaluator(aclService)
            methodSecurityExpressionHandler.setPermissionEvaluator(permissionEvaluator)
            methodSecurityExpressionHandler.setPermissionCacheOptimizer(AclPermissionCacheOptimizer(aclService))
        }
    }
}

Comment From: jzheaux

This is similar enough to #11598 that I'll close this and let's continue the conversation over there.