wisdomisite-java/src/main/java/com/zhgd/xmgl/security/JwtTokenProvider.java
2024-07-03 16:11:21 +08:00

141 lines
5.2 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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 lombok.extern.slf4j.Slf4j;
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
@Slf4j
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<>(16);
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) {
log.error("error", e);
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);
}
}
}