| | |
| | | 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 |
| | |
| | | @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, |
| | |
| | | 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; |
| | | } |
| | | } |