1、新增预结算单

2、新增正式结算单
3、调整IAM认证登录
This commit is contained in:
2026-08-18 21:31:59 +08:00
parent c8b8b59c50
commit 154cc4a7cb
53 changed files with 4517 additions and 13 deletions
@@ -25,6 +25,7 @@
*/
package org.springblade.auth.config;
import org.springblade.auth.granter.IamAwareTokenGranterFactory;
import org.springblade.auth.handler.BladeAuthorizationHandler;
import org.springblade.auth.handler.BladeLockHandler;
import org.springblade.auth.handler.BladeLogHandler;
@@ -37,6 +38,9 @@ import org.springblade.core.jwt.props.JwtProperties;
import org.springblade.core.launch.props.BladeProperties;
import org.springblade.core.launch.server.ServerInfo;
import org.springblade.core.oauth2.config.OAuth2AutoConfiguration;
import org.springblade.core.oauth2.granter.TokenGranter;
import org.springblade.core.oauth2.granter.TokenGranterEnhancer;
import org.springblade.core.oauth2.granter.TokenGranterFactory;
import org.springblade.core.oauth2.handler.AuthorizationHandler;
import org.springblade.core.oauth2.handler.PasswordHandler;
import org.springblade.core.oauth2.handler.TokenHandler;
@@ -51,8 +55,11 @@ import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.jdbc.core.JdbcTemplate;
import java.util.List;
/**
* BladeAuthConfiguration
*
@@ -101,4 +108,12 @@ public class BladeAuthConfiguration {
return new BladeUserDetailService(userClient);
}
@Primary
@Bean("iamAwareTokenGranterFactory")
public TokenGranterFactory tokenGranterFactory(List<TokenGranter> tokenGranters,
List<TokenGranterEnhancer> tokenGranterEnhancers,
OAuth2Properties properties) {
return new IamAwareTokenGranterFactory(tokenGranters, tokenGranterEnhancers, properties);
}
}
@@ -65,8 +65,10 @@ import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.Base64;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.UUID;
import java.util.stream.Collectors;
/**
@@ -167,7 +169,7 @@ public class IamSsoTokenGranter extends AuthorizationCodeGranter {
return result.getData();
}
log.info("IAM统一身份认证未匹配到本系统账号,开始自动创建用户,tenantId={}, accountNo={}", tenantId, accountNo);
R<Boolean> saveResult = userClient.saveUser(buildIamUser(profileResponse, tenantId, accountNo));
R<Boolean> saveResult = userClient.saveIamUser(buildIamUser(profileResponse, tenantId, accountNo));
if (!saveResult.isSuccess() || !Boolean.TRUE.equals(saveResult.getData())) {
log.warn("IAM统一身份认证自动创建用户失败,tenantId={}, accountNo={}, msg={}", tenantId, accountNo, saveResult.getMsg());
throw new UserInvalidException(OAuth2TokenConstant.USER_NOT_FOUND);
@@ -185,12 +187,14 @@ public class IamSsoTokenGranter extends AuthorizationCodeGranter {
user.setTenantId(tenantId);
user.setUserType(UserType.WEB.getCategory());
user.setAccount(accountNo);
user.setPassword(accountNo);
user.setPassword(UUID.randomUUID().toString());
user.setName(accountNo);
user.setRealName(accountNo);
user.setRoleId(StringPool.MINUS_ONE);
user.setDeptId(StringPool.MINUS_ONE);
user.setPostId(StringPool.MINUS_ONE);
user.setIsOa(1);
user.setSyncTime(new Date());
user.setStatus(StatusType.ACTIVE.getType());
log.info("IAM统一身份认证自动创建用户参数,tenantId={}, accountNo={}, iamId={}", tenantId, accountNo, profileResponse.getId());
return user;
@@ -206,13 +210,13 @@ public class IamSsoTokenGranter extends AuthorizationCodeGranter {
}
private boolean isIamRequest(OAuth2Request request, boolean logMiss) {
String redirectUri = normalizeRedirectUri(request.getRedirectUri());
boolean iamRequest = StringUtil.isNotBlank(properties.getRedirectUri())
String redirectUri = resolveRedirectUri(request);
boolean iamRequest = StringUtil.isNotBlank(redirectUri)
&& StringUtil.isNotBlank(request.getCode())
&& StringUtil.equals(properties.getRedirectUri(), redirectUri);
&& isDedicatedIamEndpoint(request);
if (!iamRequest && logMiss) {
log.info("IAM统一身份认证请求未命中,configRedirectUri={}, requestRedirectUri={}, normalizedRedirectUri={}, code={}",
properties.getRedirectUri(), request.getRedirectUri(), redirectUri, request.getCode());
log.info("IAM统一身份认证请求未命中,configRedirectUri={}, requestRedirectUri={}, normalizedRedirectUri={}, hasCode={}",
properties.getRedirectUri(), request.getRedirectUri(), redirectUri, StringUtil.isNotBlank(request.getCode()));
}
return iamRequest;
}
@@ -247,8 +251,7 @@ public class IamSsoTokenGranter extends AuthorizationCodeGranter {
properties.getTokenUrl(),
properties.getProfileUrl(),
properties.getClientId(),
properties.getClientSecret(),
properties.getRedirectUri()
properties.getClientSecret()
)) {
throw new UserInvalidException("IAM统一身份认证配置不完整");
}
@@ -265,7 +268,7 @@ public class IamSsoTokenGranter extends AuthorizationCodeGranter {
.header(HttpHeaders.AUTHORIZATION, authorizationHeader())
.POST(HttpRequest.BodyPublishers.ofString(tokenBody, StandardCharsets.UTF_8))
.build();
log.info("IAM统一身份认证换取Token请求,method={}, headers={}, body={}", httpRequest.method(), httpRequest.headers().map(), tokenBody);
log.info("IAM统一身份认证换取Token请求,url={}, method={}", properties.getTokenUrl(), httpRequest.method());
HttpResponse<String> response = httpClient.send(
httpRequest,
HttpResponse.BodyHandlers.ofString(StandardCharsets.UTF_8)
@@ -292,12 +295,12 @@ public class IamSsoTokenGranter extends AuthorizationCodeGranter {
.header(HttpHeaders.AUTHORIZATION, profileAuthorizationHeader(accessToken))
.GET()
.build();
log.info("IAM统一身份认证获取用户信息请求,headers={}, body={}", httpRequest.headers().map(), "");
log.info("IAM统一身份认证获取用户信息请求,url={}, method={}", properties.getProfileUrl(), httpRequest.method());
HttpResponse<String> response = httpClient.send(
httpRequest,
HttpResponse.BodyHandlers.ofString(StandardCharsets.UTF_8)
);
log.info("IAM统一身份认证获取用户信息响应,headers={}, body={}", response.headers().map(), response.body());
log.info("IAM统一身份认证获取用户信息响应,status={}", response.statusCode());
if (response.statusCode() < 200 || response.statusCode() >= 300) {
log.warn("IAM统一身份认证获取用户信息失败,status={}", response.statusCode());
throw new UserInvalidException(OAuth2TokenConstant.TOKEN_NOT_CORRECT);
@@ -321,10 +324,24 @@ public class IamSsoTokenGranter extends AuthorizationCodeGranter {
if (StringUtil.isNotBlank(request.getState())) {
params.put("state", request.getState());
}
params.put("redirect_uri", properties.getRedirectUri());
params.put("redirect_uri", resolveRedirectUri(request));
return params;
}
/**
* 获取 IAM 回调地址,优先使用前端请求传入的值,兼容未传参时的后端默认配置。
*
* @param request OAuth2 请求
* @return IAM 回调地址
*/
private String resolveRedirectUri(OAuth2Request request) {
String requestRedirectUri = normalizeRedirectUri(request.getRedirectUri());
if (StringUtil.isNotBlank(requestRedirectUri)) {
return requestRedirectUri;
}
return normalizeRedirectUri(properties.getRedirectUri());
}
private String buildTokenBody(Map<String, String> params) {
return params.entrySet().stream()
.map(entry -> encode(entry.getKey()) + "=" + encode(entry.getValue()))
@@ -89,3 +89,16 @@ social:
client-id: 233************
client-secret: 233************************************
redirect-uri: ${social.domain}/oauth/redirect/dingtalk
# IAM统一身份认证
iam:
sso:
token-url: ${IAM_SSO_TOKEN_URL:http://172.16.204.83:38000/gwzh/IAM/IAM_SSO_TOKEN}
profile-url: ${IAM_SSO_PROFILE_URL:http://172.16.204.83:38000/gwzh/IAM/IAM_SSO_PROFILE}
client-id: ${IAM_SSO_CLIENT_ID:f0b52f23f71b1649c468}
client-secret: ${IAM_SSO_CLIENT_SECRET:5b3d8575f0899946623ab86523ac3dd8ee98}
system-client-id: ${IAM_SSO_SYSTEM_CLIENT_ID:saber3}
system-client-secret: ${IAM_SSO_SYSTEM_CLIENT_SECRET:saber3_secret}
redirect-uri: ${IAM_SSO_REDIRECT_URI:http://172.16.203.228:8000/callback}
authorization: ${IAM_SSO_AUTHORIZATION:Z3d6aF90bXMtOVJJU0RVN1U6YW0yYkcwWnBJZ0RQZmtrSjNaZkZjUDBSaGFuSEtxQng=}
profile-authorization: ${IAM_SSO_PROFILE_AUTHORIZATION:Z3d6aF90bXMtOVJJU0RVN1U6YW0yYkcwWnBJZ0RQZmtrSjNaZkZjUDBSaGFuSEtxQng=}