package com.qianwen.core.secure.utils;
|
|
import io.jsonwebtoken.JwtBuilder;
|
import io.jsonwebtoken.Jwts;
|
import io.jsonwebtoken.SignatureAlgorithm;
|
import java.security.Key;
|
import java.util.Base64;
|
import java.util.Calendar;
|
import java.util.Date;
|
import java.util.Map;
|
import java.util.Objects;
|
import javax.crypto.spec.SecretKeySpec;
|
import javax.servlet.http.HttpServletRequest;
|
import com.qianwen.core.jwt.JwtUtil;
|
import com.qianwen.core.jwt.props.JwtProperties;
|
import com.qianwen.core.secure.TokenInfo;
|
import com.qianwen.core.secure.constant.SecureConstant;
|
import com.qianwen.core.secure.exception.SecureException;
|
import com.qianwen.core.secure.provider.IClientDetails;
|
import com.qianwen.core.secure.provider.IClientDetailsService;
|
import com.qianwen.core.tool.utils.Charsets;
|
import com.qianwen.core.tool.utils.Func;
|
import com.qianwen.core.tool.utils.SpringUtil;
|
import com.qianwen.core.tool.utils.StringUtil;
|
import com.qianwen.core.tool.utils.WebUtil;
|
|
/* loaded from: blade-core-secure-9.3.0.0-SNAPSHOT.jar:org/springblade/core/secure/utils/SecureUtil.class */
|
public class SecureUtil extends AuthUtil {
|
private static final String CLIENT_ID = "client_id";
|
private static IClientDetailsService clientDetailsService;
|
private static JwtProperties jwtProperties;
|
static final /* synthetic */ boolean $assertionsDisabled;
|
|
static {
|
$assertionsDisabled = !SecureUtil.class.desiredAssertionStatus();
|
}
|
|
private static IClientDetailsService getClientDetailsService() {
|
if (clientDetailsService == null) {
|
clientDetailsService = (IClientDetailsService) SpringUtil.getBean(IClientDetailsService.class);
|
}
|
return clientDetailsService;
|
}
|
|
private static JwtProperties getJwtProperties() {
|
if (jwtProperties == null) {
|
jwtProperties = (JwtProperties) SpringUtil.getBean(JwtProperties.class);
|
}
|
return jwtProperties;
|
}
|
|
public static TokenInfo createJWT(Map<String, Object> user, String audience, String issuer, String tokenType) {
|
long expireMillis;
|
String[] tokens = extractAndDecodeHeader();
|
String clientId = tokens[0];
|
String clientSecret = tokens[1];
|
IClientDetails clientDetails = clientDetails(clientId);
|
if (!validateClient(clientDetails, clientId, clientSecret)) {
|
throw new SecureException("客户端认证失败, 请检查请求头 [Authorization] 信息");
|
}
|
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());
|
JwtBuilder builder = Jwts.builder().setHeaderParam("typ", "JWT").setIssuer(issuer).setAudience(audience).signWith(signingKey);
|
|
user.forEach(builder::claim);
|
builder.claim(CLIENT_ID, clientId);
|
if (tokenType.equals("access_token")) {
|
expireMillis = clientDetails.getAccessTokenValidity().intValue() * 1000;
|
} else if (tokenType.equals("refresh_token")) {
|
expireMillis = clientDetails.getRefreshTokenValidity().intValue() * 1000;
|
} else {
|
expireMillis = getExpire();
|
}
|
long expMillis = nowMillis + expireMillis;
|
Date exp = new Date(expMillis);
|
builder.setExpiration(exp).setNotBefore(now);
|
TokenInfo tokenInfo = new TokenInfo();
|
tokenInfo.setToken(builder.compact());
|
tokenInfo.setExpire((int) (expireMillis / 1000));
|
if (getJwtProperties().getState().booleanValue() && "access_token".equals(tokenType)) {
|
String tenantId = String.valueOf(user.get("tenant_id"));
|
String userId = String.valueOf(user.get("user_id"));
|
JwtUtil.addAccessToken(tenantId, userId, tokenInfo.getToken(), tokenInfo.getExpire());
|
}
|
if (getJwtProperties().getState().booleanValue() && getJwtProperties().getSingle().booleanValue() && "refresh_token".equals(tokenType)) {
|
String tenantId2 = String.valueOf(user.get("tenant_id"));
|
String userId2 = String.valueOf(user.get("user_id"));
|
JwtUtil.addRefreshToken(tenantId2, userId2, tokenInfo.getToken(), tokenInfo.getExpire());
|
}
|
return tokenInfo;
|
}
|
|
public static TokenInfo createJWT(Map<String, Object> user, String audience, String issuer, String tokenType, String clientId, String clientSecret) {
|
long expireMillis;
|
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());
|
JwtBuilder builder = Jwts.builder().setHeaderParam("typ", "JWT").setIssuer(issuer).setAudience(audience).signWith(signingKey);
|
user.forEach(builder::claim);
|
builder.claim(CLIENT_ID, clientId);
|
if (tokenType.equals("access_token")) {
|
expireMillis = clientDetails.getAccessTokenValidity().intValue() * 1000;
|
} else if (tokenType.equals("refresh_token")) {
|
expireMillis = clientDetails.getRefreshTokenValidity().intValue() * 1000;
|
} else {
|
expireMillis = getExpire();
|
}
|
long expMillis = nowMillis + expireMillis;
|
Date exp = new Date(expMillis);
|
builder.setExpiration(exp).setNotBefore(now);
|
TokenInfo tokenInfo = new TokenInfo();
|
tokenInfo.setToken(builder.compact());
|
tokenInfo.setExpire((int) (expireMillis / 1000));
|
if (getJwtProperties().getState().booleanValue() && "access_token".equals(tokenType)) {
|
String tenantId = String.valueOf(user.get("tenant_id"));
|
String userId = String.valueOf(user.get("user_id"));
|
JwtUtil.addAccessToken(tenantId, userId, tokenInfo.getToken(), tokenInfo.getExpire());
|
}
|
return tokenInfo;
|
}
|
|
public static long getExpire() {
|
Calendar cal = Calendar.getInstance();
|
cal.add(6, 1);
|
cal.set(11, 3);
|
cal.set(13, 0);
|
cal.set(12, 0);
|
cal.set(14, 0);
|
return cal.getTimeInMillis() - System.currentTimeMillis();
|
}
|
|
public static String[] extractAndDecodeHeader() {
|
|
try {
|
byte[] decoded;
|
String header = ((HttpServletRequest) Objects.<HttpServletRequest>requireNonNull(WebUtil.getRequest()))
|
.getHeader("Authorization");
|
header = Func.toStr(header).replace("Basic%20", "Basic ");
|
if (!header.startsWith(SecureConstant.BASIC_HEADER_PREFIX))
|
throw new SecureException("未获取到请求头[Authorization]的信息");
|
byte[] base64Token = header.substring(6).getBytes(Charsets.UTF_8_NAME);
|
try {
|
decoded = Base64.getDecoder().decode(base64Token);
|
} catch (IllegalArgumentException var7) {
|
throw new RuntimeException("客户端令牌解析失败");
|
}
|
String token = new String(decoded, Charsets.UTF_8_NAME);
|
int index = token.indexOf(":");
|
if (index == -1)
|
throw new RuntimeException("客户端令牌不合法");
|
return new String[] { token.substring(0, index), token.substring(index + 1) };
|
} catch (Throwable ex) {
|
throw new RuntimeException("客户端令牌解析失败", ex);
|
}
|
|
|
}
|
|
public static String getClientIdFromHeader() {
|
String[] tokens = extractAndDecodeHeader();
|
if ($assertionsDisabled || tokens.length == 2) {
|
return tokens[0];
|
}
|
throw new AssertionError();
|
}
|
|
private static IClientDetails clientDetails(String clientId) {
|
return getClientDetailsService().loadClientByClientId(clientId);
|
}
|
|
private static boolean validateClient(IClientDetails clientDetails, String clientId, String clientSecret) {
|
return clientDetails != null && StringUtil.equals(clientId, clientDetails.getClientId()) && StringUtil.equals(clientSecret, clientDetails.getClientSecret());
|
}
|
}
|