springsecurity如何防御CSRF攻击


quickstart

  • 一SecurityConfig继承WebSecurityConfigurerAdapter
    • 二定义用户接口加入到spring容器中
      • 三spring security内部的流程

一SecurityConfig继承WebSecurityConfigurerAdapter 【springsecurity如何防御CSRF攻击】先进行配置,现在使用这套工具都是先定义好类
@Override protected void configure(HttpSecurity http) throws Exception { .formLogin() .loginPage("/authentication/require")//指定没有认证时跳转到的认证url .loginProcessingUrl("/authentication/form")//提交登录表单的url .and() .authorizeRequests() .antMatchers("/authentication/require").permitAll() .anyRequest() .authenticated() .and() .csrf().disable(); }

这里简单说明一下就是使用了链式编程的技巧每次都返回一个this的对象进行操作,and()方法就是这样使用。
对于这个配置类简单说一下用法
SecurityConfig继承自WebSecurityConfigurerAdapter,重写里面的configure(HttpSecurity http)这个方法,配置好需要认证的登录url,以及提交表单的url,这里除了登录url不需要认证之外,其他的url都需要认证才能访问,并且formLogin表名这是一个表单提交,loginprocessingUrl中是设置的提交登录表单的url。
当然你使用HttpSecurityConfigurerAdapter也是可以的,但是从使用范围来看,还是web这个比较宽。
二定义用户接口加入到spring容器中 继承一个UserDetailSevice接口并且加入到容器中,实现loadUserByUsername方法,里面的逻辑通常是从数据库查找出对应用户名的密码然后构造一个UserDetail对象,spring security会根据返回的这个带有正确用户信息的对象和前台传过来的用户名密码进行比对来判断是否认证通过。
/** * 表单登录的时候会调用loadUserByUsername来验证前端传过来的账号密码是否正确 */ @Component public class MyUserDetailService implements UserDetailsService { private Logger logger = LoggerFactory.getLogger(MyUserDetailService.class); @Autowired private PasswordEncoder passwordEncoder; @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { logger.info("登录用户名===========" + username); //这里需要去数据库查询用户的账号密码来比对是否正确,以及账号是否过期等等 String password = passwordEncoder.encode("123456"); logger.info("数据库密码是==============" + password); return new User(username, password, true, true, true, true, AuthorityUtils.commaSeparatedStringToAuthorityList("admin")); } }

访问一个一个http://localhost:8080/user的接口,那么spring security 发现配置中这个接口是需要拦截的,并且当前的请求还没有通过认证,就会重定向到loginPage设置的这个接口或者页面中去。当我们调用loginProcessingUrl这个接口去提交表单的时候,如果通过了认证,那么就会重定向到原来我们想要访问的接口中去了,如果认证不成功,那么就出现认证失败等信息。
三spring security内部的流程
springsecurity如何防御CSRF攻击
文章图片

这里的流程还是挺好理解的,相信拦截器模式大家都不陌生,而这里就类似拦截器的实现过程
spring security内部其实是通过一个过滤器链来实现认证流程的,比如说这里的UsernamePasswordAuthenticationFilter就是拦截我们通过表单提交接口提交的用户名和密码,如果是Basic提交的话,就会被BasicAuthenticationFilter拦截,最后的橙色FilterSecurityInterceptor是首先判断我们当前请求的url是否需要认证,如果需要认证,那么就看当前请求是否已经认证,是的话就放行到我们要访问的接口,否则重定向到认证页面。

    推荐阅读