1 回答
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 来声明任何安全配置,并且您可以在不同的位置执行此操作。
但请注意,如果发生冲突,这可能会覆盖彼此的配置。
添加回答
举报