-
Notifications
You must be signed in to change notification settings - Fork 140
/
JwtTokenFilter.java
138 lines (110 loc) · 5.21 KB
/
JwtTokenFilter.java
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
package com.zzx.filter;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.zzx.config.JwtConfig;
import com.zzx.config.RedisConfig;
import com.zzx.controller.ErrorController;
import com.zzx.model.entity.Result;
import com.zzx.model.entity.StatusCode;
import com.zzx.service.UserService;
import com.zzx.utils.JwtTokenUtil;
import com.zzx.utils.RequestUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.TimeUnit;
@Component
public class JwtTokenFilter extends OncePerRequestFilter {
@Autowired
private UserService userService;
@Autowired
private RequestUtil requestUtil;
/**
* 范围时间内限制最大请求次数
*/
private static final int LIMIT_REQUEST_FREQUENCY_COUNT = 8;
@Autowired
private RedisTemplate<String, String> redisTemplate;
@Autowired
private JwtConfig jwtConfig;
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException {
String ipAddress = requestUtil.getIpAddress(request);
String redisKey = RedisConfig.REDIS_IP_PREFIX + ipAddress;
//缓存时间 2s 会影响swagger-ui的使用,建议开发时调整JwtTokenFilter.LIMIT_REQUEST_FREQUENCY_COUNT的值
// 127.0.0.1_/blog/hotBlog
String value = redisTemplate.opsForValue().get(redisKey);
if (null != value) {
Integer count = Integer.parseInt(value);
if (count > JwtTokenFilter.LIMIT_REQUEST_FREQUENCY_COUNT) {
//请求频繁
request.getRequestDispatcher(ErrorController.FREQUENT_OPERATION).forward(request, response);
return;
} else {
count++;
redisTemplate.opsForValue().set(redisKey, count.toString(), RedisConfig.REDIS_LIMIT_REQUEST_FREQUENCY_TIME, TimeUnit.MILLISECONDS);
}
} else {
redisTemplate.opsForValue().set(redisKey, "1", RedisConfig.REDIS_LIMIT_REQUEST_FREQUENCY_TIME, TimeUnit.MILLISECONDS);
}
checkPermission(request, response, chain);
}
/**
* 校验权限
*
* @param request
* @param response
*/
private void checkPermission(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
boolean giveFlag = false;
String authHeader = request.getHeader(jwtConfig.getHeader());
if (authHeader != null && authHeader.startsWith(jwtConfig.getPrefix())) {
UserDetails userDetails = userService.loadUserByToken(authHeader);
if (null != userDetails) {
//此请求是否校验过
if (SecurityContextHolder.getContext().getAuthentication() == null) {
UsernamePasswordAuthenticationToken authentication =
new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
SecurityContextHolder.getContext().setAuthentication(authentication);
}
} else {
giveFlag = true;
}
} else {
//token校验失败
giveFlag = true;
}
if (giveFlag) {
//token因某原因校验失败,给定游客身份->[游客]角色未写入数据库角色表
// 省去每个方法上的permitAll注解
List<SimpleGrantedAuthority> authorities = new ArrayList<>();
authorities.add(new SimpleGrantedAuthority("NORMAL"));
//假定身份
User user = new User("NORMAL", "NORMAL", authorities);
UsernamePasswordAuthenticationToken authentication =
new UsernamePasswordAuthenticationToken(user, null, user.getAuthorities());
//赋予权限
SecurityContextHolder.getContext().setAuthentication(authentication);
}
chain.doFilter(request, response);
}
}