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

调用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());
    }
	
}

总结

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

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring Security提供了一种简单的方式来实现短信登录功能。下面是一个基本的示例配置: 1. 首先,确保你的项目中已经引入了Spring Security依赖。 2. 创建一个用于处理短信登录的控制器。例如,你可以创建一个`SmsLoginController`类。 ```java @RestController public class SmsLoginController { @PostMapping("/login/sms") public ResponseEntity<String> loginWithSms(@RequestParam("phoneNumber") String phoneNumber, @RequestParam("smsCode") String smsCode) { // 在这里编写验证逻辑和登录逻辑 // 验证手机号码和短信验证码是否匹配,并且登录用户 return ResponseEntity.ok("登录成功"); } } ``` 3. 创建一个Spring Security配置类,并进行相应的配置。例如,你可以创建一个`SecurityConfig`类。 ```java @Configuration @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http .authorizeRequests() .antMatchers("/login/sms").permitAll() // 允许短信登录接口的匿名访问 .anyRequest().authenticated() // 其他请求需要认证 .and() .formLogin() .disable() // 禁用表单登录 .logout() .disable() // 禁用注销功能 .csrf() .disable(); // 禁用CSRF保护(仅供示例,实际项目需要启用CSRF保护) } } ``` 4. 设置短信登录的配置。可以通过实现`AuthenticationProvider`接口来自定义短信登录的验证逻辑。例如,你可以创建一个`SmsCodeAuthenticationProvider`类。 ```java @Component public class SmsCodeAuthenticationProvider implements AuthenticationProvider { @Override public Authentication authenticate(Authentication authentication) throws AuthenticationException { String phoneNumber = authentication.getPrincipal().toString(); String smsCode = authentication.getCredentials().toString(); // 在这里编写验证逻辑,例如调用短信服务商的接口校验短信验证码 // 校验通过后,创建一个认证成功的Authentication对象 SmsCodeAuthenticationToken authenticatedToken = new SmsCodeAuthenticationToken(phoneNumber, null); authenticatedToken.setDetails(authentication.getDetails()); return authenticatedToken; } @Override public boolean supports(Class<?> authentication) { return (SmsCodeAuthenticationToken.class.isAssignableFrom(authentication)); } } ``` 5. 注册短信登录配置。在上述的`SecurityConfig`类中,通过重写`configure`方法注册短信登录的配置。 ```java @Configuration @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { @Autowired private SmsCodeAuthenticationProvider smsCodeAuthenticationProvider; @Override protected void configure(HttpSecurity http) throws Exception { // 省略其他配置... // 注册短信登录的配置 SmsCodeAuthenticationFilter smsCodeAuthenticationFilter = new SmsCodeAuthenticationFilter(); smsCodeAuthenticationFilter.setAuthenticationManager(http.getSharedObject(AuthenticationManager.class)); smsCodeAuthenticationFilter.setAuthenticationSuccessHandler(new SimpleUrlAuthenticationSuccessHandler()); smsCodeAuthenticationFilter.setAuthenticationFailureHandler(new SimpleUrlAuthenticationFailureHandler()); http.authenticationProvider(smsCodeAuthenticationProvider) .addFilterAfter(smsCodeAuthenticationFilter, UsernamePasswordAuthenticationFilter.class); } } ``` 现在,你可以使用`/login/sms`接口来进行短信登录了。向该接口发送POST请求,携带手机号码和短信验证码作为参数即可实现短信登录功能。请注意,以上只是一个简单的示例,实际项目中可能需要进行更多的配置和处理。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值