package com.smartor.common; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.json.JsonMapper; import lombok.extern.slf4j.Slf4j; import okhttp3.*; import javax.net.ssl.*; import java.io.IOException; import java.net.URI; import java.net.URLEncoder; import java.nio.charset.StandardCharsets; import java.security.SecureRandom; import java.security.cert.X509Certificate; import java.util.*; import java.util.concurrent.locks.ReentrantLock; @Slf4j public class LyraTokenUtil { private static final List cache = new ArrayList<>(); private static final JsonMapper objectMapper = JsonMapper.builder().build(); private final OkHttpClient client; private final URI url; private final String clientId; private final String clientSecret; private final ReentrantLock lock = new ReentrantLock(); private Date expireTime; private String token; private final X509TrustManager trustManager; private LyraTokenUtil(URI url, String clientId, String clientSecret) { this.url = url; this.clientId = clientId; this.clientSecret = clientSecret; SSLContext sslContext; try { // 创建一个信任所有证书的 TrustManager TrustManager[] trustAllManagers = new TrustManager[]{new X509TrustManager() { @Override public void checkClientTrusted(X509Certificate[] chain, String authType) { } @Override public void checkServerTrusted(X509Certificate[] chain, String authType) { } @Override public X509Certificate[] getAcceptedIssuers() { return new X509Certificate[0]; } }}; // 保存 TrustManager this.trustManager = (X509TrustManager) trustAllManagers[0]; // 初始化 SSLContext sslContext = SSLContext.getInstance("TLS"); sslContext.init(null, trustAllManagers, new SecureRandom()); } catch (Exception e) { throw new IllegalStateException("Failed to initialize SSLContext", e); } // 创建 OkHttpClient,设置自定义的 SSLContext this.client = new OkHttpClient.Builder().sslSocketFactory(sslContext.getSocketFactory(), trustManager) // 直接使用保存的 TrustManager .hostnameVerifier((hostname, session) -> true) // 忽略主机名验证 .build(); } public static synchronized LyraTokenUtil createLyraTokenUtil(String url, String clientId, String clientSecret) { return cache.stream().filter(it -> it.url.equals(URI.create(url))).findFirst().orElseGet(() -> { LyraTokenUtil lyraTokenUtil = new LyraTokenUtil(URI.create(url), clientId, clientSecret); cache.add(lyraTokenUtil); return lyraTokenUtil; }); } public String getToken() throws IOException { lock.lock(); try { if (expireTime == null || expireTime.before(new Date())) { RequestBody formBody = new FormBody.Builder().add("grant_type", "client_credentials").add("client_id", clientId).add("client_secret", URLEncoder.encode(clientSecret, StandardCharsets.UTF_8.toString())).build(); Request request = new Request.Builder().url(url.toURL()).post(formBody).build(); try (Response response = client.newCall(request).execute()) { if (response.isSuccessful()) { ResponseBody body = response.body(); if (body != null) { JsonNode jsonNode = objectMapper.readTree(body.string()); String accessToken = jsonNode.get("access_token").asText(); String tokenType = jsonNode.get("token_type").asText(); this.token = tokenType + " " + accessToken; int expiresIn = jsonNode.get("expires_in").asInt(); this.expireTime = new Date(System.currentTimeMillis() + (expiresIn - 300) * 1000); } else { throw new RuntimeException("Response body is null"); } } else { throw new RuntimeException("Failed to get token, HTTP status: " + response.code()); } } } return token; } finally { lock.unlock(); } } }