diff --git a/blade-auth/src/main/java/org/springblade/auth/granter/IamSsoTokenGranter.java b/blade-auth/src/main/java/org/springblade/auth/granter/IamSsoTokenGranter.java index fd04d99..d3c7b7c 100644 --- a/blade-auth/src/main/java/org/springblade/auth/granter/IamSsoTokenGranter.java +++ b/blade-auth/src/main/java/org/springblade/auth/granter/IamSsoTokenGranter.java @@ -56,6 +56,7 @@ import org.springframework.stereotype.Component; import java.io.IOException; import java.net.URI; +import java.net.URLDecoder; import java.net.URLEncoder; import java.net.http.HttpClient; import java.net.http.HttpRequest; @@ -122,7 +123,12 @@ public class IamSsoTokenGranter extends AuthorizationCodeGranter { throw new UserInvalidException(OAuth2TokenConstant.USER_NOT_FOUND); } - UserInfo userInfo = loadOrCreateIamUser(request, profileResponse, accountNo); + String tenantId = resolveTenantId(request); + if (StringUtil.isBlank(tenantId)) { + log.warn("IAM统一身份认证请求缺少租户ID,accountNo={}", accountNo); + throw new UserInvalidException(OAuth2TokenConstant.USER_NOT_FOUND); + } + UserInfo userInfo = loadOrCreateIamUser(request, profileResponse, tenantId, accountNo); OAuth2User user = TokenUtil.convertUser(userInfo, request); if (user == null) { throw new UserInvalidException(OAuth2TokenConstant.USER_NOT_FOUND); @@ -131,28 +137,28 @@ public class IamSsoTokenGranter extends AuthorizationCodeGranter { return user; } - private UserInfo loadOrCreateIamUser(OAuth2Request request, IamSsoProfileResponse profileResponse, String accountNo) { - R result = userClient.userInfo(request.getTenantId(), accountNo); + private UserInfo loadOrCreateIamUser(OAuth2Request request, IamSsoProfileResponse profileResponse, String tenantId, String accountNo) { + R result = userClient.userInfo(tenantId, accountNo); if (result.isSuccess() && result.getData() != null) { return result.getData(); } - log.info("IAM统一身份认证未匹配到本系统账号,开始自动创建用户,tenantId={}, accountNo={}", request.getTenantId(), accountNo); - R saveResult = userClient.saveUser(buildIamUser(request, profileResponse, accountNo)); + log.info("IAM统一身份认证未匹配到本系统账号,开始自动创建用户,tenantId={}, accountNo={}", tenantId, accountNo); + R saveResult = userClient.saveUser(buildIamUser(profileResponse, tenantId, accountNo)); if (!saveResult.isSuccess() || !Boolean.TRUE.equals(saveResult.getData())) { - log.warn("IAM统一身份认证自动创建用户失败,tenantId={}, accountNo={}, msg={}", request.getTenantId(), accountNo, saveResult.getMsg()); + log.warn("IAM统一身份认证自动创建用户失败,tenantId={}, accountNo={}, msg={}", tenantId, accountNo, saveResult.getMsg()); throw new UserInvalidException(OAuth2TokenConstant.USER_NOT_FOUND); } - R createdResult = userClient.userInfo(request.getTenantId(), accountNo); + R createdResult = userClient.userInfo(tenantId, accountNo); if (!createdResult.isSuccess() || createdResult.getData() == null) { - log.warn("IAM统一身份认证自动创建用户后未查询到用户,tenantId={}, accountNo={}", request.getTenantId(), accountNo); + log.warn("IAM统一身份认证自动创建用户后未查询到用户,tenantId={}, accountNo={}", tenantId, accountNo); throw new UserInvalidException(OAuth2TokenConstant.USER_NOT_FOUND); } return createdResult.getData(); } - private User buildIamUser(OAuth2Request request, IamSsoProfileResponse profileResponse, String accountNo) { + private User buildIamUser(IamSsoProfileResponse profileResponse, String tenantId, String accountNo) { User user = new User(); - user.setTenantId(request.getTenantId()); + user.setTenantId(tenantId); user.setUserType(UserType.WEB.getCategory()); user.setAccount(accountNo); user.setPassword(accountNo); @@ -162,12 +168,42 @@ public class IamSsoTokenGranter extends AuthorizationCodeGranter { user.setDeptId(StringPool.MINUS_ONE); user.setPostId(StringPool.MINUS_ONE); user.setStatus(StatusType.ACTIVE.getType()); - log.info("IAM统一身份认证自动创建用户参数,tenantId={}, accountNo={}, iamId={}", request.getTenantId(), accountNo, profileResponse.getId()); + log.info("IAM统一身份认证自动创建用户参数,tenantId={}, accountNo={}, iamId={}", tenantId, accountNo, profileResponse.getId()); return user; } private boolean isIamRequest(OAuth2Request request) { - return StringUtil.isNotBlank(properties.getRedirectUri()) && StringUtil.equals(properties.getRedirectUri(), request.getRedirectUri()); + String redirectUri = normalizeRedirectUri(request.getRedirectUri()); + boolean iamRequest = StringUtil.isNotBlank(properties.getRedirectUri()) + && StringUtil.isNotBlank(request.getCode()) + && StringUtil.equals(properties.getRedirectUri(), redirectUri); + if (!iamRequest) { + log.info("IAM统一身份认证请求未命中,configRedirectUri={}, requestRedirectUri={}, normalizedRedirectUri={}, code={}", + properties.getRedirectUri(), request.getRedirectUri(), redirectUri, request.getCode()); + } + return iamRequest; + } + + private String resolveTenantId(OAuth2Request request) { + if (StringUtil.isNotBlank(request.getTenantId())) { + return request.getTenantId(); + } + if (request.getHttpRequest() == null) { + return null; + } + return request.getHttpRequest().getParameter("tenantId"); + } + + private String normalizeRedirectUri(String redirectUri) { + if (StringUtil.isBlank(redirectUri)) { + return redirectUri; + } + try { + return URLDecoder.decode(redirectUri, StandardCharsets.UTF_8); + } catch (IllegalArgumentException exception) { + log.warn("IAM统一身份认证redirect_uri解码失败,redirectUri={}", redirectUri, exception); + return redirectUri; + } } private void validateRequest(OAuth2Request request) {