org.macrocloud.kernel.security.utils.SecureUtil Maven / Gradle / Ivy
package org.macrocloud.kernel.security.utils;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import lombok.SneakyThrows;
import org.macrocloud.kernel.auth.TokenInfo;
import org.macrocloud.kernel.auth.exception.SecureException;
import org.macrocloud.kernel.auth.utils.AuthUtil;
import org.macrocloud.kernel.auth.utils.JwtUtil;
import org.macrocloud.kernel.launch.constant.TokenConstant;
import org.macrocloud.kernel.security.constant.SecureConstant;
import org.macrocloud.kernel.security.provider.IClientDetails;
import org.macrocloud.kernel.security.provider.IClientDetailsService;
import org.macrocloud.kernel.toolkit.utils.Charsets;
import org.macrocloud.kernel.toolkit.utils.Func;
import org.macrocloud.kernel.toolkit.utils.SpringUtil;
import org.macrocloud.kernel.toolkit.utils.StringPool;
import org.macrocloud.kernel.toolkit.utils.StringUtil;
import org.macrocloud.kernel.toolkit.utils.WebUtil;
import javax.crypto.spec.SecretKeySpec;
import java.security.Key;
import java.util.*;
/**
* Secure工具类
*
*/
public class SecureUtil extends AuthUtil {
private final static String CLIENT_ID = TokenConstant.CLIENT_ID;
private static IClientDetailsService clientDetailsService;
/**
* 获取客户端服务类
*
* @return clientDetailsService
*/
private static IClientDetailsService getClientDetailsService() {
if (clientDetailsService == null) {
clientDetailsService = SpringUtil.getBean(IClientDetailsService.class);
}
return clientDetailsService;
}
/**
* 创建令牌
*
* @param user user
* @param audience audience
* @param issuer issuer
* @param tokenType tokenType
* @return jwt
*/
public static TokenInfo createJWT(Map user, String audience, String issuer, String tokenType) {
String[] tokens = extractAndDecodeHeader();
String clientId = tokens[0];
String clientSecret = tokens[1];
// 获取客户端信息
IClientDetails clientDetails = clientDetails(clientId);
// 校验客户端信息
if (!validateClient(clientDetails, clientId, clientSecret)) {
throw new SecureException("client authentication failed, please check the header parameters");
}
SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
long nowMillis = System.currentTimeMillis();
Date now = new Date(nowMillis);
//生成签名密钥
byte[] apiKeySecretBytes = Base64.getDecoder().decode(JwtUtil.getBase64Security());
Key signingKey = new SecretKeySpec(apiKeySecretBytes, signatureAlgorithm.getJcaName());
//添加构成JWT的类 byte[] apiKeySecretBytes = Base64.getDecoder().decode(JwtUtil.getBase64Security());
JwtBuilder builder = Jwts.builder().setHeaderParam("typ", "JWT")
.setIssuer(issuer)
.setAudience(audience)
.signWith(signingKey);
//设置JWT参数
user.forEach(builder::claim);
//设置应用id
builder.claim(CLIENT_ID, clientId);
//添加Token过期时间
long expireMillis;
if (tokenType.equals(TokenConstant.ACCESS_TOKEN)) {
expireMillis = clientDetails.getAccessTokenValidity() * 1000L;
} else if (tokenType.equals(TokenConstant.REFRESH_TOKEN)) {
expireMillis = clientDetails.getRefreshTokenValidity() * 1000L;
} else {
expireMillis = getExpire();
}
long expMillis = nowMillis + expireMillis;
Date exp = new Date(expMillis);
builder.setExpiration(exp).setNotBefore(now);
//组装Token信息
TokenInfo tokenInfo = new TokenInfo();
tokenInfo.setToken(builder.compact());
tokenInfo.setExpire((int) (expireMillis / 1000L));
//Token状态配置, 仅在生成AccessToken时候执行
if (TokenConstant.ACCESS_TOKEN.equals(tokenType)) {
String tenantId = String.valueOf(user.get(TokenConstant.TENANT_ID));
String userId = String.valueOf(user.get(TokenConstant.USER_ID));
}
return tokenInfo;
}
/**
* 获取过期时间(次日凌晨3点)
*
* @return expire
*/
public static long getExpire() {
Calendar cal = Calendar.getInstance();
cal.add(Calendar.DAY_OF_YEAR, 1);
cal.set(Calendar.HOUR_OF_DAY, 3);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.MILLISECOND, 0);
return cal.getTimeInMillis() - System.currentTimeMillis();
}
/**
* 客户端信息解码
*/
@SneakyThrows
public static String[] extractAndDecodeHeader() {
// 获取请求头客户端信息
String header = Objects.requireNonNull(WebUtil.getRequest()).getHeader(SecureConstant.BASIC_HEADER_KEY);
header = Func.toStr(header).replace(SecureConstant.BASIC_HEADER_PREFIX_EXT, SecureConstant.BASIC_HEADER_PREFIX);
if (!header.startsWith(SecureConstant.BASIC_HEADER_PREFIX)) {
throw new SecureException("no client information in request header");
}
byte[] base64Token = header.substring(6).getBytes(Charsets.UTF_8_NAME);
byte[] decoded;
try {
decoded = Base64.getDecoder().decode(base64Token);
} catch (IllegalArgumentException var7) {
throw new RuntimeException("failed to decode basic authentication token");
}
String token = new String(decoded, Charsets.UTF_8_NAME);
int index = token.indexOf(StringPool.COLON);
if (index == -1) {
throw new RuntimeException("invalid basic authentication token");
} else {
return new String[]{token.substring(0, index), token.substring(index + 1)};
}
}
/**
* 获取请求头中的客户端id
*/
public static String getClientIdFromHeader() {
String[] tokens = extractAndDecodeHeader();
assert tokens.length == 2;
return tokens[0];
}
/**
* 获取客户端信息
*
* @param clientId 客户端id
* @return clientDetails
*/
private static IClientDetails clientDetails(String clientId) {
return getClientDetailsService().loadClientByClientId(clientId);
}
/**
* 校验Client
*
* @param clientId 客户端id
* @param clientSecret 客户端密钥
* @return boolean
*/
private static boolean validateClient(IClientDetails clientDetails, String clientId, String clientSecret) {
if (clientDetails != null) {
return StringUtil.equals(clientId, clientDetails.getClientId()) && StringUtil.equals(clientSecret, clientDetails.getClientSecret());
}
return false;
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy