由于我不是安全Maven,我在这里再次向你寻求建议,重新保护CSRF处理,在我的情况下,通过Spring Boot 配置。
我有以下设置:
安全配置
@EnableWebSecurity
public class WebSecurityConfig {
private static final String ADMIN = "ADMIN";
private static final String USER = "USER";
@Bean
public InMemoryUserDetailsManager userDetailsService() {
UserDetails user = User
.withUsername("user")
.password(passwordEncoder().encode("password"))
.roles(USER)
.build();
UserDetails admin = User
.withUsername("admin")
.password(passwordEncoder().encode("password"))
.roles(ADMIN)
.build();
return new InMemoryUserDetailsManager(user, admin);
}
@Bean
public BCryptPasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Bean
//@Order(1) // Order is required incase you create multiple filterchains for security
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
return http
.authorizeRequests()
.antMatchers("/auth/login").permitAll()
.antMatchers("/books/special").hasAnyRole("ADMIN")
.antMatchers("/books/**").hasAnyRole("USER", "ADMIN")
.anyRequest().authenticated()
.and()
.httpBasic()
.and()
.logout().logoutRequestMatcher(new AntPathRequestMatcher("/auth/logout"))
.and()
.csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
.and()
.build();
}
}
休息控制器
@RestController
@RequestMapping("/auth")
public class AuthenticationController {
@GetMapping("/login")
public String login() {
return "You are logged in";
}
@PostMapping("/logout")
public String logout() {
return "You are logged out";
}
}
@RestController
@RequestMapping("/books")
public class BookController {
@GetMapping
public List<String> getAllBooks() {
return Arrays.asList("Book1", "Book2", "Book3", "Book4", "Book5");
}
@GetMapping("/special")
public String getSpecialBook() {
return "Special book";
}
@PostMapping
public String createBook() {
return "Book6";
}
@PatchMapping
public String updateBook() {
return "Book6 is now book7";
}
@DeleteMapping("/special")
public String deleteBook() {
return "Some book was deleted";
}
}
我目前正在使用Postman来验证身份验证部分是否按预期运行。
我从Spring安全性生成的cookie中获取XSRF-TOKEN,并在POST / PATCH / DELETE的头文件中使用它(不用于GET方法)
POST / PATCH / DELETE按预期工作,如果X-XSRF-TOKEN不存在,我们将得到403禁止,如果存在,我将从控制器接收字符串。
我有点困惑的问题来了。
似乎只要我的应用程序通过调用ex /login的用户的身份验证
用户的身份验证保存在某个地方,我现在可以访问所有的GET端点,而无需任何进一步的身份验证。即使我重新启动应用程序,也不需要重新进行身份验证。
只有在明确调用“/logout”端点之后,我才需要在调用GET请求时再次进行身份验证。
在spring文档中,他们说我们需要为所有操作请求(POST/PUT/PATCH/DELETE)显式设置X-XSRF-TOKEN,但是他们并没有真正提到应该如何处理GET请求,除了
我们可以放宽期望,只要求为每个更新状态的HTTP请求提供令牌。这样做是安全的,因为同源策略确保恶意站点无法读取响应。此外,我们不希望在HTTP GET中包含随机令牌,因为这可能导致令牌泄漏。
我希望这不是太混乱,读起来像写起来一样,我很高兴,如果人们能给我提供理论,这样我就可以扩展我的研究,因为我觉得这可能会导致一些漏洞,我还没有发现。
谨致问候
1条答案
按热度按时间rbl8hiat1#
代努姆先生在评论中或多或少地回答了我的问题。
我的应用程序行为的原因是SessionManagement没有设置为无状态,因此为登录用户保留了一个会话,并在每次请求时自动从 Postman 发送。
为了对每个请求进行身份验证,我需要在WebSecurityConfig中添加以下行:
这将删除我收到的JSESSIONID cookie,并在每次请求时刷新我的CSRF令牌。
之前,我的CSRF令牌在每个请求上都是相同的,这可能是由于已识别的会话。
感谢您帮助解开谜团!