【发布时间】:2023-02-04 04:00:28
【问题描述】:
我已将我的 Spring Boot 项目升级到 Spring Boot 3。
我还更新了 WebSecurityConfig,它现在看起来像这样:
// imports...
@Configuration
@EnableWebSecurity
@RequiredArgsConstructor
public class CustomWebSecurityConfig {
final UserDetailsServiceImpl userDetailsService;
private final AuthEntryPointJwt unauthorizedHandler;
private final PasswordEncoder passwordEncoder;
@Bean
public AuthTokenFilter authenticationJwtTokenFilter() {
return new AuthTokenFilter();
}
@Bean
public DaoAuthenticationProvider authenticationProvider() {
DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
authProvider.setUserDetailsService(userDetailsService);
authProvider.setPasswordEncoder(passwordEncoder);
return authProvider;
}
@Bean
public AuthenticationManager authenticationManager(AuthenticationConfiguration authConfig) throws Exception {
return authConfig.getAuthenticationManager();
}
/**
* Sets up a chain of antmatchers specifying what permissions and roles have access to which resources.
*
* @param http Injected HttpSecurity object
* @return Chain of Security filters
* @throws Exception Currently throws general exception
*/
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http.cors().and().csrf().disable()
// https://stackoverflow.com/questions/74447778/spring-security-in-spring-boot-3
.authorizeHttpRequests(requests -> requests.requestMatchers("/api/auth/**").permitAll()
.requestMatchers("/api/test/**").permitAll()
.requestMatchers("/").permitAll()
.requestMatchers("/index.html").permitAll()
.requestMatchers("/favicon.ico").permitAll()
.requestMatchers("/main.js").permitAll()
.requestMatchers("/polyfills.js").permitAll()
.requestMatchers("/runtime.js").permitAll()
.requestMatchers("/styles.css").permitAll()
.requestMatchers("/vendor.css").permitAll()
.requestMatchers("/assets/**").permitAll()
.requestMatchers("/error").permitAll()
.requestMatchers("/**").permitAll()
.anyRequest().authenticated());
http.exceptionHandling().authenticationEntryPoint(unauthorizedHandler).and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
http.authenticationProvider(authenticationProvider());
http.addFilterBefore(authenticationJwtTokenFilter(), UsernamePasswordAuthenticationFilter.class);
return http.build();
}
}
这是带有@PreAuthorize 的示例端点:
// imports...
@RestController
@RequestMapping("/api/test")
public class TestController {
@GetMapping("/all")
public String allAccess() {
return "Public Content.";
}
@GetMapping("/user")
@PreAuthorize("hasRole('USER') or hasRole('MODERATOR') or hasRole('ADMIN')")
public String userAccess() {
return "User Content.";
}
@GetMapping("/mod")
@PreAuthorize("hasRole('MODERATOR')")
public String moderatorAccess() {
return "Moderator Board.";
}
@GetMapping("/admin")
@PreAuthorize("hasRole('ADMIN')")
public String adminAccess() {
return "Admin Board.";
}
}
我为这个用例编写的测试部分失败,因为登录用户可以访问所有端点,但默认情况下只有“USER”-Role。 这两个测试失败:
@Test
@DisplayName("Give user no token and forbid access")
@WithMockUser(roles = "USER")
void givenUserToken_whenGetSecureRequest_thenForbidden() throws Exception {
mockMvc.perform(get("/api/test/mod"))
.andExpect(status().isForbidden());
}
@Test
@DisplayName("Give user no token and forbid access v.2")
@WithMockUser(roles = "USER")
void givenUserToken_whenGetSecureRequest_thenForbidden2() throws Exception {
mockMvc.perform(get("/api/test/admin"))
.andExpect(status().isForbidden());
}
我阅读了一些关于@EnableMethodSecurity 的内容,但我还没有找到使用它和修复@PreAuthorize 不起作用的方法
【问题讨论】:
标签: spring-boot spring-security