All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.diboot.iam.util.TokenUtils Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (c) 2015-2020, www.dibo.ltd ([email protected]).
 * 

* Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of * the License at *

* https://www.apache.org/licenses/LICENSE-2.0 *

* Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. */ package com.diboot.iam.util; import com.diboot.core.cache.BaseCacheManager; import com.diboot.core.config.BaseConfig; import com.diboot.core.exception.InvalidUsageException; import com.diboot.core.util.ContextHolder; import com.diboot.core.util.S; import com.diboot.core.util.V; import com.diboot.iam.config.Cons; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import jakarta.servlet.ServletResponse; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; /** * Token相关操作类 * @author Yangzhao * @version v2.0 * @date 2019/6/6 */ public class TokenUtils { private static final Logger log = LoggerFactory.getLogger(TokenUtils.class); private static final String AUTH_HEADER = getConfigValue("diboot.iam.token-header-key", "Authorization"); public static final int EXPIRES_IN_MINUTES = getConfigIntValue("diboot.iam.token-expires-minutes", 60); /** * 从请求头中获取客户端发来的token * @param request * @return */ public static String getRequestToken(HttpServletRequest request) { String authtoken = request.getHeader(AUTH_HEADER); if(authtoken != null){ if(authtoken.startsWith(Cons.TOKEN_PREFIX_BEARER)){ authtoken = authtoken.substring(Cons.TOKEN_PREFIX_BEARER.length()); } authtoken = authtoken.trim(); } if(V.isEmpty(authtoken)){ log.warn("请求未指定token: {}", authtoken); return null; } if(!isActiveAccessToken(authtoken)){ log.warn("已过期或非系统颁发的token: {}", authtoken); return null; } return authtoken; } /** * 生成Token * @return */ public static String generateToken(){ return S.newUuid(); } /** * 临近过期时生成新的token * @param cachedUserInfo * @return */ public static synchronized String responseNewTokenIfRequired(ServletResponse response, String cachedUserInfo) { if(isCloseToExpired(cachedUserInfo)){ //将刷新的token放入response header String refreshToken = generateToken(); cacheRefreshToken(refreshToken, cachedUserInfo); ((HttpServletResponse)response).setHeader(AUTH_HEADER, refreshToken); log.debug("写回刷新token :{}", refreshToken); return refreshToken; } return null; } /** * 缓存新的token * @param accessToken * @param userInfoStr */ public static void cacheAccessToken(String accessToken, String userInfoStr) { getIamCacheManager().putCacheObj(Cons.CACHE_TOKEN_USERINFO, accessToken, userInfoStr); } /** * 退出时移除失效的全部token * @param accessToken */ public static void removeAccessTokens(String accessToken) { getIamCacheManager().removeCacheObj(Cons.CACHE_TOKEN_USERINFO, accessToken); } /** * 获取缓存的token信息 * @param accessToken * @return */ public static String getCachedUserInfoStr(String accessToken) { String userInfoStr = getIamCacheManager().getCacheString(Cons.CACHE_TOKEN_USERINFO, accessToken); if(userInfoStr == null){ log.info("token {} 缓存信息不存在", accessToken); } return userInfoStr; } /** * token是否有效: 未过期/刷新token 均有效 * @param accessToken * @return */ public static boolean isActiveAccessToken(String accessToken) { String userInfoStr = getCachedUserInfoStr(accessToken); if(V.isEmpty(userInfoStr)){ return false; } if(isExpired(userInfoStr)){ IamSecurityUtils.logoutByToken(accessToken); return false; } return true; } /** * 缓存刷新token * @param refreshToken */ public synchronized static void cacheRefreshToken(String refreshToken, String userInfoStr) { String prefixTemp = S.substringBeforeLast(userInfoStr, Cons.SEPARATOR_COMMA); //如果是刷新token则更新颁发时间 userInfoStr = prefixTemp + Cons.SEPARATOR_COMMA + System.currentTimeMillis(); cacheAccessToken(refreshToken, userInfoStr); } /** * 是否已过期 * @param userInfoStr * @return */ private static final int EXPIRES_MINUTES_INDEX = 4, ISSUED_AT_INDEX = 5; public static boolean isExpired(String userInfoStr){ if(V.isEmpty(userInfoStr)){ return false; } String[] userFields = S.split(userInfoStr); int expiresInMinutes = Integer.parseInt(userFields[EXPIRES_MINUTES_INDEX]); // 获取当前token的过期时间 long issuedAt = Long.parseLong(userFields[ISSUED_AT_INDEX]); // 获取当前token的过期时间 long expiredBefore = issuedAt + expiresInMinutes * 60000L; return System.currentTimeMillis() > expiredBefore; } /** * 是否临近过期 * @param userInfoStr * @return */ public static boolean isCloseToExpired(String userInfoStr){ if(V.isEmpty(userInfoStr)){ return false; } String[] userFields = S.split(userInfoStr); int expiresInMinutes = Integer.parseInt(userFields[EXPIRES_MINUTES_INDEX]); // 当前token是否临近过期 long current = System.currentTimeMillis(); long issuedAt = Long.parseLong(userFields[ISSUED_AT_INDEX]); long expiration = issuedAt + expiresInMinutes* 60000L; long remaining = expiration - current; if(remaining > 0){ long elapsed = current - issuedAt; // 小于1/4 则更新 double past = ((double) elapsed / remaining); return past > 3.0; } return false; } private static BaseCacheManager iamCacheManager; private static BaseCacheManager getIamCacheManager() { if(iamCacheManager == null) { iamCacheManager = (BaseCacheManager)ContextHolder.getBean("iamCacheManager"); if(iamCacheManager == null) { throw new InvalidUsageException("exception.invalidUsage.tokenUtils.getIamCacheManager.message"); } } return iamCacheManager; } /** * 获取配置参数值 * @return */ private static String getConfigValue(String key, String defaultValue){ String value = BaseConfig.getProperty(key); return value != null? value : defaultValue; } /** * 获取配置参数值 * @return */ private static int getConfigIntValue(String key, int defaultValue){ String value = BaseConfig.getProperty(key); return value != null? Integer.parseInt(value) : defaultValue; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy