项目中 用jeesite 做服务端, ajax请求业务时,如果session超时 一直返回 web登录页面, 需要重写 shiro拦截器的onAccessDenied方法,判断到如果 Principal为空并且是ajax请求 直接ajax返回,
/**
* Copyright © 2012-2016 <a href="https://github.com/thinkgem/jeesite">JeeSite</a> All rights reserved.
*/
package com.thinkgem.jeesite.modules.sys.security;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.util.WebUtils;
import org.springframework.stereotype.Service;
import com.thinkgem.jeesite.common.mapper.JsonMapper;
import com.thinkgem.jeesite.common.utils.StringUtils;
/**
* 表单验证(包含验证码)过滤类
* @author ThinkGem
* @version 2014-5-19
*/
@Service
public class FormAuthenticationFilter extends org.apache.shiro.web.filter.authc.FormAuthenticationFilter {
public static final String DEFAULT_CAPTCHA_PARAM = "validateCode";
public static final String DEFAULT_MOBILE_PARAM = "mobileLogin";
public static final String DEFAULT_MESSAGE_PARAM = "message";
private String captchaParam = DEFAULT_CAPTCHA_PARAM;
private String mobileLoginParam = DEFAULT_MOBILE_PARAM;
private String messageParam = DEFAULT_MESSAGE_PARAM;
boolean isAjax(HttpServletRequest request){
return (request.getHeader("X-Requested-With") != null && "XMLHttpRequest".equals( request.getHeader("X-Requested-With").toString()) ) ;
}
/**
* 重写该方法 session超时 ajax请求 返回json
*/
@Override
protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
// TODO Auto-generated method stub
HttpServletRequest httpRequest = (HttpServletRequest) request;
HttpServletResponse httpResponse = (HttpServletResponse) response;
Subject subject = getSubject(request, response);
if (subject.getPrincipal() == null && isAjax(httpRequest)) {
httpResponse.reset();
httpResponse.setContentType("application/json");
httpResponse.setCharacterEncoding("utf-8");
Map<String, String> map = new HashMap<String, String>();
map.put("code", "-1");
map.put("msg", "session timeOut");
httpResponse.getWriter().print(JsonMapper.toJsonString(map));
return false;
}
return super.onAccessDenied(request, response);
}
protected AuthenticationToken createToken(ServletRequest request, ServletResponse response) {
String username = getUsername(request);
String password = getPassword(request);
if (password==null){
password = "";
}
boolean rememberMe = isRememberMe(request);
String host = StringUtils.getRemoteAddr((HttpServletRequest)request);
String captcha = getCaptcha(request);
boolean mobile = isMobileLogin(request);
return new UsernamePasswordToken(username, password.toCharArray(), rememberMe, host, captcha, mobile);
}
/**
* 获取登录用户名
*/
protected String getUsername(ServletRequest request, ServletResponse response) {
String username = super.getUsername(request);
if (StringUtils.isBlank(username)){
username = StringUtils.toString(request.getAttribute(getUsernameParam()), StringUtils.EMPTY);
}
return username;
}
/**
* 获取登录密码
*/
@Override
protected String getPassword(ServletRequest request) {
String password = super.getPassword(request);
if (StringUtils.isBlank(password)){
password = StringUtils.toString(request.getAttribute(getPasswordParam()), StringUtils.EMPTY);
}
return password;
}
/**
* 获取记住我
*/
@Override
protected boolean isRememberMe(ServletRequest request) {
String isRememberMe = WebUtils.getCleanParam(request, getRememberMeParam());
if (StringUtils.isBlank(isRememberMe)){
isRememberMe = StringUtils.toString(request.getAttribute(getRememberMeParam()), StringUtils.EMPTY);
}
return StringUtils.toBoolean(isRememberMe);
}
public String getCaptchaParam() {
return captchaParam;
}
protected String getCaptcha(ServletRequest request) {
return WebUtils.getCleanParam(request, getCaptchaParam());
}
public String getMobileLoginParam() {
return mobileLoginParam;
}
protected boolean isMobileLogin(ServletRequest request) {
return WebUtils.isTrue(request, getMobileLoginParam());
}
public String getMessageParam() {
return messageParam;
}
/**
* 登录成功之后跳转URL
*/
public String getSuccessUrl() {
return super.getSuccessUrl();
}
@Override
protected void issueSuccessRedirect(ServletRequest request,
ServletResponse response) throws Exception {
// Principal p = UserUtils.getPrincipal();
// if (p != null && !p.isMobileLogin()){
WebUtils.issueRedirect(request, response, getSuccessUrl(), null, true);
// }else{
// super.issueSuccessRedirect(request, response);
// }
}
/**
* 登录失败调用事件
*/
@Override
protected boolean onLoginFailure(AuthenticationToken token,
AuthenticationException e, ServletRequest request, ServletResponse response) {
String className = e.getClass().getName(), message = "";
if (IncorrectCredentialsException.class.getName().equals(className)
|| UnknownAccountException.class.getName().equals(className)){
message = "用户或密码错误, 请重试.";
}
else if (e.getMessage() != null && StringUtils.startsWith(e.getMessage(), "msg:")){
message = StringUtils.replace(e.getMessage(), "msg:", "");
}
else{
message = "系统出现点问题,请稍后再试!";
e.printStackTrace(); // 输出到控制台
}
request.setAttribute(getFailureKeyAttribute(), className);
request.setAttribute(getMessageParam(), message);
return true;
}
}