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 來聲明任何安全配置,并且您可以在不同的位置執行此操作。
但請注意,如果發生沖突,這可能會覆蓋彼此的配置。
添加回答
舉報