Spring boot + thymeleaf + Shiro 会话过期返回登录界面片段之解决方案

Spring boot + thymeleaf + Shiro 会话过期返回登录界面片段之解决方案
解决方案的主导思想是:检测当会话过期时,判断是否为ajax请求,若是ajax请求,则将该url请求结果的状态置为401,并且不保存此次访问请求的url,当前端检测到访问结果为401时,跳转至登录界面,用户可顺利进行账户密码的输入并完成登录。
在此主导思想下将会遇到以下几个问题:
1.前端ajax请求完成后的统一处理问题;
2.后端会话过期的检测问题;
3.对封装后的ajax进行请求完成后的统一处理问题;
4.对临时添加的界面元素执行ajax请求的统一处理问题;
5.在spring boot框架下对shiro自定义的Formauthenticationfilter表单验证器的继承问题。
会话超时时执行相关操作,出现问题如下: 会话超时时出现的页面
会话超时时执行相关操作,问题解决目标如下:
问题解决的目标
针对问题1,前端ajax请求后的统一处理问题解决如下:

/**
* 设置未来(全局)的AJAX请求默认选项
* 主要设置了AJAX请求遇到Session过期的情况
*/
$.ajaxSetup({
complete: function(xhr,status) {
if(xhr.status == 401) {
var top = getTopWinow();
top.location.href = '/login';
}
}
});

/**
* 在页面中任何嵌套层次的窗口中获取顶层窗口
* @return 当前页面的顶层窗口对象
*/
function getTopWinow(){
var p = window;
while(p != p.parent){
p = p.parent;
}
return p;
}
针对问题2,后端会话过期的检测问题解决如下:
解决思路为重写shiro表单过滤器FormAuthenticationFilter中的onAccessDenied方法,在该方法中除了实现原有的功能外,还需要增加判断,当shiro认证未通过的情况下,并且前端为ajax请求,则将该请求的请求状态置为401。
后端会话过期的检测及是否为ajax请求判断的主要代码如下:
public class XFormAuthenticationFilter extends FormAuthenticationFilter {
private static final Logger log = LoggerFactory.getLogger(XFormAuthenticationFilter.class);

public XFormAuthenticationFilter() {
setLoginUrl(DEFAULT_LOGIN_URL);
}
@Override
protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
HttpServletRequest httpRequest = WebUtils.toHttp(request);
HttpServletResponse httpResponse = WebUtils.toHttp(response);
if (isLoginRequest(request, response)) {
if (isLoginSubmission(request, response)) {
if (log.isTraceEnabled()) {
log.trace("Login submission detected. Attempting to execute login.");
}
return executeLogin(request, response);
} else {
if (log.isTraceEnabled()) {
log.trace("Login page view.");
}
// allow them to see the login page ;)
return true;
}
} else {
if (log.isTraceEnabled()) {
log.trace("Attempting to access a path which requires authentication. Forwarding to the "
+ "Authentication url [" + getLoginUrl() + "]");
}
// 判断session里是否有用户信息
if (httpRequest.getHeader("X-Requested-With") != null
&& httpRequest.getHeader("X-Requested-With").equalsIgnoreCase("XMLHttpRequest")) {
// 如果是ajax请求响应头会有,x-requested-with
httpResponse.sendError(HttpStatus.UNAUTHORIZED.value());

//redirectToLogin(request, response);
} else {
redirectToLogin(request, response);
}
return false;
}
}
}

针对问题3,.对封装后的ajax进行请求完成后的统一处理问题的解决视具体情况而定。
1>对jquery-ujs扩展及ajax回调 UI渲染的ajax请求完成后的统一处理如下:
$("*[data-remote='true']").on('ajax:complete', function(xhr, status) {
if (status.status == 401) {
var top = getTopWinow();
top.location.href = '/login';
}
});
2>对datatable封装后的ajax请求完成后的统一处理如下:
$.extend($.fn, {
cdataTable: function (setting) {
if (undefined == setting) {
setting = {};
}
/**
* 设置未来(全局)的AJAX请求默认选项
* 主要设置了AJAX请求遇到Session过期的情况
*/
$.extend(setting.ajax, {"error": function (xhr, error, thrown) {
if(xhr.status == 401) {
var top = getTopWinow();
top.location.href = '/login';
}
}
});
}
});
针对问题4,对临时添加的界面元素执行ajax请求的统一处理问题解决情况如下:
若本页面或页面片段在加载过程或相关程序执行过程中有临时界面元素生成,并要对此进行ajax请求后的结果进行统一处理,则需在该页面的页面上,加入以下代码:
$('form').on('ajax:complete', function(xhr, status) {//form表示执行ajax请求的界面元素
if (status.status == 401) {
var top = getTopWinow();
top.location.href = '/login';
}
});
针对问题5.对spring boot框架下对shiro自定义的Formauthenticationfilter表单验证器的继承问题的解决如下:
其解决方案按照shiro的java config配置即可,需要的一点是不要把继承Formauthenticationfilter表单验证器的XFormauthenticationfilter配置成bean,在ShiroFilterFactoryBean中直接使用即可,具体原因是若配置成bean,则使用anon白名单放过的url在shiro中可通过,但是会被spring boot容器拦截掉,而把XFormauthenticationfilter当做feibean的普通的shiro拦截器使用就不存在这个问题。具体代码如下:
@Autowired
@Bean(name = "shiroFilter")
public ShiroFilterFactoryBean getShiroFilterFactoryBean(DefaultWebSecurityManager securitymanager) {
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
shiroFilterFactoryBean.setSecurityManager(securitymanager);
shiroFilterFactoryBean.setLoginUrl("/login");
shiroFilterFactoryBean.setSuccessUrl("/");
shiroFilterFactoryBean.setUnauthorizedUrl("/login");
Map<String, Filter> filters = new HashMap<String, Filter>();
filters.put("authc", new XFormAuthenticationFilter());
shiroFilterFactoryBean.setFilters(filters);
filterChainDefinitionMap.put("/favicon.ico", "anon");
filterChainDefinitionMap.put("/assets/**", "anon");
filterChainDefinitionMap.put("/static/**", "anon");
filterChainDefinitionMap.put("/user/service", "anon");
filterChainDefinitionMap.put("/**", "authc");
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
return shiroFilterFactoryBean;
}
针对问题5,可能出现问题的具体描述如下,具体思想是不能让spring boot容器将自定义的shiro过滤器接管,即不能配置成bean的原因。
基于Spring Boot 2.0、Spring Data JPA、ThymeleafShiro开发的后台管理系统可以实现一个功能强大且易于维护的应用程序。 这套技术栈的优势包括: 1. Spring Boot 2.0:它是一个快速构建应用程序的框架,提供自动化配置和减少样板代码的优势,使开发变得更加高效。 2. Spring Data JPA:它是一个基于JPA的持久化框架,通过简化数据库操作和提供对各种数据库的支持,大大减少了开发人员的工作量。 3. Thymeleaf:它是一个服务器端的Java模板引擎,可以直接处理HTML、XML、JavaScript、CSS和文本等内容。它具有易于学习和使用的特点,并且能够与Spring Boot实现良好的集成。 4. Shiro:它是一个功能强大且灵活的Java安全框架,可以提供认证、授权、加密和会话管理等功能。通过集成Shiro,我们可以轻松实现后台管理系统的用户认证和访问控制等安全需求。 基于这套技术栈,我们可以开发一个后台管理系统,实现用户登录、权限管理、菜单管理、角色管理、用户管理等功能。利用Spring Boot的自动化配置和快速启动特性,我们可以快速搭建项目的骨架,并集成Spring Data JPA实现数据访问,利用Thymeleaf开发可复用的页面组件,通过Shiro实现用户认证和授权。 总之,基于Spring Boot 2.0、Spring Data JPA、ThymeleafShiro的后台管理系统,不仅可以极大地提高开发效率,还能够提供丰富的功能和安全性,帮助我们快速构建高质量的应用程序。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值