liukangdong
2025-03-05 3201bba04baf50d368fbc4ac11658701e97a0a97
server/system_service/src/main/java/com/doumee/config/cloudfilter/LoginHandlerInterceptor.java
@@ -1,70 +1,128 @@
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.core.model.LoginUserInfo;
import com.doumee.service.business.third.model.LoginUserInfo;
import com.doumee.core.utils.Constants;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authz.UnauthorizedException;
import org.apache.shiro.authz.annotation.RequiresPermissions;
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;
public class LoginHandlerInterceptor implements HandlerInterceptor {
    private RedisTemplate<String,Object> stringRedisTemplate;
    private long expireTime;
    // 由于该类未交给spring管理,因此不能使用自动装配的方式获取RedisTemplate对象
    public LoginHandlerInterceptor(RedisTemplate<String,Object> stringRedisTemplate) {
    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 {
        HandlerMethod handlerMethod = (HandlerMethod) handler;
        Class<?> beanType = handlerMethod.getBeanType();
        if (!beanType.isAnnotationPresent(LoginNoRequired.class) && !handlerMethod.hasMethodAnnotation(LoginNoRequired.class)) {
            //获取token
            String token = request.getHeader(Constants.HEADER_USER_TOKEN);  // 从 http 请求头中取出 token
            if (StringUtils.isNotBlank(token)) {
              LoginUserInfo user =   checkLogin(request,response);
                if (!handlerMethod.hasMethodAnnotation(RequiresPermissions.class)) {
                    RequiresPermissions p = handlerMethod.getMethodAnnotation(RequiresPermissions.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(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(),"没有该操作权限");
                            }
                        }
                        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(),"未登录");
            }
        }else{
            throw new BusinessException(ResponseStatus.NO_LOGIN.getCode(),request.getRequestURI()+"未登录");
        }
        return true;
    }
    private LoginUserInfo checkLogin(HttpServletRequest request, HttpServletResponse response) {
        String token = request.getHeader(Constants.HEADER_USER_TOKEN);
    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(),"未登录");
        }
@@ -76,12 +134,92 @@
        if(user ==null ){
            throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"用户登陆已失效,请重新登陆!");
        }
        stringRedisTemplate.expire(Constants.REDIS_TOKEN_KEY+token,this.expireTime, 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];
        }
    }
}