tao.mo

manager-server | 修改 |

FCL登录cookies调整
mt
2025年5月27日14:40:10
......@@ -10,12 +10,30 @@ public class PropertiesConfig {
@Value("${fcl.login.url}")
private String fclLoginUrl;
@Value("${fcl.twidx.url}")
private String twIdxUrl;
@Value("${fcl.preClearIndex.url}")
private String preClearIndexUrl;
@Value("${fcl.interface.userinfo}")
private String userInfoUrl;
@Value("${fcl.login.redjrectLogin}")
private String redjrectLogin;
@Value("${spring.profiles.env}")
private String env;
@Value("${fcl.interface.token.url}")
private String fclTokenUrl;
@Value("${fcl.interface.token.grant_type}")
private String fclGrantType;
@Value("${fcl.interface.token.client_id}")
private String fclClientId;
@Value("${fcl.interface.token.client_secret}")
private String fclClientSecret;
@Value("${fcl.interface.token.scope}")
private String fclScope;
}
......
......@@ -15,10 +15,12 @@ import com.fedex.connect.common.model.sys.User;
import com.fedex.connect.manager.common.enums.FCLSessionInfoEnum;
import com.fedex.connect.manager.controller.base.BaseController;
import com.fedex.connect.manager.controller.sys.ISysAuthController;
import com.fedex.connect.manager.data.dto.FclInfoDto;
import com.fedex.connect.manager.data.dto.LogLoginDto;
import com.fedex.connect.manager.data.dto.LoginRequest;
import com.fedex.connect.manager.data.dto.SysUserDto;
import com.fedex.connect.manager.enums.ResponseCode;
import com.fedex.connect.manager.util.LoginControllerUtils;
import com.fedex.connect.manager.util.ParamConfigUtil;
import com.google.gson.JsonObject;
import io.jsonwebtoken.Claims;
......@@ -57,6 +59,9 @@ public class SysAuthController extends BaseController implements ISysAuthControl
@Autowired
private ParamConfigUtil paramConfigUtil;
@Autowired
private LoginControllerUtils loginControllerUtils;
@Value("${fcl.interface.logurl}")
private String fclIndexLoginUrl;
......@@ -98,7 +103,7 @@ public class SysAuthController extends BaseController implements ISysAuthControl
res.sendRedirect(redirectUrl);
}
}else {
res.sendRedirect(propertiesConfig.getTwIdxUrl());
res.sendRedirect(propertiesConfig.getPreClearIndexUrl());
}
} catch (IOException e) {
......@@ -123,9 +128,13 @@ public class SysAuthController extends BaseController implements ISysAuthControl
if (StringUtils.isBlank(fcl_token_key)){
return;
}
JsonObject jsonObject = sysAuthService.getFclToken(fcl_token_key);
String fcl_uuid = jsonObject.get(FCLSessionInfoEnum.FCL_UUID.getCode()).getAsString();
String fcl_contactname = jsonObject.get(FCLSessionInfoEnum.FCL_CONTACTNAME.getCode()).getAsString().replaceAll("\"","");
JsonObject tokenInfo = sysAuthService.getFclToken(fcl_token_key);
/**
* 获取fcl相关信息
*/
FclInfoDto fclInfoDto = loginControllerUtils.getFclInfo(tokenInfo);
String fcl_uuid = fclInfoDto.getFclUuid();
String fcl_contactname = fclInfoDto.getFclContactname();
User loginUser = sysUserService.findUserByFcl(fcl_uuid);
if (loginUser == null){
......@@ -141,7 +150,6 @@ public class SysAuthController extends BaseController implements ISysAuthControl
}
}
//如果名称和原来不一样,则更新
if(StringUtils.isNotBlank(fcl_contactname) && !fcl_contactname.equals(loginUser.getUserName())){
String encode_fcl_contactname = StringUtils.trimToEmpty(fcl_contactname);
if (StringUtils.isNotBlank(encode_fcl_contactname)){
......@@ -159,20 +167,18 @@ public class SysAuthController extends BaseController implements ISysAuthControl
loginRequest.setRememberMe(true);
ResponseVo tokenResult = sysAuthService.createAccessToken(loginRequest, loginUser);
DictionaryEntries dicUserLoginType = cacheSystem.getDicUserLoginType(UserLoginTypeEnum.FCLLOGINREGISTRATION.getCode());
//记录日志
LogLoginDto dto = new LogLoginDto(loginUser.getId(), dicUserLoginType.getId(),
UserLoginTypeEnum.LOGIN.getMsg());
logLoginService.saveLoginLog(dto);
try{
if (tokenResult.isSuccess()){
String redirectUrl = String.format("%s?token=%s&uid=%s", propertiesConfig.getRedjrectLogin(), tokenResult.getData(), loginUser.getId());
res.sendRedirect(redirectUrl);
log.info("wlgnLogin____________________finish:"+redirectUrl);
}else {
res.sendRedirect(propertiesConfig.getTwIdxUrl());
res.sendRedirect(propertiesConfig.getPreClearIndexUrl());
}
} catch (IOException e) {
log.error("FCL客户登录初始化 | 发生异常 | 异常如下:",e);
......@@ -281,4 +287,4 @@ public class SysAuthController extends BaseController implements ISysAuthControl
}
return resultRS;
}
}
}
\ No newline at end of file
......
package com.fedex.connect.manager.data.dto;
import lombok.Data;
/**
* @Author mt
* @Description fcl登录信息
* @Date 2025/5/26
*/
@Data
public class FclInfoDto {
//fcl身份认证oauth
String oAuthSecret;
//fdxLogin信息
String fdxLogin;
//用户uuid
String fclUuid;
//用户名称
String fclContactname;
//用户登录账号
private String userId;
//用户邮箱
private String emailAddress;
}
package com.fedex.connect.manager.data.vo;
import lombok.Data;
/**
* FCL接口获取token响应对象
*/
@Data
public class FCLTokenResponseVo {
private String access_token;
private String token_type;
private Long expires_in;
private String scope;
public String getAuthorization(){
return this.toString(this.token_type) + " " + this.toString(this.access_token);
}
private String toString(String str) {
return str == null ? "" : str;
}
}
package com.fedex.connect.manager.data.vo;
import com.alibaba.fastjson.JSONObject;
import lombok.Data;
import java.io.Serializable;
import java.util.List;
/**
* @Author mt
* @Description FCL接口获取用户信息-响应数据对象
* @Date 2025/5/26
*/
@Data
public class FCLUserInfoVo implements Serializable {
private String transactionId;
private OutPut output;
@Data
public static class OutPut implements Serializable{
UserProfile userProfile;
}
@Data
public static class UserProfile implements Serializable{
private Boolean profileLocked;
private LoginInformation loginInformation;
private UserProfileAddress userProfileAddress;
private String lastProfileModifiedDate;
private String uuid;
}
@Data
public static class LoginInformation implements Serializable{
/**
* 用户账号信息
*/
private String userId;
private Boolean emailAsUserId;
private SecretQuestion secretQuestion;
}
@Data
public static class SecretQuestion implements Serializable{
private String code;
private String text;
}
@Data
public static class UserProfileAddress implements Serializable{
private Contact contact;
private ContactAncillaryDetail contactAncillaryDetail;
private Address address;
}
@Data
public static class Contact implements Serializable{
private PersonName personName;
private String companyName;
private String phoneNumber;
private String faxNumber;
private String emailAddress;
}
@Data
public static class PersonName implements Serializable{
private String firstName;
private String middleName;
private String lastName;
}
@Data
public static class ContactAncillaryDetail implements Serializable{
private List<PhoneNumberDetails> phoneNumberDetails;
}
@Data
public static class PhoneNumberDetails implements Serializable{
private String type;
private Number number;
private JSONObject permissions;
}
@Data
public static class Number implements Serializable{
private String countryCode;
private String localNumber;
}
@Data
public static class Address implements Serializable{
private List<String> streetLines;
private String city;
private String stateOrProvinceCode;
private String postalCode;
private String countryCode;
private Boolean residential;
}
}
package com.fedex.connect.manager.data.vo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @Author mt
* @Description 调取用户信息返回VO
* @Date 2025/5/26
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class UserDataApiVo {
private String userId;
private String emailAddress;
private String uuid;
private String userName;
}
package com.fedex.connect.manager.util;
import com.alibaba.fastjson.JSON;
import com.fedex.connect.manager.common.enums.FCLSessionInfoEnum;
import com.fedex.connect.manager.config.PropertiesConfig;
import com.fedex.connect.manager.data.dto.FclInfoDto;
import com.fedex.connect.manager.data.vo.FCLTokenResponseVo;
import com.fedex.connect.manager.data.vo.FCLUserInfoVo;
import com.fedex.connect.manager.data.vo.UserDataApiVo;
import com.google.gson.JsonObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.*;
import org.springframework.stereotype.Component;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
import java.net.URLDecoder;
import java.util.*;
/**
* @Author mt
* @Description 登录相关util
* @Date 2025/5/26
*/
@Slf4j
@Component
public class LoginControllerUtils {
/**
* 普通访问
*/
@Autowired
private RestTemplate restTemplate;
@Autowired
private PropertiesConfig propertiesConfig;
public FclInfoDto getFclInfo(JsonObject tokenInfo){
FclInfoDto fclInfoDto = new FclInfoDto();
String secretValue;
String fdxLogin;
try {
secretValue = this.getOauthSecret(tokenInfo);
fdxLogin = this.getFdxLogin(tokenInfo);
FCLTokenResponseVo fclInterfaceToken = this.getFclInterfaceToken();
HttpHeaders headers = new HttpHeaders();
headers.set("Authorization", fclInterfaceToken.getAuthorization());
List<String> cookieList = new ArrayList<>();
if (StringUtils.isNotBlank(fdxLogin)) {
cookieList.add("fdx_login=" + fdxLogin);
}
if (StringUtils.isNotBlank(secretValue)){
cookieList.add(secretValue);
}
headers.set("Cookie", StringUtils.join(cookieList, ";"));
HttpEntity<String> entity = new HttpEntity("", headers);
log.info("apiExchange | entity: {}", JSON.toJSONString(entity));
ResponseEntity<String> resp = restTemplate.exchange(propertiesConfig.getUserInfoUrl(), HttpMethod.GET, entity, String.class);
log.info("apiExchange | resp: {}", JSON.toJSONString(resp));
String body = resp.getBody();
FCLUserInfoVo fclUserInfoResponse = JSON.parseObject(body, FCLUserInfoVo.class);
//获取email和userId
UserDataApiVo userDataApiVo = this.createUserDataApiVo(fclUserInfoResponse);
fclInfoDto.setFclContactname(userDataApiVo.getUserName());
String fcl_uuid = this.getUuid(tokenInfo,userDataApiVo.getUuid());
String fcl_contactname = this.decodeMultiLevelUrl(this.getFclContactName(tokenInfo,userDataApiVo.getUserName()));
fclInfoDto.setFclUuid(fcl_uuid);
fclInfoDto.setFclContactname(fcl_contactname);
fclInfoDto.setOAuthSecret(secretValue);
fclInfoDto.setFdxLogin(fdxLogin);
fclInfoDto.setUserId(userDataApiVo.getUserId());
fclInfoDto.setEmailAddress(userDataApiVo.getEmailAddress());
}catch(Exception ex){
log.error("apiExchange | fdxLogin: {}, secretValue: {} url: {}, userId: {} |具体原因: "
, fclInfoDto.getFdxLogin(), fclInfoDto.getOAuthSecret(), propertiesConfig.getUserInfoUrl(),fclInfoDto.getUserId());
ex.printStackTrace();
}
return fclInfoDto;
}
/**
* @Author mt
* @Description 构建获取用户信息Vo
* @Date 2025/5/26
* @param fclUserInfoResponse
* @return com.fedex.connect.manager.data.vo.UserDataApiVo
*/
public UserDataApiVo createUserDataApiVo(FCLUserInfoVo fclUserInfoResponse) {
FCLUserInfoVo.UserProfile userProfile = fclUserInfoResponse.getOutput().getUserProfile();
Optional<String> userId = Optional.ofNullable(userProfile)
.map(FCLUserInfoVo.UserProfile::getLoginInformation)
.map(FCLUserInfoVo.LoginInformation::getUserId);
Optional<String> emailAddress = Optional.ofNullable(userProfile)
.map(FCLUserInfoVo.UserProfile::getUserProfileAddress)
.map(FCLUserInfoVo.UserProfileAddress::getContact)
.map(FCLUserInfoVo.Contact::getEmailAddress)
.filter(email -> !email.isEmpty());
Optional<String> uuid = Optional.ofNullable(userProfile)
.map(FCLUserInfoVo.UserProfile :: getUuid);
Optional<String> firstNameOpt = Optional.ofNullable(userProfile)
.map(FCLUserInfoVo.UserProfile::getUserProfileAddress)
.map(FCLUserInfoVo.UserProfileAddress::getContact)
.map(FCLUserInfoVo.Contact::getPersonName)
.map(personName -> personName.getFirstName());
Optional<String> lastNameOpt = Optional.ofNullable(userProfile)
.map(FCLUserInfoVo.UserProfile::getUserProfileAddress)
.map(FCLUserInfoVo.UserProfileAddress::getContact)
.map(FCLUserInfoVo.Contact::getPersonName)
.map(personName -> personName.getLastName());
String userName = null;
if (firstNameOpt.isPresent() && lastNameOpt.isPresent()){
userName = firstNameOpt.get() + "+" + lastNameOpt.get();
}else if (firstNameOpt.isPresent()){
userName = firstNameOpt.get();
}if (lastNameOpt.isPresent()){
userName = lastNameOpt.get();
}
return new UserDataApiVo(userId.orElse(null), emailAddress.orElse(null),uuid.orElse(null),userName);
}
public FCLTokenResponseVo getFclInterfaceToken(){
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
MultiValueMap<String,String> postParameters = new LinkedMultiValueMap<>();
postParameters.put("client_id", Collections.singletonList(propertiesConfig.getFclClientId()));
postParameters.put("client_secret", Collections.singletonList(propertiesConfig.getFclClientSecret()));
postParameters.put("scope", Collections.singletonList(propertiesConfig.getFclScope()));
postParameters.put("grant_type", Collections.singletonList(propertiesConfig.getFclGrantType()));
HttpEntity<String> entity = new HttpEntity(postParameters,headers);
String fclTokenUrl = propertiesConfig.getFclTokenUrl();
ResponseEntity<FCLTokenResponseVo> resp = restTemplate.exchange(fclTokenUrl, HttpMethod.POST, entity, FCLTokenResponseVo.class);
return resp.getBody();
}
/**
* @Author mt
* @Description 获取fdxLogin
* @Date 2025/5/26
* @param tokenInfo
* @return java.lang.String
*/
private String getFdxLogin(JsonObject tokenInfo) {
if (tokenInfo == null) {
return "";
}
/**
* 先获取fdx_login
*/
return Optional.ofNullable(tokenInfo.get(FCLSessionInfoEnum.FDX_LOGIN.getCode()))
.map(Object::toString)
.orElse("");
}
/**
* @Author mt
* @Description 获取oauthSecret
* @Date 2025/5/26
* @param tokenInfo
* @return java.lang.String
*/
private String getOauthSecret(JsonObject tokenInfo){
Object secretValue = tokenInfo.get(FCLSessionInfoEnum.FCL_OAUTH.getCode());
if (secretValue != null) {
return FCLSessionInfoEnum.FCL_OAUTH.getCode() + "=" + secretValue.toString();
}
return "";
}
/**
* @Author mt
* @Description 安全获取用户名
* @Date 2025/5/26
* @param tokenInfo
* @param userName
* @return java.lang.String
*/
private String getFclContactName(JsonObject tokenInfo,String userName){
String fcl_contactname = "";
if (tokenInfo != null) {
Object contactObj = tokenInfo.get(FCLSessionInfoEnum.FCL_CONTACTNAME.getCode());
if (contactObj != null) {
fcl_contactname = contactObj.toString().replace("\"", "");
}
}
if (StringUtils.isBlank(fcl_contactname) && StringUtils.isNotBlank(userName)){
fcl_contactname = userName;
}
return fcl_contactname;
}
/**
* @Author mt
* @Description 获取uuid
* @Date 2025/5/26
* @param tokenInfo
* @param uuidApi
* @return java.lang.String
*/
private String getUuid(JsonObject tokenInfo, String uuidApi) {
return Optional.ofNullable(tokenInfo)
.map(info -> info.get(FCLSessionInfoEnum.FCL_UUID.getCode()))
.map(Objects::toString)
.orElseGet(() -> Optional.ofNullable(uuidApi)
.orElse(""));
}
/**
* @Author mt
* @Description 对用户名进行解码处理
* @Date 2025/5/26
* @param encodedStr
* @return java.lang.String
*/
private String decodeMultiLevelUrl(String encodedStr) {
if (StringUtils.isBlank(encodedStr)){
return "";
}
String current = encodedStr;
String previous;
do {
previous = current;
try {
current = URLDecoder.decode(current, "UTF-8");
} catch (Exception e) {
return current;
}
} while (!current.equals(previous));
return current;
}
}
......@@ -33,7 +33,7 @@ fcl:
url:
https://iclear-connectuat.apac.fedex.com/manager-server/auth/wlgnLogin
redjrectLogin: https://iclear-connectuat.apac.fedex.com/ipc/#/redjrectLogin
twidx:
preClearIndex:
url: http://iclear-connectuat.apac.fedex.com
interface:
logurl: https://www.fedex.com/secure-login/en-us/#/login-credentials?redirectUrl=http://iclear-connectuat.apac.fedex.com/manager-server/auth/wlgnForward
......
......@@ -26,7 +26,7 @@ fcl:
login:
url: https://exportdeclaration-tw.apac.fedex.com/icleartw/auth/wlgnLogin
redjrectLogin: https://exportdeclaration-tw.apac.fedex.com/IcTw/#/redjrectLogin
twidx:
preClearIndex:
url: https://exportdeclaration-tw.apac.fedex.com
interface:
logurl: https://www.fedex.com/secure-login/zh-tw/#/login-credentials?redirectUrl=https://exportdeclaration-tw.apac.fedex.com/icleartw/auth/wlgnForward
......
......@@ -27,7 +27,7 @@ fcl:
url:
https://iclear-connectuat.apac.fedex.com/manager-server/auth/wlgnLogin
redjrectLogin: https://iclear-connectuat.apac.fedex.com/ipc/#/redjrectLogin
twidx:
preClearIndex:
url: http://iclear-connectuat.apac.fedex.com
interface:
logurl: https://www.fedex.com/secure-login/en-us/#/login-credentials?redirectUrl=http://iclear-connectuat.apac.fedex.com/manager-server/auth/wlgnForward
......
......@@ -26,7 +26,7 @@ fcl:
url:
https://iclear-connectuat.apac.fedex.com/manager-server/auth/wlgnLogin
redjrectLogin: https://iclear-connectuat.apac.fedex.com/ipc/#/redjrectLogin
twidx:
preClearIndex:
url: http://iclear-connectuat.apac.fedex.com
interface:
logurl: https://www.fedex.com/secure-login/en-us/#/login-credentials?redirectUrl=http://iclear-connectuat.apac.fedex.com/manager-server/auth/wlgnForward
......