在我的 Spring Boot 應用程式中,我正在嘗試洗掉使用已棄用的類 WebSecurityConfigurerAdapter 來配置安全性,如本博文中所建議的那樣。
以前,我的安全配置類是這樣的:
@EnableWebSecurity
@EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled = true, jsr250Enabled = true)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// the filter classes constructor arguments are
// @Autowired fields of SecurityConfiguration
var jwtAuthenticationFilter = new JwtAuthenticationFilter(
authenticationManager(),
authenticationAuditService,
jwtTokenService,
roleResolver,
objectMapper,
messageSourceAccessor,
roleActivityService);
var jwtAuthorisationFilter = new JwtAuthorisationFilter(jwtTokenService, userRepository, userRoleRepository);
http.cors().and().csrf().disable().authorizeRequests()
.anyRequest().authenticated().and()
.addFilter(jwtAuthenticationFilter)
.addFilterAfter(jwtAuthorisationFilter, BasicAuthenticationFilter.class)
.addFilterBefore(filterChainExceptionHandler, LogoutFilter.class)
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS);
}
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
}
這實際上是創建 2 個 Spring Security 過濾器并將它們添加到過濾器鏈中。洗掉 WebSecurityConfigurerAdapter 后,該類現在如下所示:
@EnableWebSecurity
@EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled = true, jsr250Enabled = true)
public class SecurityConfiguration {
@Bean
public SecurityFilterChain configure(HttpSecurity http) throws Exception {
// the filter classes constructor arguments are
// @Autowired fields of SecurityConfiguration
var jwtAuthenticationFilter = new JwtAuthenticationFilter(
authenticationConfiguration.getAuthenticationManager(),
authenticationAuditService,
jwtTokenService,
roleResolver,
objectMapper,
messageSourceAccessor,
roleActivityService);
var jwtAuthorisationFilter = new JwtAuthorisationFilter(jwtTokenService, userRepository, userRoleRepository);
http.cors().and().csrf().disable().authorizeRequests()
.anyRequest().authenticated().and()
.addFilter(jwtAuthenticationFilter)
.addFilterAfter(jwtAuthorisationFilter, BasicAuthenticationFilter.class)
.addFilterBefore(filterChainExceptionHandler, LogoutFilter.class)
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS);
return http.build();
}
}
但是,在進行這些更改之后,許多測驗都失敗了。這似乎是因為不再加載安全過濾器。例如,在進行上述更改之前,以下測驗通過
@WebMvcTest(MyController.class)
@WithMockUser
public class MyControllerTests {
@Autowired
private MyController controller;
@Test
void deleteRole_ShouldThrowsAccessDeniedException_WhenUserHasInvalidRole() {
assertThrows(AccessDeniedException.class, () -> this.controller.deleteRole(UUID.randomUUID()));
}
}
正在測驗的控制器方法/動作是:
@PreAuthorize("hasAuthority('SYSTEM_ADMIN')")
public void deleteRole(@PathVariable UUID id) {
// implementation omitted
}
看來測驗現在失敗了,因為@PreAuthorize不存在實作定義的角色檢查所需的安全過濾器。
有沒有辦法在測驗運行時強制加載安全配置?
uj5u.com熱心網友回復:
你需要注釋你的測驗
@Import(SecurityConfiguration.class)
背景關系切片的過濾器@WebMvcTest自動包含WebSecurityConfigurerAdapter帶有注釋的實作,@Component但它不掃描@Bean配置類的工廠方法。
Spring Boot 2.7 的發行說明中也提到了這一點。這里有更多關于討論的細節:https ://github.com/spring-projects/spring-boot/issues/31162
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/490380.html
