为什么在启用csrf时会出现401错误?

v64noz0r  于 2021-07-26  发布在  Java
关注(0)|答案(1)|浏览(661)

因此,我正在开发我的第一个完整堆栈应用程序(spring boot rest api和vue.js frontend),使用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错误。
提前谢谢!

3b6akqbq

3b6akqbq1#

显然,您正在使用jwts对请求进行身份验证。这通常不涉及cookie(令牌通常作为请求头发送)。如果您的情况是这样的(jwt在报头中收到),您可以忽略sonarqube警告,您不需要csrf保护。
原因是csrf是一种攻击,当受害者访问恶意网站时,攻击者利用受害者用户的现有会话进行攻击。这是基于浏览器随请求发送的Cookie仅取决于目的地,而不是来源地(即,攻击者.com上的javascript可以向受害者.com发出请求,并且用户针对受害者.com的Cookie将自动发送)。如果请求头用于传输令牌,则恶意域上的攻击者无法访问该令牌。
如果您仍然想让它工作(例如,您的jwt确实是从cookie接收到的),那么您必须从前端(vuejs)发送正确的csrf令牌,每个请求都不是get,因此这是对前端的更改,而不是对后端的更改。

相关问题