郑永安
2023-06-19 f65443d8abeaedc9d102324565e8368e7c9d90c8
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
package com.gk.firework.Config.Oauth2;
 
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.gk.firework.Domain.AuthorizationInfo;
import com.gk.firework.Domain.Utils.CommonUtil;
import com.gk.firework.Domain.Utils.Constants;
import com.gk.firework.Domain.Utils.Msg;
import com.gk.firework.Domain.Vo.UserVo;
import com.gk.firework.Service.AuthorizationService;
import com.gk.firework.Service.UserService;
import io.jsonwebtoken.Claims;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.util.AntPathMatcher;
 
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;
import java.util.Map;
 
/**
 * AccessToken filter
 *
 * @author zhangby
 * @date 2019-05-20 20:32
 */
public class AccessTokenFilter implements Filter {
    private final Logger logger = LoggerFactory.getLogger(this.getClass());
 
    /**
     * redis service
     */
    IRedisService redisService = SpringContextUtil.getBean(IRedisService.class);
 
    UserService userService = SpringContextUtil.getBean(UserService.class);
 
    AuthorizationService authorizationService = SpringContextUtil.getBean(AuthorizationService.class);
 
    /**
     * do filter
     *
     * @param servletRequest  servletRequest
     * @param servletResponse servletResponse
     * @param filterChain     filterChain
     * @throws IOException      IOException
     * @throws ServletException ServletException
     */
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        response.setHeader("Access-Control-Allow-Origin", request.getHeader("Origin"));
        Msg msg = new Msg();
        try {
            // filter url  && !request.getMethod().equals("OPTIONS")
            if (urlMatcher(request.getRequestURI(), Constants.FILTER_EXCLUDE_PATH)){
                String token = request.getHeader(HttpHeaders.AUTHORIZATION);
                if (null != token && !token.equals("undefined")) {
                    /** 解析token */
                    Claims claims = CommonUtil.parseJWT(token);
                    if (ObjectUtil.isNotNull(claims)) {
                        //设置当前登录用户
                        System.setProperty(Constants.CURRENT_USER_ID, claims.get("user_id").toString());
                        try {
                            //获取redis 查询token是否有效 [jti]
                            String tokenKey = StrUtil.format(RedisKeyEnum.AUTH_TOKEN.getKey(), claims.getId());
                            Object userInfo = redisService.get(tokenKey);
                            if (ObjectUtil.isNotNull(userInfo)) {
                                Map map = JSON.parseObject(userInfo.toString(), Map.class);
                                UserVo userVo = userService.selectUserVoByName(map.get("username").toString());
                                if (null == userVo) {
                                    msg.setCode("100");
                                    msg.setMessage("用户不存在");
                                    returnJson(response, msg);
                                    return;
                                }
                                if (userVo.getIssale() == 1){
                                    if (userVo.getStatus()!=null && userVo.getStatus() != 1){
                                        msg.setCode("100");
                                        msg.setMessage("用户已失效");
                                        returnJson(response, msg);
                                        return;
                                    }
                                    if (userVo.getExpiredate() != null && userVo.getExpiredate().getTime() < System.currentTimeMillis()){
                                        msg.setCode("100");
                                        msg.setMessage("用户已超期");
                                        returnJson(response, msg);
                                        return;
                                    }
 
                                    Object loginObj =  map.get("logintime");
                                    Object authObj =  map.get("auth");
                                    if (loginObj != null && authObj != null){
                                        //通过auth查询授权码最后登录时间
                                        AuthorizationInfo authInfo = authorizationService.selectByUser(userVo.getCompanynumber(),authObj.toString());
                                        if (authInfo == null){
                                            msg.setCode("100");
                                            msg.setMessage("授权码无效");
                                            returnJson(response, msg);
                                            return;
                                        }
                                        if (authInfo.getLasttime().getTime() > Long.parseLong(loginObj.toString())){
                                            redisService.set(tokenKey, userInfo, 0L);
                                            msg.setCode("100");
                                            msg.setMessage("登录失效,请重新登录");
                                            returnJson(response, msg);
                                            return;
                                        }
                                    }
                                }
                                //更新登录超时时间
                                redisService.set(tokenKey, userInfo, 60L*60L*18L);
                            } else {
                                logger.info("998:登录超时,无效认证");
                                msg.setCode("100");
                                msg.setMessage("登录超时,无效认证");
                                returnJson(response, msg);
                                return;
                            }
                        } catch (Exception e) {
                            logger.info("401:非授权访问,无效的token");
                        }
                    } else {
                        logger.info("500: 账户或密码不正确,登录失败");
                    }
                }
                else if(request.getMethod().equals("OPTIONS")) {
                    response.setHeader("Access-Control-Allow-Origin", request.getHeader("Origin"));
                    response.setHeader("Access-Control-Allow-Credentials", "true");
                    response.setHeader("Access-Control-Allow-Methods", "POST, GET, PATCH, DELETE, PUT, OPTIONS");
                    response.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, X-Auth-Token, Authorization");
                    response.setHeader("Access-Control-Max-Age","3600");
                    response.setStatus(HttpStatus.OK.value());
                    return;
                }
                else {
                    logger.info("500: token不存在");
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            //系统异常
            msg.setCode("100");
            msg.setMessage("系统异常请稍后重试");
            returnJson(response, msg);
            response.setStatus(HttpStatus.OK.value());
        }
        filterChain.doFilter(servletRequest, servletResponse);
        //过滤器结束之后销毁
        System.clearProperty(Constants.CURRENT_USER_ID);
    }
 
 
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    }
 
    @Override
    public void destroy() {
 
    }
 
    /**
     * 认证是否需要,验证session url
     *
     * @param real_url
     * @return
     */
    private boolean urlMatcher(String real_url, String pathFilter) {
        AntPathMatcher antPathMatcher = new AntPathMatcher();
        /** 验证添加项url */
        if (StrUtil.isNotBlank(pathFilter)) {
            for (String path : pathFilter.split(",")) {
                if (antPathMatcher.match(path.trim(), real_url.trim())) {
                    return false;
                }
            }
        }
        return true;
    }
 
    /**
     * 返回url
     *
     * @param response
     * @param json
     */
    private void returnJson(HttpServletResponse response, Msg msg) {
        PrintWriter writer = null;
        response.setCharacterEncoding("UTF-8");
        response.setContentType("text/html; charset=utf-8");
        response.setHeader("Access-Control-Allow-Credentials", "true");
        response.setHeader("Access-Control-Allow-Methods", "POST, GET, PATCH, DELETE, PUT, OPTIONS");
        response.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, X-Auth-Token, Authorization");
        response.setHeader("Access-Control-Max-Age","3600");
        try {
            writer = response.getWriter();
            writer.print(JSON.toJSON(msg));
        } catch (IOException e) {
        } finally {
            if (writer != null) {
                writer.close();
            }
        }
    }
}