From ca5436abd755ad04735810d9e146c7dcd1158663 Mon Sep 17 00:00:00 2001 From: liriming <1343021927@qq.com> Date: 星期二, 25 三月 2025 11:05:32 +0800 Subject: [PATCH] 认证 --- ansteel-biz/src/main/java/com/iailab/module/ansteel/config/FeignTokenInterceptor.java | 43 ++++++++++ ansteel-biz/src/main/java/com/iailab/module/ansteel/util/token/IailabClient.java | 145 ++++++++++++++++++++++++++++++++++++ 2 files changed, 188 insertions(+), 0 deletions(-) diff --git a/ansteel-biz/src/main/java/com/iailab/module/ansteel/config/FeignTokenInterceptor.java b/ansteel-biz/src/main/java/com/iailab/module/ansteel/config/FeignTokenInterceptor.java new file mode 100644 index 0000000..2e45c51 --- /dev/null +++ b/ansteel-biz/src/main/java/com/iailab/module/ansteel/config/FeignTokenInterceptor.java @@ -0,0 +1,43 @@ +package com.iailab.module.ansteel.config; + +import com.iailab.module.ansteel.util.token.IailabClient; +import feign.RequestInterceptor; +import feign.RequestTemplate; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.HttpHeaders; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; + +@Configuration +public class FeignTokenInterceptor implements RequestInterceptor { + + @Autowired + private IailabClient iailabClient; + + @Override + public void apply(RequestTemplate requestTemplate) { + // 从当前请求上下文中获取Token + String token = getTokenFromCurrentRequest(); + + if (token == null) { + // 如果没有获取到Token,从system-server中获取token + token = iailabClient.getToken(); + if (token!= null) { + requestTemplate.header(HttpHeaders.AUTHORIZATION, token); + } + Long tenantId = iailabClient.getTenantId(); + if (tenantId != null) { + requestTemplate.header("tenant-id", String.valueOf(tenantId)); + } + } + } + + private String getTokenFromCurrentRequest() { + ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); + if (attributes!= null) { + return attributes.getRequest().getHeader(HttpHeaders.AUTHORIZATION); + } + return null; + } +} \ No newline at end of file diff --git a/ansteel-biz/src/main/java/com/iailab/module/ansteel/util/token/IailabClient.java b/ansteel-biz/src/main/java/com/iailab/module/ansteel/util/token/IailabClient.java new file mode 100644 index 0000000..974c1cd --- /dev/null +++ b/ansteel-biz/src/main/java/com/iailab/module/ansteel/util/token/IailabClient.java @@ -0,0 +1,145 @@ +package com.iailab.module.ansteel.util.token; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.core.ParameterizedTypeReference; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Component; +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.Map; + +/** + * @author PanZhibao + * @Description + * @createTime 2024年11月21日 + */ +@Slf4j +@Component +public class IailabClient { + + /** + * 平台地址 + */ + @Value("${iailab.token.base-url}") + private String BASE_URL; + + /** + * 租户编号 + */ + @Value("${iailab.token.tenant-id}") + private String TENANT_ID; + + /** + * 客户端信息 + */ + @Value("${iailab.token.client-id}") + private String CLIENT_ID; + @Value("${iailab.token.client-secret}") + private String CLIENT_SECRET; + @Value("${iailab.token.username}") + private String USERNAME; + @Value("${iailab.token.password}") + private String PASSWORD; + private static final String GRAND_TYPE = "password"; + private static final String SCOPE = "user.read user.write"; + + + private static final RestTemplate restTemplate = new RestTemplate(); + + // 鉴权token + private String accessToken; + // 刷新token + private String refreshToken; + // 鉴权token过期时间 + private Long expireTime; + + /** + * 用户名密码方式获取平台token + */ + private synchronized void authenticate() { + log.info("获取平台token"); + // 1.1 构建请求头 + HttpHeaders headers = new HttpHeaders(); + addClientHeader(headers); + // 1.2 构建authenticate请求URL + String authenticateUrl = BASE_URL + "/oauth2/token?" + // 密码模式的参数 + + "grant_type=" + GRAND_TYPE + + "&username=" + USERNAME + + "&password=" + PASSWORD + + "&scope=" + SCOPE; + // 2. 执行请求 + ResponseEntity<Map<String, Object>> exchange = restTemplate.exchange( + authenticateUrl, + HttpMethod.POST, + new org.springframework.http.HttpEntity<>(headers), + new ParameterizedTypeReference<Map<String, Object>>() { + }); + Assert.isTrue(exchange.getStatusCode().is2xxSuccessful(), "响应必须是 200 成功"); + log.info(exchange.toString()); + Map<String, Object> authMap = exchange.getBody(); + accessToken = authMap.get("access_token").toString(); + refreshToken = authMap.get("refresh_token").toString(); + expireTime = Long.valueOf(authMap.get("expires_time").toString()); + } + + private synchronized void refreshToken() { + log.info("刷新token"); + // 1.1 构建请求头 + HttpHeaders headers = new HttpHeaders(); + addClientHeader(headers); + // 1.2 构建authenticate请求URL + String authenticateUrl = BASE_URL + "/system/auth/client-refresh-token?refreshToken=" + refreshToken + + "&clientId=" + CLIENT_ID; + // 2. 执行请求 + ResponseEntity<Map<String, Object>> exchange = restTemplate.exchange( + authenticateUrl, + HttpMethod.POST, + new org.springframework.http.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 { + accessToken = authMap.get("access_token").toString(); + expireTime = Long.valueOf(authMap.get("expires_time").toString()); + } + } + + private void addClientHeader(HttpHeaders headers) { + // client 拼接,需要 BASE64 编码 + String client = CLIENT_ID + ":" + CLIENT_SECRET; + client = Base64Utils.encodeToString(client.getBytes(StandardCharsets.UTF_8)); + headers.add("Authorization", "Basic " + client); + headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED); + headers.set("tenant-id", getTenantId().toString()); + } + + public String getToken() { + //第一次请求或者token过期,需要重新获取token + if(ObjectUtils.isEmpty(accessToken)) { + authenticate(); + } else if (expireTime < System.currentTimeMillis() / 1000) { + refreshToken(); + } + + return accessToken; + } + public Long getTenantId() { + return Long.valueOf(TENANT_ID); + } +} \ No newline at end of file -- Gitblit v1.9.3