sdk/pom.xml
@@ -45,27 +45,12 @@ <groupId>com.iailab</groupId> <artifactId>iailab-common-test</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-validation</artifactId> </dependency> </dependencies> <!-- <build>--> <!-- <!– 设置构建的 jar 包名 –>--> <!-- <finalName>${project.artifactId}</finalName>--> <!-- <plugins>--> <!-- <!– 打包 –>--> <!-- <plugin>--> <!-- <groupId>org.springframework.boot</groupId>--> <!-- <artifactId>spring-boot-maven-plugin</artifactId>--> <!-- <version>${spring.boot.version}</version>--> <!-- <executions>--> <!-- <execution>--> <!-- <goals>--> <!-- <goal>repackage</goal> <!– 将引入的 jar 打入其中 –>--> <!-- </goals>--> <!-- </execution>--> <!-- </executions>--> <!-- </plugin>--> <!-- </plugins>--> <!-- </build>--> <build> <plugins> <plugin> sdk/src/main/java/com/iailab/sdk/auth/client/IailabAuthClient.java
@@ -1,16 +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.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 @@ -21,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, @@ -70,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; } } sdk/src/main/java/com/iailab/sdk/auth/client/vo/AuthLoginRespVO.java
对比新文件 @@ -0,0 +1,24 @@ package com.iailab.sdk.auth.client.vo; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; import java.time.LocalDateTime; @Data @NoArgsConstructor @AllArgsConstructor @Builder public class AuthLoginRespVO { private Long userId; private String accessToken; private String refreshToken; private LocalDateTime expiresTime; } sdk/src/main/java/com/iailab/sdk/auth/config/AuthProperties.java
对比新文件 @@ -0,0 +1,15 @@ package com.iailab.sdk.auth.config; import lombok.Data; import org.springframework.boot.context.properties.ConfigurationProperties; @ConfigurationProperties(prefix = "iailab.token") @Data public class AuthProperties { private String baseUrl; private String tenantId; private String username; private String password; private String clientId; private String clientSecret; } sdk/src/main/java/com/iailab/sdk/auth/config/SdkAutoConfiguration.java
对比新文件 @@ -0,0 +1,28 @@ package com.iailab.sdk.auth.config; import com.iailab.sdk.auth.client.IailabAuthClient; import com.iailab.sdk.util.http.IailabHttpUtils; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Configuration; import javax.annotation.PostConstruct; /** * SDK配置文件 */ @Configuration @EnableConfigurationProperties(AuthProperties.class) public class SdkAutoConfiguration { private final AuthProperties authProperties; public SdkAutoConfiguration(AuthProperties authProperties) { this.authProperties = authProperties; } @PostConstruct public void init() { IailabAuthClient.setAuthProperties(authProperties); IailabHttpUtils.setAuthProperties(authProperties); } } sdk/src/main/java/com/iailab/sdk/auth/config/SdkConfiguration.java
文件已删除 sdk/src/main/java/com/iailab/sdk/auth/enums/ErrorCodeConstants.java
对比新文件 @@ -0,0 +1,16 @@ package com.iailab.sdk.auth.enums; import com.iailab.framework.common.exception.ErrorCode; /** * System 错误码枚举类 * * system 系统,使用 1-002-000-000 段 */ public interface ErrorCodeConstants { // ========== AUTH 模块 1-002-000-000 ========== ErrorCode AUTH_LOGIN_BAD_CREDENTIALS = new ErrorCode(1_002_000_000, "登录失败,账号密码不正确"); ErrorCode AUTH_BAD_CREDENTIALS = new ErrorCode(400, "client_id 或 client_secret 未正确传递"); ErrorCode AUTH_REFRESH_TOKEN_ERROR = new ErrorCode(1_002_000_001, "刷新token失败"); } sdk/src/main/java/com/iailab/sdk/util/http/IailabHttpUtils.java
@@ -1,6 +1,7 @@ package com.iailab.sdk.util.http; import com.iailab.sdk.auth.client.IailabAuthClient; import com.iailab.sdk.auth.config.AuthProperties; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.client.methods.HttpGet; @@ -8,6 +9,7 @@ import org.apache.http.entity.StringEntity; import org.apache.http.util.EntityUtils; import org.springframework.util.CollectionUtils; import org.springframework.util.ObjectUtils; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; @@ -16,6 +18,12 @@ public class IailabHttpUtils { private static AuthProperties authProperties; public static void setAuthProperties(AuthProperties properties) { authProperties = properties; } /** * * @param url @@ -23,8 +31,9 @@ * @param charset * @return */ public static String doGet(String url, Map<String, String> map, String charset, String accessToken) { public static String doGet(String url, Map<String, String> map, String charset) throws Exception { System.out.println("start doGet url: " + url); checkToken(); org.apache.http.client.HttpClient httpClient = null; HttpGet httpGet = null; String result = null; @@ -51,8 +60,9 @@ //设置参数 httpGet.addHeader("Accept", "application/json"); httpGet.addHeader("Content-Type", "application/json;charset=UTF-8"); httpGet.addHeader("Authorization", "Bearer " + accessToken); httpGet.addHeader("Tenant-Id", String.valueOf(IailabAuthClient.TENANT_ID)); httpGet.addHeader("Authorization", "Bearer " + IailabAuthClient.accessToken); httpGet.addHeader("Tenant-Id", String.valueOf(authProperties.getTenantId())); HttpResponse response = httpClient.execute(httpGet); if (response != null) { HttpEntity resEntity = response.getEntity(); @@ -73,8 +83,9 @@ * @param charset * @return */ public static String doPost(String url, String json, String charset, String accessToken) { public static String doPost(String url, String json, String charset) throws Exception { System.out.println("start doPost url: " + url); checkToken(); org.apache.http.client.HttpClient httpClient = null; HttpPost httpPost = null; String result = null; @@ -84,8 +95,8 @@ //设置参数 httpPost.addHeader("Accept", "application/json"); httpPost.addHeader("Content-Type", "application/json;charset=UTF-8"); httpPost.addHeader("Authorization", "Bearer " + accessToken); httpPost.addHeader("Tenant-Id", String.valueOf(IailabAuthClient.TENANT_ID)); httpPost.addHeader("Authorization", "Bearer " + IailabAuthClient.accessToken); httpPost.addHeader("Tenant-Id", String.valueOf(authProperties.getTenantId())); StringEntity stringEntity = new StringEntity(json); stringEntity.setContentEncoding("UTF-8"); stringEntity.setContentType("application/json"); @@ -103,4 +114,13 @@ return result; } private static void checkToken() throws Exception { //第一次请求或者token过期,需要重新获取token if(ObjectUtils.isEmpty(IailabAuthClient.accessToken)) { IailabAuthClient.authenticate(); } else if (IailabAuthClient.expireTime < System.currentTimeMillis() / 1000) { IailabAuthClient.refreshToken(); } } } sdk/src/main/resources/META-INF/spring.factories
对比新文件 @@ -0,0 +1 @@ org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.iailab.sdk.auth.config.SdkAutoConfiguration sdk/src/main/resources/application-dev.yaml
文件已删除 sdk/src/main/resources/application.yaml
@@ -1,13 +1,4 @@ spring: application: name: sdk profiles: active: dev iailab: auth: base-url: http://172.16.8.100:48080/admin-api tenant-id: 1 #spring: # application: # name: sdk # sdk/src/test/java/com/iailab/sdk/IailabClientTest.java
@@ -18,21 +18,13 @@ @Test public void testLogin() throws Exception { // 准备参数 AuthLoginReqVO authLoginReqVO = new AuthLoginReqVO(); authLoginReqVO.setUsername("sysadmin"); authLoginReqVO.setPassword("iailab2019"); TokenDTO login = IailabAuthClient.login(authLoginReqVO); System.out.println(login.getAccessToken()); System.out.println(login.getRefreshToken()); IailabAuthClient.authenticate(); } @Test public void testRefreshToken() { public void testRefreshToken() throws Exception { // 准备参数 String refreshToken = "1d62031562364ed29d6d414fea97e2dd"; TokenDTO tokenDTO = IailabAuthClient.refreshToken(refreshToken); System.out.println(tokenDTO); IailabAuthClient.refreshToken(); }