Skip to content

Commit e2b63a4

Browse files
committed
feat: 添加 Token 请求头的校验过滤器
1 parent 5f4ab55 commit e2b63a4

2 files changed

Lines changed: 94 additions & 0 deletions

File tree

simple-framework/src/main/java/top/cadecode/framework/config/SecurityConfig.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,9 @@
1414
import org.springframework.security.core.userdetails.UserDetailsService;
1515
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
1616
import org.springframework.security.crypto.password.PasswordEncoder;
17+
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
1718
import top.cadecode.framework.security.*;
19+
import top.cadecode.framework.security.filter.JwtTokenAuthenticationFilter;
1820

1921
/**
2022
* @author Cade Li
@@ -35,6 +37,7 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
3537
private final SignOutSuccessHandler signOutSuccessHandler;
3638
private final NoAuthenticationHandler noAuthenticationHandler;
3739
private final NoAuthorityHandler noAuthorityHandler;
40+
private final JwtTokenAuthenticationFilter jwtTokenAuthenticationFilter;
3841

3942
@Bean
4043
public PasswordEncoder passwordEncoder() {
@@ -69,6 +72,8 @@ protected void configure(HttpSecurity http) throws Exception {
6972
.exceptionHandling()
7073
.authenticationEntryPoint(noAuthenticationHandler)
7174
.accessDeniedHandler(noAuthorityHandler);
75+
// 注册 JWT 校验过滤器
76+
http.addFilterBefore(jwtTokenAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);
7277
}
7378

7479
@Override
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
package top.cadecode.framework.security.filter;
2+
3+
import com.nimbusds.jwt.JWTClaimsSet;
4+
import lombok.RequiredArgsConstructor;
5+
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
6+
import org.springframework.security.core.authority.SimpleGrantedAuthority;
7+
import org.springframework.security.core.context.SecurityContextHolder;
8+
import org.springframework.security.web.authentication.WebAuthenticationDetails;
9+
import org.springframework.stereotype.Component;
10+
import org.springframework.web.filter.OncePerRequestFilter;
11+
import top.cadecode.common.core.exception.CommonException;
12+
import top.cadecode.common.core.response.CommonResponse;
13+
import top.cadecode.common.enums.AuthErrorEnum;
14+
import top.cadecode.common.util.JsonUtil;
15+
import top.cadecode.common.util.StringUtil;
16+
import top.cadecode.common.util.TokenUtil;
17+
import top.cadecode.common.util.WebUtil;
18+
import top.cadecode.framework.model.entity.SecurityUser;
19+
20+
import javax.servlet.FilterChain;
21+
import javax.servlet.ServletException;
22+
import javax.servlet.http.HttpServletRequest;
23+
import javax.servlet.http.HttpServletResponse;
24+
import java.io.IOException;
25+
import java.text.ParseException;
26+
import java.util.List;
27+
import java.util.stream.Collectors;
28+
29+
/**
30+
* @author Cade Li
31+
* @date 2021/12/12
32+
* @description JWT Token 校验过滤器
33+
*/
34+
@Component
35+
@RequiredArgsConstructor
36+
public class JwtTokenAuthenticationFilter extends OncePerRequestFilter {
37+
38+
private final TokenUtil tokenUtil;
39+
40+
@Override
41+
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
42+
FilterChain filterChain) throws ServletException, IOException {
43+
String requestURI = request.getRequestURI();
44+
// 取出 token
45+
String token = request.getHeader(tokenUtil.getHeader());
46+
// token 为空,则不拦截
47+
if (StringUtil.isEmpty(token)) {
48+
filterChain.doFilter(request, response);
49+
return;
50+
}
51+
// 校验 Token
52+
try {
53+
checkToken(request, response, token);
54+
filterChain.doFilter(request, response);
55+
} catch (Exception e) {
56+
writeResponse(response, AuthErrorEnum.TOKEN_ERROR, requestURI);
57+
}
58+
}
59+
60+
private void checkToken(HttpServletRequest request, HttpServletResponse response, String token) throws Exception {
61+
// 取出 token 内容
62+
JWTClaimsSet claimsSet = tokenUtil.verifyToken(token);
63+
// 判断过期时间
64+
if (claimsSet.getExpirationTime().getTime() < System.currentTimeMillis()) {
65+
writeResponse(response, AuthErrorEnum.TOKEN_EXPIRED, request.getRequestURI());
66+
return;
67+
}
68+
// 认证通过,设置认证信息
69+
long id = claimsSet.getLongClaim("id");
70+
List<String> roles = claimsSet.getStringListClaim("roles");
71+
SecurityUser securityUser = new SecurityUser();
72+
securityUser.setId(id);
73+
securityUser.setAuthorities(roles.stream()
74+
.map(SimpleGrantedAuthority::new)
75+
.collect(Collectors.toList()));
76+
// 构造 UsernamePasswordAuthenticationToken
77+
UsernamePasswordAuthenticationToken authentication =
78+
new UsernamePasswordAuthenticationToken(securityUser, null, securityUser.getAuthorities());
79+
// 设置认证信息,用于后面的过滤器使用
80+
authentication.setDetails(new WebAuthenticationDetails(request));
81+
SecurityContextHolder.getContext().setAuthentication(authentication);
82+
}
83+
84+
private void writeResponse(HttpServletResponse response, AuthErrorEnum authErrorEnum, String requestURI) {
85+
CommonResponse<Object> commonResponse = CommonResponse.of(authErrorEnum).path(requestURI);
86+
WebUtil.writeJsonToResponse(response, JsonUtil.objToStr(commonResponse));
87+
}
88+
89+
}

0 commit comments

Comments
 (0)