wisdomisite-java/src/main/java/com/zhgd/xmgl/security/JwtTokenProvider.java
2023-12-14 17:40:15 +08:00

139 lines
5.2 KiB
Java

package com.zhgd.xmgl.security;
import cn.hutool.core.util.IdUtil;
import com.zhgd.exception.CustomException;
import com.zhgd.redis.lock.RedisRepository;
import com.zhgd.xmgl.modules.basicdata.mapper.SystemUserMapper;
import com.zhgd.xmgl.util.EnvironmentUtil;
import io.jsonwebtoken.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatus;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import javax.servlet.http.HttpServletRequest;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
/**
* @program: devManage
* @description: JWTtoken生成工具
* @author: Mr.Peng
* @create: 2019-09-24 10:46
**/
@Component
public class JwtTokenProvider {
@Value("${security.jwt.token.secret-key}")
private String secretKey;
@Value("${userTokenExpireMinute:10}")
private Integer userTokenExpireMinute;
@Autowired
private RedisRepository redisRepository;
private final String USER_TOKEN_EXPIRE_PREFIX = "USER_TOKEN_EXPIRE:";
private static ConcurrentHashMap<String, String> userMap = new ConcurrentHashMap<>();
@Autowired
private MyUserDetailsImpl myUserDetailsImpl;
@PostConstruct
protected void init() {
secretKey = Base64.getEncoder().encodeToString(secretKey.getBytes());
}
/**
* @param username
* @param validityInMilliseconds 单位是秒
* @return
*/
public String createToken(String username, Integer validityInMilliseconds) {
return createToken(username, validityInMilliseconds, null);
}
/**
* @param username
* @param validityInMilliseconds 单位是秒
* @return
*/
public String createToken(String username, Integer validityInMilliseconds, Integer loginTimeOut) {
String uuid = IdUtil.simpleUUID();
Map<String, Object> claims = new HashMap<>();
claims.put("uuid", uuid);
claims.put("account", username);
claims.put("loginTimeOut", loginTimeOut);
Date now = new Date();
Date validity = new Date(now.getTime() + validityInMilliseconds * 1000L);
String token = Jwts.builder()//
.setClaims(claims)//
.setIssuedAt(now)//
.setExpiration(validity)//过期时间秒
.signWith(SignatureAlgorithm.HS256, secretKey)//
.compact();
userMap.put(username, token);
//刷新token
String key = USER_TOKEN_EXPIRE_PREFIX + EnvironmentUtil.getActiveEnvironment() + ":" + username + ":" + uuid;
redisRepository.set(key, "", userTokenExpireMinute * 60L);
return token;
}
public Authentication getAuthentication(String token) {
UserDetails userDetails = myUserDetailsImpl.loadUserByUsername(getUsername(token));
return new UsernamePasswordAuthenticationToken(userDetails, "", userDetails.getAuthorities());
}
public String getUsername(String token) {
Map<String, Object> cs = (Map<String, Object>) Jwts.parser().setSigningKey(secretKey).parseClaimsJws(token).getBody();
return (String) cs.get("account");
}
public String resolveToken(HttpServletRequest req) {
//String bearerToken=req.getParameter("token");
String bearerToken = req.getHeader("Authorization");
if (bearerToken != null && bearerToken.startsWith("Bearer ")) {
return bearerToken.substring(7);
}
return bearerToken;
}
public boolean validateToken(String token) {
try {
JwtParser jwtParser = Jwts.parser().setSigningKey(secretKey);
Jws<Claims> claims = jwtParser.parseClaimsJws(token);
Claims body = claims.getBody();
if (body.getExpiration().before(new Date())) {
return false;
}
Map<String, Object> cs = (Map<String, Object>) body;
if (Objects.equals(cs.get("loginTimeOut"), 1)) {
//判断token过期没有
String key = USER_TOKEN_EXPIRE_PREFIX + EnvironmentUtil.getActiveEnvironment() + ":" + cs.get("account") + ":" + cs.get("uuid");
if (redisRepository.get(key) == null) {
return false;
}
//刷新token
redisRepository.set(key, "", userTokenExpireMinute * 60L);
}
return true;
} catch (JwtException | IllegalArgumentException e) {
e.printStackTrace();
throw new CustomException("Expired or invalid JWT token", HttpStatus.FORBIDDEN);
}
}
public void valiadteLogin(String token) {
String userName = getUsername(token);
if (userMap.containsKey(userName)) {
if (!token.equals(userMap.get(userName))) {
throw new CustomException("该账户已其他地方登录", HttpStatus.FORBIDDEN);
}
} else {
userMap.put(userName, token);
}
}
}