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<LyraTokenUtil> 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(); 
 | 
        } 
 | 
    } 
 | 
} 
 |