1、全局拦截前端接口请求
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import com.mollen.exam.interceptor.UserAuthorityInterceptor;
@Configuration
public class SecurityConfiguration extends WebMvcConfigurerAdapter {
@Autowired
private UserAuthorityInterceptor userAuthorityInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(userAuthorityInterceptor).addPathPatterns("/**");
}
}
2.配置无需拦截的接口
import java.util.ArrayList;
import java.util.List;
public enum UnFilterURL {
USER_LOGIN("loginByPwd", "用户登录"),
USER_LOGIN_OUT("loginOut", "用户登出"),
USER_UPDATE_PASSWORDS("updatePasswords", "修改密码"),
USER_FORGET_PASSWORDS("forgetPasswords", "忘记密码"),
GET_ORG_BY_ACCOUNT_NO("getOrgByAccountNo", "获取管理员机构列表"),
GET_VALIDATE_CODE("getValidateCode", "获取验证码"),
UnFilterURL(String code, String desc) {
this.code = code;
this.desc = desc;
}
public static List<String> getUnFilterList() {
UnFilterURL[] urls = UnFilterURL.values();
List<String> unFilterList = new ArrayList<String>();
for (UnFilterURL ufu : urls) {
unFilterList.add(ufu.getCode());
}
return unFilterList;
}
private String code;
private String desc;
public String getCode() {
return code;
}
public String getDesc() {
return desc;
}
}
3.自定义权限接口注解
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
public @interface AuthAnnotation {
String action();
String[] param() default {};
boolean useParam() default false;
}
4.过滤接口
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.bojun.author.AuthAnnotation;
import com.bojun.enums.ResponseCodeEnum;
import com.bojun.mollen.entity.dto.SysManageUserDTO;
import com.bojun.mollen.enums.UnFilterURL;
import com.bojun.mollen.service.ISysRoleService;
import com.whalin.MemCached.MemCachedClient;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import org.springframework.web.servlet.resource.ResourceHttpRequestHandler;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Component
public class UserAuthorityInterceptor extends HandlerInterceptorAdapter {
private Log log = LogFactory.getLog(UserAuthorityInterceptor.class);
@Autowired
private ISysRoleService roleService;
@Autowired
private MemCachedClient memCached;
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
log.info("--------------自定义拦截器----------------");
System.out.println(handler+"..........");
if (null == handler) {
return true;
}
if(!(handler instanceof HandlerMethod)){
return true;
}
HandlerMethod handlerMethod = (HandlerMethod) handler;
String actionName = handlerMethod.getMethod().getName();
List<String> unFilterURLList = UnFilterURL.getUnFilterList();
if (unFilterURLList.contains(actionName)) {
return true;
}
String token = request.getHeader("token");
log.info("--------------token----------------:" + token);
JSONObject json = new JSONObject();
if (StringUtils.isBlank(token)) {
json.put("code", 401);
json.put("msg", "超时请登录!");
outString(response, JSON.toJSONString(json));
return false;
}
if (null == memCached.get(token)) {
json.put("code", 401);
json.put("msg", "超时请登录!");
outString(response, JSON.toJSONString(json));
return false;
}
String valStr = JSON.toJSONString(memCached.get(token));
SysManageUserDTO manageUser = JSON.parseObject(valStr, SysManageUserDTO.class);
if (null != manageUser.getType() && 0 == manageUser.getType()) {
memCached.set(token, manageUser, new Date(15 * 60 * 1000));
request.setAttribute("manageUser", manageUser);
return true;
}
String authority = null;
try {
authority = handlerMethod.getMethodAnnotation(AuthAnnotation.class).action();
} catch (Exception e) {
log.error("找不到权限注解方法异常", e);
}
if (StringUtils.isEmpty(authority)) {
json.put("code", "400");
json.put("msg", "拦截器找不到方法异常");
outString(response, JSON.toJSONString(json));
return false;
}
if (StringUtils.isNotEmpty(manageUser.getRoleId())) {
Map<String, Object> paramsMap = new HashMap<String, Object>();
paramsMap.put("accountNo", manageUser.getAccountNo());
List<String> authorityMenu = roleService.getLoginAuthorityUrl(paramsMap);
if (null == authorityMenu || (!authorityMenu.contains(authority) && !"common".equals(authority))) {
json.put("code", "403");
json.put("msg", "暂无访问权限");
outString(response, JSON.toJSONString(json));
return false;
}
}else{
json.put("code", "403");
json.put("msg", "账户未分配角色");
outString(response, JSON.toJSONString(json));
return false;
}
memCached.set(token, manageUser, new Date(15 * 60 * 1000));
request.setAttribute("manageUser", manageUser);
return true;
}
public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3)
throws Exception {
}
public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3)
throws Exception {
}
public void outString(HttpServletResponse response, String str) {
try {
response.setCharacterEncoding("UTF-8");
PrintWriter out = response.getWriter();
out.write(str);
out.flush();
out.close();
} catch (IOException e) {
log.error(e);
}
}
}
5.使用方式
@RequestMapping(value = "/getAllByCondition", method = RequestMethod.POST)
public void getAllByCondition(HttpServletRequest request,
@RequestParam(value = "pageNum") int pageNum,
@RequestParam(value = "pageSize") int pageSize){
try {
...
} catch (Exception e) {
log.error("getAllByCondition:", e);
outJson(errorInfo(ResponseCodeEnum.EXCEPTION_REQUEST.getCode()));
}
}
6.总结
1.自定义适配器
继承WebMvcConfigurerAdapter类重写addInterceptors()方法拦截所有接口。(Spring5 要用WebMvcConfigurer)
2.自定义拦截规则
继承HandlerInterceptorAdapter类,重写preHandle()方法。
3.枚举不过滤接口。
4.自定义权限控制注解。
拦截器通过handlerMethod.getMethodAnnotation(AuthAnnotation.class).action()拿到这个注解里面的值判断是否有接口权限。