package com.iailab.sdk.auth.client; import com.fasterxml.jackson.databind.ObjectMapper; import com.iailab.sdk.auth.client.vo.AuthLoginReqVO; 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 * @Description * @createTime 2025年02月18日 */ @Component @Service public class IailabAuthClient { 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 void authenticate() throws Exception { System.out.println("登录获取平台token"); // 1.1 构建请求头 HttpHeaders headers = new HttpHeaders(); addClientHeader(headers); headers.setContentType(MediaType.APPLICATION_JSON_UTF8); // 1.2 构建authenticate请求URL // 1.2 构建authenticate请求URL String authenticateUrl = authProperties.getBaseUrl() + "/system/oauth2/token?" // 密码模式的参数 + "&grant_type=" + GRAND_TYPE + "&username=" + authProperties.getUsername() + "&password=" + authProperties.getPassword() + "&scope=" + SCOPE; // 2. 执行请求 ResponseEntity> exchange = restTemplate.exchange( authenticateUrl, HttpMethod.POST, new HttpEntity<>(headers), new ParameterizedTypeReference>() { }); Map 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> exchange = restTemplate.exchange( authenticateUrl, HttpMethod.POST, new HttpEntity<>(headers), new ParameterizedTypeReference>() { }); Assert.isTrue(exchange.getStatusCode().is2xxSuccessful(), "响应必须是 200 成功"); Map 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", authProperties.getTenantId()); } }