调用Spring Security下接口 get 可以成功,而post失败

本文探讨了在SpringSecurity环境下,GET请求成功而POST请求失败的问题,深入分析了原因在于CSRF跨站防护的默认开启。提供了三种解决方案,包括关闭CSRF、配置豁免URL以及重写过滤器,帮助开发者有效解决POST请求被拦截的问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

调用Spring Security下接口 get 可以成功,而post失败

问题描述

调用第三方接口的时候,因为接口是在Spring Security权限项目路下的,所以会出现只有get成功而post失败的情况。

原因

springSecurity会对所有http请求以及所有静态资源进行拦截,一般情况下静态资源以及http请求则不需要进行拦截。

		http.authorizeRequests()
				.antMatchers("/api/**", "/css/**", "/js/**", "/fonts/**", "/images/**")
				.permitAll()
				.anyRequest()
				.authenticated()

以上是基本配置,就是允许拦截通过。
但是springSecurity在2.0之后会默认自动开启CSRF跨站防护,而一旦开启了CSRF,所有经的http请求以及资源都被会CsrfFilter拦截,仅仅GET|HEAD|TRACE|OPTIONS这4类方法会被放行,也就是说post,delete等方法依旧是被拦截掉的,限制了除了get以外的大多数方法,报出403错误。

解决方案

查阅了一些帖子,最多的就是关闭CSRF或者重写过滤器。当然方法很多,毕竟跨域的作用也很大。所以就有ignoring方法的使用了。它是完全绕过spring security的所有filter的。罗列以下三种方式:

1.法一

直接配置configure(HttpSecurity http),直接关闭,这样的话都不会被拦截,所以还是不建议这样做

http.csrf().disable();

2.法二

通过配置方形的url,这样就不会拦截

http.csrf().ignoringAntMatchers("/druid/*");

3.法三

单独拿出来配置,与前两者不同,配置类中再次重写configure方法

@Override
	public void configure(WebSecurity web){
		web.ignoring().antMatchers("/api/**", "/css/**", "/js/**", "/fonts/**", "/images/**", "/lib/**","/ws/**");
	}

完整配置展示

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

	@Autowired
	private MyAuthenctiationSuccessHandler myAuthenctiationSuccessHandler;
	
	@Override
	protected void configure(HttpSecurity http) throws Exception {
		http.headers().frameOptions().disable(); //用于加载页面iframe部分
		http.authorizeRequests()
				.antMatchers("/druid/**","/getVerify","/css/**", "/js/**", "/fonts/**")
				.permitAll() // 允许所有用户访问
				.anyRequest().authenticated()
				.and()
			.formLogin() // 定义当需要用户登录时候,转到的登录页面
				.loginPage("/login") 
				.failureUrl("/login?error=true")
				.defaultSuccessUrl("/index")//成功登录后跳转页面
				.successHandler(myAuthenctiationSuccessHandler)
				.permitAll()
				.and()
			.sessionManagement()
				.invalidSessionUrl("/login")
				.and()
			.requestCache().disable()
			.logout()
				.logoutSuccessUrl("/login") //成功退出后跳转到的页面
				.permitAll()//退出
				.and()
			.csrf()//.disable();
			.ignoringAntMatchers("/pushLog/**","/druid/**");
	}
	
	@Override
	public void configure(WebSecurity web){
		web.ignoring().antMatchers("/swagger-ui.html","/doc.html", "/v2/**", "/webjars/**", "/swagger-resources/**");
	}
	
	@Bean
    public AuthenticationProvider authenticationProvider() {
        AuthenticationProvider provider = new MyAuthenticationProvider();
        return provider;
    }
	
	@Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.authenticationProvider(authenticationProvider());
    }
	
}

总结

这样的方式也比较直接简单,本文也没有对源码进行阐述,以后会不上,也是因为正好遇到这个问题,写出来大家一起学习吧,对于接口的认证则需要自己在接口中进行验证了。有什么想法,或者不对的欢迎留言啊

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值