139 lines
5.2 KiB
Java
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);
|
|
}
|
|
}
|
|
|
|
}
|