| package com.doumee.config.cloudfilter; | 
|   | 
| import com.alibaba.fastjson.JSONObject; | 
| import com.doumee.config.annotation.CloudRequiredPermission; | 
| import com.doumee.config.annotation.LoginNoRequired; | 
| import com.doumee.config.jwt.JwtProperties; | 
| import com.doumee.config.jwt.JwtTokenUtil; | 
| import com.doumee.core.constants.ResponseStatus; | 
| import com.doumee.core.exception.BusinessException; | 
| import com.doumee.service.business.third.model.LoginUserInfo; | 
| import com.doumee.core.utils.Constants; | 
| import lombok.extern.slf4j.Slf4j; | 
| import org.apache.commons.lang3.StringUtils; | 
| import org.springframework.data.redis.core.RedisTemplate; | 
| import org.springframework.web.method.HandlerMethod; | 
| import org.springframework.web.servlet.HandlerInterceptor; | 
|   | 
| import javax.annotation.Resource; | 
| import javax.servlet.ServletInputStream; | 
| import javax.servlet.http.Cookie; | 
| import javax.servlet.http.HttpServletRequest; | 
| import javax.servlet.http.HttpServletRequestWrapper; | 
| import javax.servlet.http.HttpServletResponse; | 
| import java.io.BufferedReader; | 
| import java.io.IOException; | 
| import java.io.InputStreamReader; | 
| import java.util.*; | 
| import java.util.concurrent.TimeUnit; | 
|   | 
| @Slf4j | 
| public class LoginHandlerInterceptor implements HandlerInterceptor { | 
|   | 
|     private RedisTemplate<String,Object> stringRedisTemplate; | 
|     private long expireTime; | 
|   | 
|     public long getExpireTime() { | 
|         return expireTime; | 
|     } | 
|   | 
|     public void setExpireTime(long expireTime) { | 
|         this.expireTime = expireTime; | 
|     } | 
|   | 
|     // 由于该类未交给spring管理,因此不能使用自动装配的方式获取RedisTemplate对象 | 
|     public LoginHandlerInterceptor(RedisTemplate<String,Object> stringRedisTemplate,long expireTime) { | 
|         this.expireTime = expireTime; | 
|         this.stringRedisTemplate = stringRedisTemplate; | 
|     } | 
|   | 
|     @Override | 
|     public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { | 
|         if(handler instanceof HandlerMethod){ | 
|             HandlerMethod handlerMethod = (HandlerMethod) handler; | 
|             Class<?> beanType = handlerMethod.getBeanType(); | 
|             if (!beanType.isAnnotationPresent(LoginNoRequired.class) && !handlerMethod.hasMethodAnnotation(LoginNoRequired.class)) { | 
|                 //获取token | 
|                 Cookie[]  cookies =   request.getCookies(); | 
|                 String token = request.getHeader(Constants.HEADER_USER_TOKEN);  // 从 http 请求头中取出 token | 
|                 if(StringUtils.isBlank(token)){ | 
|                     for(Cookie c :cookies){ | 
|                         if(StringUtils.equals(c.getName(),Constants.HEADER_USER_TOKEN)){ | 
|                             token = c.getValue(); | 
|                         } | 
|                     } | 
|                 } | 
|                 if (StringUtils.isNotBlank(token)) { | 
|                     LoginUserInfo user =   checkLogin(token); | 
|                     if (handlerMethod.hasMethodAnnotation(CloudRequiredPermission.class)) { | 
|                         CloudRequiredPermission p = handlerMethod.getMethodAnnotation(CloudRequiredPermission.class); | 
|                         if(p.value()!=null && p.value().length>0){ | 
|                             boolean hasPermission = false; | 
|                             for(String s :p.value()){ | 
|                                 if(user.getPermissions()!=null){ | 
|                                     for(String t :user.getPermissions()){ | 
|                                         if(StringUtils.equals(t,s)){ | 
|                                             hasPermission = true; | 
|                                             break; | 
|                                         } | 
|                                     } | 
|                                 } | 
|                             } | 
|                             if(!hasPermission) { | 
|                                 //没有操作权限 | 
|                                 throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"没有该操作权限"); | 
|                             } | 
|                         } | 
|   | 
|                     } | 
|                   /* try { | 
|                         CustomHttpServletRequestWrapper requestWrapper = (CustomHttpServletRequestWrapper)request; | 
|                         String body = requestWrapper.getBody(); | 
|                         JSONObject object = JSONObject.parseObject(body); | 
|                         if(object!=null){ | 
|                             object.put("loginUserinfo",user); | 
|                             requestWrapper.setBody( JSONObject.toJSONString(object)); | 
|                         } | 
|                     }catch (Exception e){ | 
|                     }*/ | 
|                 } else { | 
|                     throw new BusinessException(ResponseStatus.NO_LOGIN.getCode(),request.getRequestURI()+"未登录,TOKEN缺失"); | 
|                 } | 
|             } | 
|         }else{ | 
|             throw new BusinessException(ResponseStatus.NO_LOGIN.getCode(),request.getRequestURI()+"未登录"); | 
|         } | 
|   | 
|         return true; | 
|     } | 
|   | 
|     private String getRequestBody(HttpServletRequest request) { | 
|         // 实现从request获取请求体的逻辑 | 
|         String body = null; | 
|         ServletInputStream inputStream = null; | 
|         try { | 
|             inputStream = request.getInputStream(); | 
|             String charset = request.getCharacterEncoding(); // 可能为null | 
|             if (charset == null) { | 
|                 charset = "UTF-8"; // 默认编码 | 
|             } | 
|             BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, charset)); | 
|             StringBuilder stringBuilder = new StringBuilder(); | 
|             String line = null; | 
|             while ((line = reader.readLine()) != null) { | 
|                 stringBuilder.append(line + "\n"); | 
|             } | 
|             body = stringBuilder.toString(); | 
|         } catch (IOException e) { | 
|             throw new RuntimeException(e); | 
|         } | 
|   | 
|         return body; | 
|     } | 
|   | 
|     private LoginUserInfo checkLogin(String token) { | 
|         if (token == null || token.isEmpty()) { | 
|             throw new BusinessException(ResponseStatus.NO_LOGIN.getCode(),"未登录"); | 
|         } | 
|         String userinfo =(String) stringRedisTemplate.opsForValue().get(Constants.REDIS_TOKEN_KEY + token); | 
|         if (StringUtils.isBlank(userinfo)) { | 
|             throw new BusinessException(ResponseStatus.NO_LOGIN.getCode(),"未登录"); | 
|         } | 
|         LoginUserInfo user = JSONObject.toJavaObject(JSONObject.parseObject(userinfo),LoginUserInfo.class ); | 
|         if(user ==null ){ | 
|             throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"用户登陆已失效,请重新登陆!"); | 
|         } | 
|         log.error("=========开始刷新token有效期:"+token+"======time:"+this.getExpireTime()); | 
|         stringRedisTemplate.expire(Constants.REDIS_TOKEN_KEY+token,this.getExpireTime(), TimeUnit.MILLISECONDS); | 
|         //权限判断------------ | 
|         return  user; | 
|     } | 
|   | 
|   | 
|   | 
|     //    @Override | 
|     public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { | 
| //        UserContext.removeUser(); | 
|     } | 
|   | 
|     class RSARequestWrapper extends HttpServletRequestWrapper { | 
|         private Map<String, String[]> params = new HashMap<>(); | 
|         /** | 
|          * 必须要实现的构造方法 | 
|          * @param request | 
|          */ | 
|         public RSARequestWrapper(HttpServletRequest request) { | 
|             super(request); | 
|             //将参数表,赋予给当前的Map以便于持有request中的参数 | 
|             this.params.putAll(request.getParameterMap()); | 
|         } | 
|         /** | 
|          * 重载构造方法 | 
|          * @param request | 
|          * @param extendParams | 
|          */ | 
|         public RSARequestWrapper(HttpServletRequest request, Map<String, Object> extendParams) { | 
|             this(request); | 
|             //这里将扩展参数写入参数表 | 
|             addAllParameters(extendParams); | 
|         } | 
|         /** | 
|          * 在获取所有的参数名,必须重写此方法,否则对象中参数值映射不上 | 
|          * @return | 
|          */ | 
|         @SuppressWarnings({ "unchecked", "rawtypes" }) | 
|         @Override | 
|         public Enumeration<String> getParameterNames() { | 
|             return new Vector(params.keySet()).elements(); | 
|         } | 
|         /** | 
|          * 增加多个参数 | 
|          * @param otherParams 增加的多个参数 | 
|          */ | 
|         public void addAllParameters(Map<String, Object> otherParams) { | 
|             for (Map.Entry<String, Object> entry : otherParams.entrySet()) { | 
|                 addParameter(entry.getKey(), entry.getValue()); | 
|             } | 
|         } | 
|         /** | 
|          * 增加参数 | 
|          * getParameterMap()中的类型是<String,String[]>类型的,所以这里要将其value转为String[]类型 | 
|          * @param name 参数名 | 
|          * @param value 参数值 | 
|          */ | 
|         public void addParameter(String name, Object value) { | 
|             if (value != null) { | 
|                 if (value instanceof String[]) { | 
|                     params.put(name, (String[]) value); | 
|                 } else if (value instanceof String) { | 
|                     params.put(name, new String[]{(String) value}); | 
|                 } else { | 
|                     params.put(name, new String[]{String.valueOf(value)}); | 
|                 } | 
|             } | 
|         } | 
|         @Override | 
|         public String[] getParameterValues(String name) { | 
|             String[] access_token_user_id = params.get("access_token_user_id"); | 
|             String[] values = params.get(name);//getValue(name); | 
|             if (values == null || access_token_user_id==null){ | 
|                 return null; | 
|             } | 
|             return values; | 
|         } | 
|   | 
|         @Override | 
|         public String getParameter(String name) { | 
|             String[] access_token_user_id = params.get("access_token_user_id"); | 
|             String[] values = params.get(name);//getValue(name); | 
|             if (values == null || access_token_user_id==null){ | 
|                 return null; | 
|             } | 
|             return values[0]; | 
|         } | 
|     } | 
| } |