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.core.constants.ResponseStatus; 
 | 
import com.doumee.core.exception.BusinessException; 
 | 
import com.doumee.service.business.third.model.LoginUserInfo; 
 | 
import com.doumee.core.utils.Constants; 
 | 
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.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.*; 
 | 
  
 | 
public class LoginHandlerInterceptor implements HandlerInterceptor { 
 | 
  
 | 
    private RedisTemplate<String,Object> stringRedisTemplate; 
 | 
  
 | 
  
 | 
    // 由于该类未交给spring管理,因此不能使用自动装配的方式获取RedisTemplate对象 
 | 
    public LoginHandlerInterceptor(RedisTemplate<String,Object> stringRedisTemplate) { 
 | 
        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()+"未登录"); 
 | 
                } 
 | 
            } 
 | 
        }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(),"用户登陆已失效,请重新登陆!"); 
 | 
        } 
 | 
        //权限判断------------ 
 | 
        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]; 
 | 
        } 
 | 
    } 
 | 
} 
 |