以下是本人开发中使用的简单实现,望各位大神提出见解及改进方法,也写此博客记录
一、继承org.springframework.web.servlet.handler.HandlerInterceptorAdapter类
package com.rzxt.test.common.auth;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.rzxt.test.common.ResultCode;
import com.rzxt.test.common.constants.Constants;
import com.rzxt.test.common.utils.MD5Util;
import com.rzxt.test.common.utils.RedisUtil;
import com.rzxt.test.web.entity.AccessToken;
import com.rzxt.test.web.entity.BaseUser;
import com.rzxt.test.web.service.AccessService;
import com.rzxt.test.web.service.UserService;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.HashMap;
import java.util.Map;
/**
* Created by lei.w on 2016/10/11 0020.
*/
public class AccessAuthInterceptor extends HandlerInterceptorAdapter {
private static Logger logger = Logger.getLogger(LogHandler.LOG_SCHEMA_AUTH);
@Autowired
AccessService accessService;
@Autowired
UserService userService;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
logger.debug("Access Auth Interceptor - 进入拦截器");
//记录访问开始时间
request.setAttribute("access_begin_time", System.currentTimeMillis());
if (handler instanceof HandlerMethod) {
HandlerMethod method = (HandlerMethod) handler;
AccessAuth accessAuth = method.getMethodAnnotation(AccessAuth.class);
if (!ObjectUtils.isEmpty(accessAuth) && accessAuth.auth()) {
} else {
logger.debug("Access Auth Interceptor - 拦截器跳出");
return true;
}
}
logger.debug("Authorized Access - 拦截器开始");
//return true;
//request basic paramter
String req_uid = request.getParameter(Constants.MOBILE_UID);
String req_access_token = request.getParameter(Constants.MOBILE_ACCESS_TOKEN);
logger.info("req uid " + req_uid);
logger.info("req access_token " + req_access_token);
//0.参数解析
if (!StringUtils.isEmpty(req_access_token) && !StringUtils.isEmpty(req_uid) && req_access_token.length() == 87) {
//fx+f+ts+token+v 2314d7e2ea7b4fe99b28042739f1af26 1 1477292375598 91a5e51dcc1028398394ee7889d20b46 000001000
String req_token = req_access_token.substring(46, 78);
String req_timestamp = req_access_token.substring(33, 46);
String req_fx = req_access_token.substring(0, 32);
String req_from = req_access_token.substring(32, 33);
String req_version = req_access_token.substring(78, 87);
logger.info("req token " + req_token);
logger.info("req timestamp " + req_timestamp);
logger.info("req fx " + req_fx);
logger.info("req from " + req_from);
logger.info("req version " + req_version);
//1.check 非空验证
if (this.checkMobileEmpty(req_uid, req_token, req_timestamp, req_fx, req_from, req_version)) {
//2.check ts时间戳
if (this.checkTs(req_timestamp)) {
//3.check 用户权限
if (this.checkUserAuth(req_uid, req_token, req_from)) {
//4.check
if (this.check(req_uid, req_token, req_timestamp, req_fx, req_from, req_version)) {
//为aspect构造属性值
request.setAttribute(Constants.MOBILE_UID, req_uid);
request.setAttribute(Constants.MOBILE_TOKEN, req_token);
request.setAttribute(Constants.MOBILE_TIMESTAMP, req_timestamp);
request.setAttribute(Constants.MOBILE_FX, req_fx);
request.setAttribute(Constants.MOBILE_FROM, req_from);
request.setAttribute(Constants.MOBILE_VERSION, req_version);
request.setAttribute(Constants.MOBILE_URI, request.getRequestURI());
request.setAttribute(Constants.MOBILE_IP, this.getIPAddr(request));
return true;
} else {
out(response, ResultCode.AUTH_FAIL);
return false;
}
} else {
out(response, ResultCode.AUTH_RELOGIN);
return false;
}
} else {
out(response, ResultCode.AUTH_FAIL);
return false;
}
} else {
out(response, ResultCode.AUTH_FAIL);
return false;
}
} else {
logger.error("Access Auth Interceptor - 请求参数不完整");
out(response, ResultCode.AUTH_FAIL);
return false;
}
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
logger.debug("Access Auth Interceptor - interceptor auth execution time 拦截器验证执行时间:" + (System.currentTimeMillis() - Long.valueOf(request.getAttribute("access_begin_time").toString())) + "ms");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
logger.debug("Access Auth Interceptor - controller execution time 控制器方法执行时间:" + (System.currentTimeMillis() - Long.valueOf(request.getAttribute("access_begin_time").toString())) + "ms");
}
@Override
public void afterConcurrentHandlingStarted(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
super.afterConcurrentHandlingStarted(request, response, handler);
}
/**
* 验证移动端参数非空
*
* @param req_uid
* @param req_token
* @param req_timestamp
* @param req_fx
* @param req_from
* @param req_version
* @return
*/
private static final boolean checkMobileEmpty(String req_uid, String req_token, String req_timestamp, String req_fx, String req_from, String req_version) {
if (!StringUtils.isEmpty(req_uid) && !StringUtils.isEmpty(req_token) && !StringUtils.isEmpty(req_timestamp) && !StringUtils.isEmpty(req_fx) && !StringUtils.isEmpty(req_from) && !StringUtils.isEmpty(req_version)) {
return true;
} else {
logger.error("Access Auth Interceptor - 解析参数不完整");
return false;
}
}
/**
* 验证时间戳ts
*
* @param req_timestamp
* @return
*/
private static final boolean checkTs(String req_timestamp) {
if (Long.valueOf(req_timestamp) < System.currentTimeMillis() - 10 * 60 * 1000) {
logger.error("Authorized Access - 超时访问");
return false;
} else {
return true;
}
}
/**
* 验证token信息
*
* @param req_uid
* @param req_token
* @return
*/
private final boolean checkUserAuth(String req_uid, String req_token, String req_side) {
try {
//1.验证uid是否存在
logger.info("Access Auth Interceptor - UserAuth [uid] = "+req_uid+" [token] = "+req_token+" [side] = "+req_side);
BaseUser baseUser = userService.getUserById(Long.valueOf(req_uid));
if (!ObjectUtils.isEmpty(baseUser)) {
//2.验证token及side
AccessToken accessToken = accessService.getAccessToken(Long.valueOf(req_uid));
if (!ObjectUtils.isEmpty(accessToken) && !StringUtils.isEmpty(accessToken.getToken()) && req_token.equalsIgnoreCase(accessToken.getToken()) && !StringUtils.isEmpty(accessToken.getSide()) && req_side.equals(accessToken.getSide() + "")) {
return true;
} else {
logger.error("Access Auth Interceptor - UserAuth token is null 权限验证失败 [uid] = "+req_uid+" [token] = "+req_token+" [side] = "+req_side);
return false;
}
} else {
logger.error("Access Auth Interceptor - UserAuth User is null 权限验证失败 [uid] = "+req_uid+" [token] = "+req_token+" [side] = "+req_side);
return false;
}
/*RedisUtil redisUtil = RedisUtil.getRu();
String cache_token = redisUtil.get(Constants.CACHE_MOBILE_AUTH_TOKEN_PREFIX + req_uid);
String cache_side = redisUtil.get(Constants.CACHE_MOBILE_AUTH_SIDE_PREFIX + req_uid);
//data token
String com_token = "";
String com_side = "";
if (!StringUtils.isEmpty(cache_token) && !StringUtils.isEmpty(cache_side)) {
com_token = cache_token;
com_side = cache_side;
logger.debug("token and side cache");
} else {
logger.debug("token and side no cache");
AccessToken accessToken = accessService.getAccessToken(Integer.valueOf(req_uid));
if (!ObjectUtils.isEmpty(accessToken) && !StringUtils.isEmpty(accessToken.getToken()) && !StringUtils.isEmpty(accessToken.getSide())) {
com_token = accessToken.getToken();
com_side = accessToken.getSide()+"";
redisUtil.set(Constants.CACHE_MOBILE_AUTH_TOKEN_PREFIX + req_uid, com_token);
redisUtil.set(Constants.CACHE_MOBILE_AUTH_SIDE_PREFIX + req_uid, com_side);
logger.debug("token and side set cache from database");
}
}*/
} catch (Exception e) {
logger.error("Access Auth Interceptor - UserAuth权限验证失败,程序异常");
return false;
}
}
/**
* 验证
*
* @param req_uid
* @param req_token
* @param req_timestamp
* @param req_fx
* @return
*/
private static final boolean check(String req_uid, String req_token, String req_timestamp, String req_fx, String req_from, String req_version) {
logger.info("MD5加密 :" + MD5Util.MD5(req_uid + "_" + req_timestamp + "_" + req_from + "_" + req_version + "_" + req_token).toLowerCase());
if (req_fx.equalsIgnoreCase(MD5Util.MD5(req_uid + "_" + req_timestamp + "_" + req_from + "_" + req_version + "_" + req_token))) {
return true;
} else {
logger.error("Access Auth Interceptor - 签名验证失败");
return false;
}
}
/**
* 错误信息
*
* @param resultCode
* @return
*/
private static final Map
Map
map.put("code", resultCode.getCode());
map.put("msg", resultCode.getMessage());
return map;
}
/**
* 返回输出json
*
* @param response
* @param resultCode
*/
private static final void out(HttpServletResponse response, ResultCode resultCode) {
ObjectMapper objectMapper = new ObjectMapper();
response.setCharacterEncoding("UTF-8");
response.setContentType("application/json; charset=utf-8");
PrintWriter out = null;
try {
out = response.getWriter();
out.append(objectMapper.writeValueAsString(resultFail(resultCode)));
} catch (IOException e) {
e.printStackTrace();
} finally {
if (out != null) {
out.close();
}
}
}
/**
* 获取http请求的真实IP地址
*
* @param request
* @return
*/
private static String getIPAddr(HttpServletRequest request) {
if (request == null)
return null;
String ip = request.getHeader("X-Forwarded-For");
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
ip = request.getHeader("Proxy-Client-IP");
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
ip = request.getHeader("WL-Proxy-Client-IP");
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
ip = request.getHeader("HTTP_CLIENT_IP");
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
ip = request.getHeader("HTTP_X_FORWARDED_FOR");
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
ip = request.getRemoteAddr();
if ("127.0.0.1".equals(ip) || "0:0:0:0:0:0:0:1".equals(ip))
try {
ip = InetAddress.getLocalHost().getHostAddress();
} catch (UnknownHostException unknownhostexception) {
}
return ip;
}
public static void main(String[] args) {
}
}
二、配置xml加载文件
xmlns="http://www.springframework.org/schema/beans"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd"
>