spring security 身份失效时的异常处理
1、问题说明
Spring Security 当身份失效时,默认的处理方式是跳转首页。但是在前后端分离的情况下,这个方式显然是不行。查阅了一些博客知道了有两种方法解决:
- 需要继承类LoginUrlAuthenticationEntryPoint,并重写commence方法(不推荐)
- 实现AuthenticationEntryPoint,实现commence方法
2、后端配置
1.实现AuthenticationEntryPoint类,实现commence方法
package com.zggk.mas.config;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.AuthenticationEntryPoint;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class MylAuthenticationEntryPoint implements AuthenticationEntryPoint {
@Override
public void commence(HttpServletRequest request, HttpServletResponse response,
AuthenticationException authException) throws IOException, ServletException {
//判是否是ajax请求
if(isAjaxRequest(request)){
//未登录,返回状态码401
response.sendError(HttpServletResponse.SC_UNAUTHORIZED,authException.getMessage());
}else{
//返回首页
response.sendRedirect("/login");
}
}
public static boolean isAjaxRequest(HttpServletRequest request) {
String ajaxFlag = request.getHeader("X-Requested-With");
return ajaxFlag != null && "XMLHttpRequest".equals(ajaxFlag);
}
}
2、security 添加配置
(第24行就是添加配置)
@EnableWebSecurity
public class SysSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private UserService userDetailImpl;
//自定义登录处理类
@Autowired
private LoginValidateAuthProvider loginValidateAuthProvider;
//自定义权限过滤器
/*
* @Autowired private MySecurityMetadataSource mySecurityMetadataSource;
*/
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(loginValidateAuthProvider);
}
@Override
protected void configure(HttpSecurity http) throws Exception {
//配置身份失效时访问接口和跳转路径的处理
http.exceptionHandling().authenticationEntryPoint(new MylAuthenticationEntryPoint());
// 设置静态资源访问权限 http.authorizeRequests().antMatchers("/index/**","/kj/**","/img/**","/login/**","/timeout","/upload/**").permitAll();
// 设置所有请求需要验证
http.authorizeRequests().anyRequest().authenticated();
//自定义登录页
http
.formLogin().loginPage("/login").
loginProcessingUrl("/login")
.defaultSuccessUrl("/index")
.successHandler(new SuccessHandler())
.failureHandler(new FailureHandler()).permitAll()
.and()
.logout()
.logoutUrl("/signout")
.addLogoutHandler(new MyLoginOutHandler())
.deleteCookies("JSESSIONID")
//.and()
// .rememberMe()
// .rememberMeParameter("remeberme")
// .userDetailsService(userDetailImpl)
//允许frame的设置
.and().headers().frameOptions().sameOrigin().
and().sessionManagement().invalidSessionUrl("/timeout")
;
}
public PasswordEncoder getPasswordEncoder() {
return new BCryptPasswordEncoder();
}
}
3、前端ajax配置
为ajax加上error的function
$.ajax({
url: url, //地址
type: cfg.type,//请求类型
data: data,//数据
dataType: 'json',
xhrFields: {
withCredentials: true // 携带跨域cookie
},
crossDomain: true,
beforeSend: function(xhr) {
xhr.setRequestHeader('X-Requested-With','XMLHttpRequest');
},
success: function(res){
//成功的响应
},
error: function(xhr, type, errorThrown){
if(xhr.status == 0){
return layer.alert('无法连接到服务器,请检查网络');
}else if(xhr.status == 401){
return layer.confirm("您当前暂未登录,是否立即登录?", {}, function(){
layer.closeAll();
location.href='/login'; //跳转到登录页面
});
}
......
},
结语
刚刚开始学习Spring Security,如果文中有错误的地方,请指正,万分感谢。
参考文档
1. https://segmentfault.com/a/1190000019906606?utm_source=tag-newest