spring|springboot 实现登录拦截和权限拦截

springboot 实现登录拦截和权限拦截 拦截器的注册器

package lingnan.interceptor; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; /** * */ @Configuration public class MyWebAppConfigurer extends WebMvcConfigurerAdapter{@Override public void addViewControllers(ViewControllerRegistry registry) { registry.addViewController("/user/toLogin").setViewName("login"); } //@Override //public void addInterceptors(InterceptorRegistry registry) { //registry.addInterceptor(new RequestLog()).addPathPatterns("/**"); //super.addInterceptors(registry); //} @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new LoginHandlerInterceptor()).addPathPatterns("/**") //下面是controller跳转登录界面的url,解除此拦截 .excludePathPatterns("/user/toLogin") //下面这些是解除静态资源的拦截 .excludePathPatterns("/assets/**") .excludePathPatterns("/css/**") .excludePathPatterns("/fonts/**") .excludePathPatterns("/images/**") .excludePathPatterns("/js/**") .excludePathPatterns("/layui/**") .excludePathPatterns("/static/**"); super.addInterceptors(registry); } }

自定义拦截器
package lingnan.interceptor; import lingnan.entity.User; import org.springframework.stereotype.Component; import org.springframework.web.method.HandlerMethod; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.lang.reflect.Method; @Component public class LoginHandlerInterceptor implements HandlerInterceptor { @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { Object user = request.getSession().getAttribute("loginUser"); System.out.println("afterCompletion----" + user + " ::: " + request.getRequestURL()); }@Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { Object user = request.getSession().getAttribute("loginUser"); System.out.println("postHandle----" + user + " ::: " + request.getRequestURL()); }@Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { User user = (User) request.getSession().getAttribute("loginUser"); System.out.println("preHandle----" + user + " ::: " + request.getRequestURL()); //controller中跳转到登录界面的方法为login()如果是这个方法直接true HandlerMethod handlerMethod = (HandlerMethod) handler; // 获取用户token Method method = handlerMethod.getMethod(); System.out.println("method:::"+method.getName()); if(method.getName().equals("login")) return true; //如果loginUser为空说明未经过登录 if (user == null) { request.setAttribute("loginError", "请先登录"); // 获取request返回页面到登录页 request.getRequestDispatcher("/user/toLogin").forward(request,response); return false; } //用于拦截普通用户试图登录管理界面,我的管理界面url含有manage字符串 if(user.getAccess()==1&&request.getRequestURL().indexOf("manage")!=-1){ request.setAttribute("loginError", "无权限,不是管理员"); // 获取request返回页面到登录页 request.getRequestDispatcher("/user/toLogin").forward(request,response); return false; } return true; }}

题外:
【spring|springboot 实现登录拦截和权限拦截】用Aop切面编程,可以看到各个方法的输入输出值等等
package lingnan.log; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Pointcut; import org.omg.PortableInterceptor.RequestInfo; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.context.annotation.Configuration; import org.springframework.web.context.request.RequestAttributes; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; import javax.servlet.http.HttpServletRequest; /** * Created by pd on 17/12/07. */ //描述切面类 @Aspect//@Aspect注解就是告诉spring 这是一个aop类,AOP切面 @Configuration//可理解为用spring的时候xml里面的标签,类中 @Bean可以理解为用Spring的时候xml里面的标签 public class LogRecordAspect { private static final Logger logger = LoggerFactory.getLogger(LogRecordAspect.class); // 用@Pointcut来注解一个切入方法 //@Pointcut注解 声明这是一个需要拦截的切面,也就是说,当调用任何一个controller方法的时候,都会激活这个aop @Pointcut("execution(* lingnan.controller.*Controller.*(..))")//两个..代表所有子目录,最后括号里的两个..代表所有参数 public void excudeService() { }//@Around注解 环绕执行,就是在调用之前和调用之后,都会执行一定的逻辑 @Around("excudeService()") public Object doAround(ProceedingJoinPoint pjp) throws Throwable {RequestAttributes ra = RequestContextHolder.getRequestAttributes(); ServletRequestAttributes sra = (ServletRequestAttributes) ra; HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest(); String url = request.getRequestURL().toString(); String method = request.getMethod(); String uri = request.getRequestURI(); String queryString = request.getQueryString(); try{ Object[] args =pjp.getArgs(); for(int i=0; i

另一种拦截器的事务记录,记录方法消耗时间,跟上面的LoginHandlerInterceptor 拦截器一样要注册到注册器上
package lingnan.log; import org.slf4j.Logger; import org.slf4j.LoggerFactory; 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.lang.reflect.Method; import java.time.Instant; /* HandlerInterceptoer拦截的是请求地址,所以针对请求地址做一些验证、预处理等操作比较合适, 比如需要统计请求这个地址的响应时间 */ /*Filter是Servlet规范规定的,不属于spring框架,也是用于请求的拦截。 但是它适合更粗粒度的拦截,在请求前后做一些编解码处理、日志记录等。 */ //用于参考没用上 public class RequestLog extends HandlerInterceptorAdapter { private static final Logger LOGGER = LoggerFactory.getLogger(RequestLog.class); /** * 前置检查,方法执行前 */ @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { String ip = request.getRemoteAddr(); Instant startTime = Instant.now(); request.setAttribute("logrequestStartTime", startTime); HandlerMethod handlerMethod = (HandlerMethod) handler; // 获取用户token Method method = handlerMethod.getMethod(); LOGGER.info("用户:"+ip+",访问目标:"+method.getDeclaringClass().getName() + "." + method.getName()); LOGGER.info("params:"+request.getQueryString()); return true; }/** *方法执行中 * @param request * @param response * @param handler * @param modelAndView * @throws Exception */ // controller处理完成 public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { HandlerMethod handlerMethod = (HandlerMethod) handler; Method method = handlerMethod.getMethod(); Instant startTime = (Instant) request.getAttribute("logrequestStartTime"); Instant endTime = Instant.now(); long executeTime = endTime.toEpochMilli()- startTime.toEpochMilli(); // log it if (executeTime > 1000) { LOGGER.info("[" + method.getDeclaringClass().getName() + "." + method.getName() + "] 执行耗时 : " + executeTime + "ms"); } else { LOGGER.info("[" + method.getDeclaringClass().getSimpleName() + "." + method.getName() + "] 执行耗时 : " + executeTime + "ms"); }} }

    推荐阅读