forked from github/dataease
fix: 【ID1003561】登录有效时间似乎不正确
This commit is contained in:
parent
c3e9157761
commit
152c621054
@ -31,7 +31,4 @@ public interface AuthApi {
|
|||||||
@PostMapping("/validateName")
|
@PostMapping("/validateName")
|
||||||
Boolean validateName(Map<String, String> nameDto);
|
Boolean validateName(Map<String, String> nameDto);
|
||||||
|
|
||||||
|
|
||||||
@GetMapping("/test")
|
|
||||||
String test();
|
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,6 @@ import org.apache.shiro.subject.PrincipalCollection;
|
|||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.context.annotation.Lazy;
|
import org.springframework.context.annotation.Lazy;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
@ -13,8 +13,6 @@ public class TokenInfo implements Serializable {
|
|||||||
|
|
||||||
private Long userId;
|
private Long userId;
|
||||||
|
|
||||||
private Long lastLoginTime;
|
|
||||||
|
|
||||||
public String format(){
|
public String format(){
|
||||||
return username + "," +userId;
|
return username + "," +userId;
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,6 @@ import io.dataease.auth.entity.TokenInfo;
|
|||||||
import io.dataease.auth.service.AuthUserService;
|
import io.dataease.auth.service.AuthUserService;
|
||||||
import io.dataease.auth.util.JWTUtils;
|
import io.dataease.auth.util.JWTUtils;
|
||||||
import io.dataease.commons.utils.CommonBeanFactory;
|
import io.dataease.commons.utils.CommonBeanFactory;
|
||||||
import io.dataease.commons.utils.ServletUtils;
|
|
||||||
import io.dataease.i18n.Translator;
|
import io.dataease.i18n.Translator;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.apache.shiro.authc.AuthenticationException;
|
import org.apache.shiro.authc.AuthenticationException;
|
||||||
@ -29,9 +28,6 @@ public class JWTFilter extends BasicHttpAuthenticationFilter {
|
|||||||
|
|
||||||
public final static String expireMessage = "Login token is expire.";
|
public final static String expireMessage = "Login token is expire.";
|
||||||
|
|
||||||
/*@Autowired
|
|
||||||
private AuthUserService authUserService;*/
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 判断用户是否想要登入。
|
* 判断用户是否想要登入。
|
||||||
@ -53,22 +49,15 @@ public class JWTFilter extends BasicHttpAuthenticationFilter {
|
|||||||
String authorization = httpServletRequest.getHeader("Authorization");
|
String authorization = httpServletRequest.getHeader("Authorization");
|
||||||
// 当没有出现登录超时 且需要刷新token 则执行刷新token
|
// 当没有出现登录超时 且需要刷新token 则执行刷新token
|
||||||
if (JWTUtils.loginExpire(authorization)){
|
if (JWTUtils.loginExpire(authorization)){
|
||||||
throw new AuthenticationException(expireMessage);
|
throw new AuthenticationException(expireMessage);
|
||||||
}
|
}
|
||||||
if (JWTUtils.needRefresh(authorization)){
|
if (JWTUtils.needRefresh(authorization)){
|
||||||
String oldAuthorization = authorization;
|
|
||||||
authorization = refreshToken(request, response);
|
authorization = refreshToken(request, response);
|
||||||
JWTUtils.removeTokenExpire(oldAuthorization);
|
|
||||||
}
|
}
|
||||||
// 删除老的操作时间
|
|
||||||
JWTUtils.removeTokenExpire(authorization);
|
|
||||||
// 设置新的操作时间
|
|
||||||
JWTUtils.addTokenExpire(authorization);
|
|
||||||
JWTToken token = new JWTToken(authorization);
|
JWTToken token = new JWTToken(authorization);
|
||||||
Subject subject = getSubject(request, response);
|
Subject subject = getSubject(request, response);
|
||||||
// 提交给realm进行登入,如果错误他会抛出异常并被捕获
|
// 提交给realm进行登入,如果错误他会抛出异常并被捕获
|
||||||
subject.login(token);
|
subject.login(token);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -108,14 +97,8 @@ public class JWTFilter extends BasicHttpAuthenticationFilter {
|
|||||||
}
|
}
|
||||||
String password = user.getPassword();
|
String password = user.getPassword();
|
||||||
|
|
||||||
// 删除老token操作时间
|
|
||||||
// JWTUtils.removeTokenExpire(token);
|
|
||||||
String newToken = JWTUtils.sign(tokenInfo, password);
|
String newToken = JWTUtils.sign(tokenInfo, password);
|
||||||
// 记录新token操作时间
|
|
||||||
// JWTUtils.addTokenExpire(newToken);
|
|
||||||
|
|
||||||
JWTToken jwtToken = new JWTToken(newToken);
|
|
||||||
this.getSubject(request, response).login(jwtToken);
|
|
||||||
// 设置响应的Header头新Token
|
// 设置响应的Header头新Token
|
||||||
HttpServletResponse httpServletResponse = (HttpServletResponse) response;
|
HttpServletResponse httpServletResponse = (HttpServletResponse) response;
|
||||||
httpServletResponse.addHeader("Access-Control-Expose-Headers", "RefreshAuthorization");
|
httpServletResponse.addHeader("Access-Control-Expose-Headers", "RefreshAuthorization");
|
||||||
|
@ -14,10 +14,6 @@ import io.dataease.commons.utils.BeanUtils;
|
|||||||
import io.dataease.commons.utils.CodingUtil;
|
import io.dataease.commons.utils.CodingUtil;
|
||||||
import io.dataease.commons.utils.ServletUtils;
|
import io.dataease.commons.utils.ServletUtils;
|
||||||
|
|
||||||
/*import io.dataease.plugins.config.SpringContextUtil;
|
|
||||||
|
|
||||||
import io.dataease.plugins.xpack.display.dto.response.SysSettingDto;
|
|
||||||
import io.dataease.plugins.xpack.display.service.DisPlayXpackService;*/
|
|
||||||
import io.dataease.i18n.Translator;
|
import io.dataease.i18n.Translator;
|
||||||
import org.apache.commons.lang3.ObjectUtils;
|
import org.apache.commons.lang3.ObjectUtils;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
@ -59,10 +55,9 @@ public class AuthServer implements AuthApi {
|
|||||||
throw new RuntimeException(Translator.get("i18n_id_or_pwd_error"));
|
throw new RuntimeException(Translator.get("i18n_id_or_pwd_error"));
|
||||||
}
|
}
|
||||||
Map<String, Object> result = new HashMap<>();
|
Map<String, Object> result = new HashMap<>();
|
||||||
TokenInfo tokenInfo = TokenInfo.builder().userId(user.getUserId()).username(username).lastLoginTime(System.currentTimeMillis()).build();
|
TokenInfo tokenInfo = TokenInfo.builder().userId(user.getUserId()).username(username).build();
|
||||||
String token = JWTUtils.sign(tokenInfo, realPwd);
|
String token = JWTUtils.sign(tokenInfo, realPwd);
|
||||||
// 记录token操作时间
|
// 记录token操作时间
|
||||||
JWTUtils.addTokenExpire(token);
|
|
||||||
result.put("token", token);
|
result.put("token", token);
|
||||||
ServletUtils.setToken(token);
|
ServletUtils.setToken(token);
|
||||||
return result;
|
return result;
|
||||||
@ -107,20 +102,5 @@ public class AuthServer implements AuthApi {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String test() {
|
|
||||||
SysUserEntity userById = authUserService.getUserById(4L);
|
|
||||||
String nickName = userById.getNickName();
|
|
||||||
// System.out.println(nickName);
|
|
||||||
/* Map<String, DisPlayXpackService> beansOfType = SpringContextUtil.getApplicationContext().getBeansOfType(DisPlayXpackService.class);
|
|
||||||
for (Map.Entry entry : beansOfType.entrySet()) {
|
|
||||||
Object key = entry.getKey();
|
|
||||||
DisPlayXpackService value = (DisPlayXpackService)entry.getValue();
|
|
||||||
List<SysSettingDto> sysSettingDtos = value.systemSettings();
|
|
||||||
|
|
||||||
String name = entry.getValue().getClass().getName();
|
|
||||||
System.out.println("key: "+ key + ", value: "+ name);
|
|
||||||
}*/
|
|
||||||
return "apple";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -11,8 +11,7 @@ import io.dataease.commons.utils.CommonBeanFactory;
|
|||||||
import org.apache.commons.lang3.ObjectUtils;
|
import org.apache.commons.lang3.ObjectUtils;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.apache.shiro.authc.AuthenticationException;
|
import org.apache.shiro.authc.AuthenticationException;
|
||||||
import org.springframework.cache.Cache;
|
|
||||||
import org.springframework.cache.CacheManager;
|
|
||||||
import org.springframework.core.env.Environment;
|
import org.springframework.core.env.Environment;
|
||||||
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
@ -38,17 +37,10 @@ public class JWTUtils {
|
|||||||
public static boolean verify(String token, TokenInfo tokenInfo, String secret) {
|
public static boolean verify(String token, TokenInfo tokenInfo, String secret) {
|
||||||
Algorithm algorithm = Algorithm.HMAC256(secret);
|
Algorithm algorithm = Algorithm.HMAC256(secret);
|
||||||
JWTVerifier verifier = JWT.require(algorithm)
|
JWTVerifier verifier = JWT.require(algorithm)
|
||||||
.withClaim("lastLoginTime", tokenInfo.getLastLoginTime())
|
|
||||||
.withClaim("username", tokenInfo.getUsername())
|
.withClaim("username", tokenInfo.getUsername())
|
||||||
.withClaim("userId", tokenInfo.getUserId())
|
.withClaim("userId", tokenInfo.getUserId())
|
||||||
.build();
|
.build();
|
||||||
verifier.verify(token);
|
verifier.verify(token);
|
||||||
if (loginExpire(token)){
|
|
||||||
// 登录超时
|
|
||||||
throw new AuthenticationException(JWTFilter.expireMessage);
|
|
||||||
// 前端拦截 登录超时状态 直接logout
|
|
||||||
//return false;
|
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -60,11 +52,10 @@ public class JWTUtils {
|
|||||||
DecodedJWT jwt = JWT.decode(token);
|
DecodedJWT jwt = JWT.decode(token);
|
||||||
String username = jwt.getClaim("username").asString();
|
String username = jwt.getClaim("username").asString();
|
||||||
Long userId = jwt.getClaim("userId").asLong();
|
Long userId = jwt.getClaim("userId").asLong();
|
||||||
Long lastLoginTime = jwt.getClaim("lastLoginTime").asLong();
|
if (StringUtils.isEmpty(username) || ObjectUtils.isEmpty(userId) ){
|
||||||
if (StringUtils.isEmpty(username) || ObjectUtils.isEmpty(userId) || ObjectUtils.isEmpty(lastLoginTime)){
|
|
||||||
throw new RuntimeException("token格式错误!");
|
throw new RuntimeException("token格式错误!");
|
||||||
}
|
}
|
||||||
TokenInfo tokenInfo = TokenInfo.builder().username(username).userId(userId).lastLoginTime(lastLoginTime).build();
|
TokenInfo tokenInfo = TokenInfo.builder().username(username).userId(userId).build();
|
||||||
return tokenInfo;
|
return tokenInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -84,24 +75,17 @@ public class JWTUtils {
|
|||||||
*/
|
*/
|
||||||
public static boolean loginExpire(String token){
|
public static boolean loginExpire(String token){
|
||||||
if (Login_Interval==0) {
|
if (Login_Interval==0) {
|
||||||
String property = CommonBeanFactory.getBean(Environment.class).getProperty("dataease.login_timeout");
|
|
||||||
// 默认超时时间是8h
|
// 默认超时时间是8h
|
||||||
int minute = StringUtils.isNotEmpty(property) ? Integer.parseInt(property): (8*60);
|
int minute = CommonBeanFactory.getBean(Environment.class).getProperty("dataease.login_timeout", Integer.class, 8*60);
|
||||||
// 分钟换算成毫秒
|
// 分钟换算成毫秒
|
||||||
Login_Interval = minute * 1000 * 60;
|
Login_Interval = minute * 1000 * 60;
|
||||||
}
|
}
|
||||||
Long now = System.currentTimeMillis();
|
|
||||||
Long lastOperateTime = tokenLastOperateTime(token);
|
Long lastOperateTime = tokenLastOperateTime(token);
|
||||||
boolean isExpire = false;
|
boolean isExpire = true;
|
||||||
if (lastOperateTime != null) {
|
if (lastOperateTime != null) {
|
||||||
|
Long now = System.currentTimeMillis();
|
||||||
isExpire = now - lastOperateTime > Login_Interval;
|
isExpire = now - lastOperateTime > Login_Interval;
|
||||||
}
|
}
|
||||||
if (isExpire) {
|
|
||||||
// System.out.println("-----------------------");
|
|
||||||
// System.out.println("-----上次操作时间是["+lastOperateTime+"]-----");
|
|
||||||
// System.out.println("-----当前操作时间是["+now+"]-----");
|
|
||||||
// System.out.println("-----------------------");
|
|
||||||
}
|
|
||||||
return isExpire;
|
return isExpire;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -127,10 +111,8 @@ public class JWTUtils {
|
|||||||
Algorithm algorithm = Algorithm.HMAC256(secret);
|
Algorithm algorithm = Algorithm.HMAC256(secret);
|
||||||
// 附带username信息
|
// 附带username信息
|
||||||
return JWT.create()
|
return JWT.create()
|
||||||
.withClaim("lastLoginTime", tokenInfo.getLastLoginTime())
|
|
||||||
.withClaim("username", tokenInfo.getUsername())
|
.withClaim("username", tokenInfo.getUsername())
|
||||||
.withClaim("userId", tokenInfo.getUserId())
|
.withClaim("userId", tokenInfo.getUserId())
|
||||||
.withClaim("exp", date)
|
|
||||||
.withExpiresAt(date)
|
.withExpiresAt(date)
|
||||||
.sign(algorithm);
|
.sign(algorithm);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
@ -162,23 +144,9 @@ public class JWTUtils {
|
|||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public static Long tokenLastOperateTime(String token){
|
public static Long tokenLastOperateTime(String token){
|
||||||
CacheManager cacheManager = CommonBeanFactory.getBean(CacheManager.class);
|
DecodedJWT jwt = JWT.decode(token);
|
||||||
Cache tokens_expire = cacheManager.getCache("tokens_expire");
|
Date expiresAt = jwt.getExpiresAt();
|
||||||
Long expTime = tokens_expire.get(token, Long.class);
|
return expiresAt.getTime();
|
||||||
return expTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void removeTokenExpire(String token){
|
|
||||||
CacheManager cacheManager = CommonBeanFactory.getBean(CacheManager.class);
|
|
||||||
Cache tokens_expire = cacheManager.getCache("tokens_expire");
|
|
||||||
tokens_expire.evict(token);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void addTokenExpire(String token){
|
|
||||||
CacheManager cacheManager = CommonBeanFactory.getBean(CacheManager.class);
|
|
||||||
Cache tokens_expire = cacheManager.getCache("tokens_expire");
|
|
||||||
long now = System.currentTimeMillis();
|
|
||||||
tokens_expire.put(token, now);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -69,16 +69,5 @@
|
|||||||
memoryStoreEvictionPolicy="LRU"
|
memoryStoreEvictionPolicy="LRU"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<cache
|
|
||||||
name="tokens_expire"
|
|
||||||
eternal="false"
|
|
||||||
maxElementsInMemory="100"
|
|
||||||
maxElementsOnDisk="1000"
|
|
||||||
overflowToDisk="true"
|
|
||||||
diskPersistent="true"
|
|
||||||
timeToIdleSeconds="1800"
|
|
||||||
timeToLiveSeconds="3600"
|
|
||||||
memoryStoreEvictionPolicy="LRU"
|
|
||||||
/>
|
|
||||||
|
|
||||||
</ehcache>
|
</ehcache>
|
Loading…
Reference in New Issue
Block a user