spring-security 在SPring Boot 2.1.1中扩展全局方法安全配置时,出现错误,指出“方法安全拦截器”已定义

30byixjq  于 2022-11-11  发布在  Spring
关注(0)|答案(3)|浏览(144)

我重写了GlobalMethodSecurityConfiguration类,但只重写了一个方法:protected MethodSecurityExpressionHandler createExpressionHandler() .
当我尝试运行应用程序时,我得到:
说明:
无法注册在类路径资源[org/springframework/security/config/annotation/method/configuration/GlobalMethodSecurityConfiguration.class]中定义的Bean 'methodSecurityInterceptor'。已在类路径资源[com/testing/config/MyMethodSecurityConfig.class]中定义了具有该名称的Bean,并且已禁用覆盖。
动作:
请考虑重命名其中一个Bean,或通过设置spring.main.allow-bean-definition-overriding=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;
    }
}
kdfy810k

kdfy810k1#

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

nzrxty8p

nzrxty8p2#

我通过合并两个配置类来解决

@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文档中所建议的

rlcwz9us

rlcwz9us3#

下面的解决方案对我很有效。
在应用程序中设置此键和值。yml或application.properties
应用程序.ymlSpring:
main:允许Bean定义覆盖:真的
application.properties
spring.main.允许Bean定义覆盖=true

相关问题