为了账号安全,请及时绑定邮箱和手机立即绑定

在多个地方配置 Spring Security

在多个地方配置 Spring Security

RISEBY 2022-06-08 17:41:48
我显然可以通过在其方法中实现单个WebSecurityConfigurerAdapter和访问来使用 Spring Security 的全部功能。但这会导致整体实现,并且如果不为此实施自定义措施,就无法跨应用程序模块进行传播。HttpSecurityconfigure因此,可能会想实现多个WebSecurityConfigurerAdapter子类。但这会导致HttpSecurity对象重复,尝试重新配置一些基本方面(例如 csrf),并且无法正确修改已在第一个适配器中配置的内容。即使禁用默认值也无济于事。因此,我的问题是:是否有在独立配置/组件类中指定 http 安全性的 Spring 或 Spring-Boot 方式?(所以 Java 不是 xml 配置)一个例子可能是在链的中间添加一个安全过滤器。另一个更改 csrf(例如会话到 cookie),而单独的另一个类只会保留默认值。
查看完整描述

1 回答

?
哈士奇WWW

TA贡献1799条经验 获得超6个赞

我不认为有这样做的直接方法。但是我们仍然可以在我们的项目架构中强制它这样做。


我们通常从 WebSecurityConfigurerAdapter 为我们的配置覆盖主要有 3 个方法。1. 配置(AuthenticationManagerBuilder auth) 2. 配置(WebSecurity web) 3. 配置(HttpSecurity http)


根据 Spring 安全架构,只能使用一个 WebSecurityConfigurer 实例。


我们可以这样设计: 1. 使用这个规则,我们可以让我们的父项目持有这个 WebsecurityConfigurer 实例。2. 我们可以让 IBaseSecurityConfig 具有以上 3 个方法签名。3. 我们将忽略任何其他 WebsecurityConfigurer 实例,只允许父 WebsecurityConfigurer 实例。4.我们可以将IBaseSecurityConfig抽象实现为BaseSecurityConfig。


就像 Spring 对我们强制实施 WebsecurityConfigurer 一样,您可以在项目模块上强制 BaseSecurityConfig 覆盖任何与安全相关的配置。


我将尝试用一个例子来解释它。


public interface IBaseSecurityConfig {


    void configure(AuthenticationManagerBuilder auth) throws Exception;

    void configure(WebSecurity web) throws Exception;

    void configure(HttpSecurity http) throws Exception;


}



@Configuration

public abstract class BaseSecurityConfig implements IBaseSecurityConfig {


    @Override

    public void configure(AuthenticationManagerBuilder auth) throws Exception {

        // TODO Any defaults


    }


    @Override

    public void configure(WebSecurity web) throws Exception {

        // TODO Any defaults


    }


    @Override

    public void configure(HttpSecurity http) throws Exception {

        // TODO Any defaults


    }

}

现在我们将通过扩展 BaseSecurityConfig 在任何地方声明我们的安全配置。假设我们声明 WebSecurityConfiguration1 如下。


@Configuration

public class WebSecurityConfiguration1 extends BaseSecurityConfig {


    @Override

    public void configure(HttpSecurity http) throws Exception {

        http.authorizeRequests().antMatchers("/css/**", "/js/**", "/admin/**").permitAll().anyRequest().authenticated()

                .and()

                .addFilterBefore(ssoFilter(), BasicAuthenticationFilter.class)

                .formLogin().loginPage("/login").permitAll().and().logout().logoutSuccessUrl("/");

    }

}

现在我们将在其他任何地方声明一个单独的安全配置。让我们称之为 WebSecurtiyConfiguration2。


@Configuration

public class WebSecurtiyConfiguration2 extends BaseSecurityConfig {


    @Override

    public void configure(HttpSecurity http) throws Exception {

        IsSecureFilter i1 = new IsSecureFilter();

        http.addFilterBefore(i1, ChannelProcessingFilter.class);

    }

}

现在我们必须自动配置上述两个声明的安全配置。我们将在我们的父项目中进行,或者您可以说我们将在 SecurityConfig 的实际实例中配置它们,如下所示。


@Configuration

@EnableWebSecurity

public class SecurityConfig extends WebSecurityConfigurerAdapter {



    @Autowired

    private List<IBaseSecurityConfig> securityConfigs;


    @Override

    protected void configure(AuthenticationManagerBuilder auth) throws Exception {

        for(IBaseSecurityConfig secConfig : securityConfigs) {

            secConfig.configure(auth);          

        }

    }


    @Override

    public void configure(WebSecurity web) throws Exception {

        for(IBaseSecurityConfig secConfig : securityConfigs) {

            secConfig.configure(web);

        }


    }


    @Override

    protected void configure(HttpSecurity http) throws Exception {

        System.out.println("CONFIGURING FROM BASE");

        for(IBaseSecurityConfig secConfig : securityConfigs) {

            secConfig.configure(http);

        }

    }

}

现在这是我们的应用程序加载类。我们必须确保没有其他 WebSecurityConfigurerAdapter 加载,只有我们的父实例被加载。我们通过@Component-> 排除过滤器来做到这一点。在@Import 的帮助下,将确保只有我们的实例被加载。


@SpringBootApplication

@EnableCaching

@ComponentScan(excludeFilters = @ComponentScan.Filter(type=FilterType.ASSIGNABLE_TYPE,classes=WebSecurityConfigurerAdapter.class))

@Import(SecurityConfig.class)

public class DemoApplication {


    public static void main(String[] args) {

        SpringApplication.run(DemoApplication.class, args);

    }

}

现在,您已经强制您的架构通过仅扩展 BaseSecurityConfig 来声明任何安全配置,并且您可以在不同的位置执行此操作。


但请注意,如果发生冲突,这可能会覆盖彼此的配置。


查看完整回答
反对 回复 2022-06-08
  • 1 回答
  • 0 关注
  • 250 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信