获取错误,指出在 SPring Boot 2.1.1 中扩展全局方法安全配置时已定义"methodSecurityInterceptor"



我正在重写GlobalMethodSecurityConfiguration类,但只有一个方法:protected MethodSecurityExpressionHandler createExpressionHandler()

当我尝试运行应用程序时,我得到:

描述:

无法注册类路径资源[org/springframework/security/config/annotation/method/config/GlobalMethodSecurityConfiguration.class]中定义的bean"methodSecurityInterceptor"。已经在类路径资源[com/testing/config/MyMethodSecurityConfig.class]中定义了具有该名称的bean,并且禁用了重写。

行动:

考虑重命名其中一个bean,或者通过设置spring.main.allow-bean definition override=true 来启用覆盖

配置类

当我没有覆盖基本方法时,它为什么要这样做?如何在不出现此错误的情况下覆盖MethodSecurityExpressionHandler

import com.testing.AadMethodSecurityExpressionHandler;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.access.expression.method.MethodSecurityExpressionHandler;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.method.configuration.GlobalMethodSecurityConfiguration;
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
public class MyMethodSecurityConfig extends GlobalMethodSecurityConfiguration
{
@Override
protected MethodSecurityExpressionHandler createExpressionHandler()
{
return new MyMethodSecurityExpressionHandler();
}
}

表达式处理程序

import org.aopalliance.intercept.MethodInvocation;
import org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler;
import org.springframework.security.access.expression.method.MethodSecurityExpressionOperations;
import org.springframework.security.core.Authentication;
public class MyMethodSecurityExpressionHandler extends DefaultMethodSecurityExpressionHandler
{
@Override
protected MethodSecurityExpressionOperations createSecurityExpressionRoot(Authentication authentication, MethodInvocation invocation)
{
MyMethodSecurityExpressionRoot root = new MyMethodSecurityExpressionRoot( authentication );
root.setPermissionEvaluator( getPermissionEvaluator() );
root.setTrustResolver( getTrustResolver() );
root.setRoleHierarchy( getRoleHierarchy() );
return root;
}
}

表达式根

import org.springframework.security.access.expression.SecurityExpressionRoot;
import org.springframework.security.access.expression.method.MethodSecurityExpressionOperations;
import org.springframework.security.core.Authentication;
public class MyMethodSecurityExpressionRoot extends SecurityExpressionRoot implements MethodSecurityExpressionOperations
{
private Object filterObject;
private Object returnObject;
private Object target;
public MyMethodSecurityExpressionRoot(Authentication a)
{
super( a );
}
@Override
public void setDefaultRolePrefix(String defaultRolePrefix)
{
//Simple test to see if this works
super.setDefaultRolePrefix( "" );
}
public void setFilterObject(Object filterObject)
{
this.filterObject = filterObject;
}
public Object getFilterObject()
{
return filterObject;
}
public void setReturnObject(Object returnObject)
{
this.returnObject = returnObject;
}
public Object getReturnObject()
{
return returnObject;
}
void setThis(Object target)
{
this.target = target;
}
public Object getThis()
{
return target;
}
}

对于任何遇到这个问题的人,解决方案是删除我在安装的WebSecurityConfigurer上配置的重复@EnableGlobalMethodSecurity注释。

我通过合并两个配置类解决了问题

@EnableWebSecurity
public class SecurityConfig {
@Configuration
@RequiredArgsConstructor
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
public static class GlobalMethodSecurityConfig extends GlobalMethodSecurityConfiguration {

private final ApplicationContext applicationContext;
@Override
protected MethodSecurityExpressionHandler createExpressionHandler() {
var expressionHandler = new CustomMethodSecurityExpressionHandler();
expressionHandler.setApplicationContext(applicationContext);
return expressionHandler;
}
}
@Configuration
public static class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
//http config
}
}
}

如Spring文档中的建议

下面的解决方案对我有效。

在application.yml或application.properties 中设置此键和值

application.yml弹簧:
main:允许bean定义重写:真正的

application.properties

spring.main.allow-bean定义override=true

最新更新