所以我正在开发我的第一个全栈应用程序(spring-boot-rest API和Vue.js前端(,我在使用sonarqube时遇到了一个问题。我的儿子发出以下警告:
请确保禁用Spring Security的CSRF保护是安全的
它来自这个文件:
@Configuration
@AllArgsConstructor
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class
WebSecurityConfig extends WebSecurityConfigurerAdapter {//provides security for endpoints
@Autowired
private JwtAuthenticationEntryPoint jwtAuthenticationEntryPoint;
@Autowired
private UserDetailsService jwtUserDetailsService;
@Autowired
private JwtRequestFilter jwtRequestFilter;
private final AccountService accountService;
private final BCryptPasswordEncoder bCryptPasswordEncoder;
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
// configure AuthenticationManager so that it knows from where to load
// user for matching credentials
// Use BCryptPasswordEncoder
auth.userDetailsService(jwtUserDetailsService).passwordEncoder(bCryptPasswordEncoder);
}
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf()/*.disable()*/.and()//So we can send post requests without being rejected(if we using form based indication we want to enable this)
.authorizeRequests()
.antMatchers("/login", "/authenticate","/register", "/register/**")
.permitAll()//any request that goes trough that end point we want to allow.
.anyRequest()
.authenticated().and().exceptionHandling().authenticationEntryPoint(jwtAuthenticationEntryPoint)
.and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and().addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class);
http.cors();
http.logout().permitAll();
http.logout().logoutSuccessHandler((new HttpStatusReturningLogoutSuccessHandler(HttpStatus.OK)));
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(daoAuthenticationProvider());
}
@Bean
public DaoAuthenticationProvider daoAuthenticationProvider() {
DaoAuthenticationProvider provider =
new DaoAuthenticationProvider();
provider.setPasswordEncoder(bCryptPasswordEncoder);
provider.setUserDetailsService(jwtUserDetailsService);
return provider;
}
}
更具体地说,这段代码:
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf()/*.disable()*/.and()//So we can send post requests without being rejected(if we using form based indication we want to enable this)
.authorizeRequests()
.antMatchers("/login", "/authenticate","/register", "/register/**")
.permitAll()//any request that goes trough that end point we want to allow.
.anyRequest()
.authenticated().and().exceptionHandling().authenticationEntryPoint(jwtAuthenticationEntryPoint)
.and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and().addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class);
http.cors();
http.logout().permitAll();
http.logout().logoutSuccessHandler((new HttpStatusReturningLogoutSuccessHandler(HttpStatus.OK)));
当我删除第一个.and()
并使用disable(现在已经注释掉了(时,我的程序可以工作,但我想找到一个解决方案,让我启用.csrf()
(我知道它是标准启用的(,并且我的登录不再给我401错误。
提前感谢!
显然,您正在使用JWT对请求进行身份验证。这通常不涉及cookie(令牌通常作为请求头发送(。如果是这种情况(JWT在标头中收到(,您可以忽略Sonarqube警告,您不需要CSRF保护。
原因是CSRF是一种攻击,当受害者访问恶意网站时,攻击者利用受害者用户的现有会话。这是基于浏览器随请求发送的cookie,仅取决于目的地,而不是来源(即attaker.com上的javascript可以向victim.com发出请求,用户对victim.com的cookie将自动发送(。如果请求标头用于传输令牌,则攻击者在其恶意域中无法访问该令牌。
如果你仍然想让它发挥作用(例如,因为你的JWT确实是从cookie中收到的(,你必须从你的前端(VueJS(发送正确的CSRF令牌,并发送每个不是get的请求,所以这是对你的前端的改变,而不是对你的后端的改变。