潘志宝
2025-03-03 a365eb1d7213c5f28c6d2fc2b8f87099d71d17d4
sdk/src/main/java/com/iailab/sdk/auth/client/IailabAuthClient.java
@@ -1,17 +1,23 @@
package com.iailab.sdk.auth.client;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.iailab.sdk.auth.client.dto.TokenDTO;
import com.iailab.sdk.auth.client.vo.AuthLoginReqVO;
import com.iailab.sdk.auth.config.SdkConfiguration;
import com.iailab.sdk.auth.config.AuthProperties;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.*;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import org.springframework.util.Base64Utils;
import org.springframework.util.ObjectUtils;
import org.springframework.web.client.RestTemplate;
import java.nio.charset.StandardCharsets;
import java.util.*;
import static com.iailab.framework.common.exception.enums.GlobalErrorCodeConstants.BAD_REQUEST;
import static com.iailab.framework.common.exception.util.ServiceExceptionUtil.exception;
import static com.iailab.sdk.auth.enums.ErrorCodeConstants.*;
/**
 * @author Houzhongjian
@@ -22,48 +28,42 @@
@Service
public class IailabAuthClient {
    /**
     * 平台地址
     */
    public static String BASE_URL = "http://172.16.8.100:48080/admin-api";
    /**
     * 租户编号
     */
    public static String TENANT_ID = "1";
    private static final RestTemplate restTemplate = new RestTemplate();
    private static AuthProperties authProperties;
    public static void setAuthProperties(AuthProperties properties) {
        authProperties = properties;
    }
    private static final String GRAND_TYPE = "password";
    private static final String SCOPE = "user.read user.write";
    // 鉴权token
    public static String accessToken;
    // 刷新token
    public static String refreshToken;
    // 鉴权token过期时间
    public static Long expireTime;
    /**
     * 用户名密码方式获取平台token
     */
    public static synchronized TokenDTO login(AuthLoginReqVO loginReqVO) throws Exception {
    public static synchronized void authenticate() throws Exception {
        System.out.println("登录获取平台token");
        ObjectMapper objectMapper = new ObjectMapper();
        String paramString = objectMapper.writeValueAsString(loginReqVO);
        // 1.1 构建请求头
        HttpHeaders headers = new HttpHeaders();
        addClientHeader(headers);
        headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
        // 1.2 构建authenticate请求URL
        String authenticateUrl = BASE_URL + "/system/auth/login";
        // 2. 执行请求
        ResponseEntity<Map<String, Object>> exchange = restTemplate.exchange(
                authenticateUrl,
                HttpMethod.POST,
                new HttpEntity<>(paramString, headers),
                new ParameterizedTypeReference<Map<String, Object>>() {
                });
        return handleResponse(exchange);
    }
    public static synchronized TokenDTO refreshToken(String refreshToken) {
        System.out.println("刷新token");
        // 1.1 构建请求头
        HttpHeaders headers = new HttpHeaders();
        addClientHeader(headers);
        // 1.2 构建authenticate请求URL
        String authenticateUrl = BASE_URL + "/system/auth/refresh-token?refreshToken=" + refreshToken;
        String authenticateUrl = authProperties.getBaseUrl() + "/system/oauth2/token?"
                // 密码模式的参数
                + "&grant_type=" + GRAND_TYPE
                + "&username=" + authProperties.getUsername()
                + "&password=" + authProperties.getPassword()
                + "&scope=" + SCOPE;
        // 2. 执行请求
        ResponseEntity<Map<String, Object>> exchange = restTemplate.exchange(
                authenticateUrl,
@@ -71,24 +71,55 @@
                new HttpEntity<>(headers),
                new ParameterizedTypeReference<Map<String, Object>>() {
                });
        return handleResponse(exchange);
        Map<String, Object> authMap = exchange.getBody();
        if(AUTH_BAD_CREDENTIALS.getCode().equals(authMap.get("code"))) {
            throw exception(AUTH_BAD_CREDENTIALS);
        } else if(AUTH_LOGIN_BAD_CREDENTIALS.getCode().equals(authMap.get("code"))) {
            throw exception(AUTH_LOGIN_BAD_CREDENTIALS);
        }
        Assert.isTrue(exchange.getStatusCode().is2xxSuccessful(), "响应必须是 200 成功");
        accessToken = authMap.get("access_token").toString();
        refreshToken = authMap.get("refresh_token").toString();
        expireTime = Long.valueOf(authMap.get("expires_time").toString());
    }
    public static synchronized void refreshToken() throws Exception {
        System.out.println("刷新token");
        // 1.1 构建请求头
        HttpHeaders headers = new HttpHeaders();
        addClientHeader(headers);
        // 1.2 构建authenticate请求URL
        String authenticateUrl = authProperties.getBaseUrl() + "/system/auth/client-refresh-token?refreshToken=" + refreshToken+ "&clientId=" + authProperties.getClientId();
        // 2. 执行请求
        ResponseEntity<Map<String, Object>> exchange = restTemplate.exchange(
                authenticateUrl,
                HttpMethod.POST,
                new HttpEntity<>(headers),
                new ParameterizedTypeReference<Map<String, Object>>() {
                });
        Assert.isTrue(exchange.getStatusCode().is2xxSuccessful(), "响应必须是 200 成功");
        Map<String, Object> authMap = exchange.getBody();
        //刷新token过期,重新获取token
        if (!ObjectUtils.isEmpty(authMap.get("code"))) {
            Integer code = Integer.valueOf(authMap.get("code").toString());
            if (code == 401) {
                authenticate();
            } else {
                throw exception(AUTH_REFRESH_TOKEN_ERROR);
            }
        } else {
            accessToken = authMap.get("access_token").toString();
            expireTime = Long.valueOf(authMap.get("expires_time").toString());
        }
    }
    private static void addClientHeader(HttpHeaders headers) {
        // client 拼接,需要 BASE64 编码
        String client = authProperties.getClientId() + ":" + authProperties.getClientSecret();
        client = Base64Utils.encodeToString(client.getBytes(StandardCharsets.UTF_8));
        headers.add("Authorization", "Basic " + client);
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
        headers.set("tenant-id", TENANT_ID);
        headers.set("tenant-id", authProperties.getTenantId());
    }
    // 统一处理响应
    private static <T> TokenDTO handleResponse(ResponseEntity<T> response) {
        Assert.isTrue(response.getStatusCode().is2xxSuccessful(), "响应必须是 200 成功");
        System.out.println(response);
        TokenDTO authTokenDTO = new TokenDTO();
        Map<String, Object> authMap = (Map<String, Object>)response.getBody();
        Map<String, Object> tokenData = (Map<String, Object>)authMap.get("data");
        authTokenDTO.setAccessToken(tokenData.get("accessToken").toString());
        authTokenDTO.setRefreshToken(tokenData.get("refreshToken").toString());
        authTokenDTO.setExpiresTime(Long.valueOf(tokenData.get("expiresTime").toString()));
        return authTokenDTO;
    }
}