当我启用 csrf 时,为什么会出现 401 错误?

5

我正在开发我的第一个全栈应用程序(使用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错误。

提前致谢!

1个回答

8

显然,您正在使用JWT来进行请求身份验证。 这通常不涉及Cookie(令牌通常作为请求头发送)。 如果您的情况是这样的(JWT在标头中接收),则可以忽略Sonarqube警告,您不需要CSRF保护。

原因是CSRF是一种攻击,攻击者利用受害用户的现有会话(当受害者访问恶意网站时)。 这基于浏览器发送的cookie仅依赖于目标,而不是源(即攻击者.com上的Javascript可以向victim.com发出请求,并且用户的victim.com cookie将自动发送)。 如果请求头用于传输令牌,则攻击者无法在其恶意域上访问该令牌。

如果您仍想使其工作(例如,您的JWT确实是从Cookie中接收到的),则必须通过VueJS从前端发送正确的CSRF令牌,以便对于每个非get请求都会附带该令牌,这对于您的前端而言是一个变化,而不是后端。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接