sso单点登录

This commit is contained in:
lichuanyang 2024-12-05 12:08:54 +08:00
parent b7202c54f5
commit 6f5f61f6a7
6 changed files with 315 additions and 0 deletions

View File

@ -0,0 +1,72 @@
package cn.iocoder.yudao.module.system.controller.admin.outapi;
import cn.iocoder.yudao.module.system.controller.admin.outapi.vo.*;
import cn.iocoder.yudao.module.system.service.outapi.Zhuozi_SSOService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;
@Tag(name = "管理后台 - Zhuozi_SSOController")
@RestController
@RequestMapping("/system/zhuoziSSO")
@Validated
public class Zhuozi_SSOController {
@Resource
Zhuozi_SSOService ssoService;
@PostMapping("/login")
@Operation(summary = "login")
public Map<String, Object> login(@RequestBody ZhuoziSSORegisterVO registerVO) {
Map<String, Object> _out = new HashMap<>();
if (registerVO != null &&
((registerVO.getAppCode() != null && !"".equals(registerVO.getAppCode().trim()) &&
ssoService.getEncryptByPlatform(Zhuozi_SSOService.App_Code).equals(registerVO.getAppCode().trim())) &&
(registerVO.getThirdCode() != null && !"".equals(registerVO.getThirdCode().trim()) &&
ssoService.getEncryptByPlatform(Zhuozi_SSOService.Third_Code1).equals(registerVO.getThirdCode().trim())))) {
_out.put("status", 200);
_out.put("message", "成功");
_out.put("data", new HashMap<String, Object>() {{
put("token", ssoService.createToken());
}});
} else {
_out.put("status", 400);
_out.put("message", "登录失败,appCode或thirdCode不正确!");
_out.put("data", "");
}
return _out;
}
@PostMapping("/thirdInfoLogin")
@Operation(summary = "thirdInfoLogin")
public Map<String, Object> thirdInfoLogin(@RequestBody ZhuoziSSOLoginVO loginVO,
@RequestHeader(value = "Authorization", required = false) String authorization) {
Map<String, Object> _out = new HashMap<>();
if (!(authorization != null && !"".equals(authorization.trim()))) {
_out.put("status", 400);
_out.put("message", "登录失败,请求头[Authorization]不能为空!");
_out.put("data", "");
} else if (!ssoService.verifyToken(authorization.trim())) {
_out.put("status", 400);
_out.put("message", "登录失败,请求头[Authorization]值无效!");
_out.put("data", "");
} else {
try {
String relName = "";
//String relName = ssoService.getDecryptByKey(loginVO.getRelName().trim(), ssoService.getEncryptByPlatform(Zhuozi_SSOService.Third_Code1));
_out = ssoService.SSOLogin(relName, null);
} catch (Exception ex) {
System.out.println(ex.getMessage());
_out = new HashMap<>();
_out.put("status", 400);
_out.put("message", "登录失败,发生异常!");
_out.put("data", "");
}
}
return _out;
}
}

View File

@ -0,0 +1,14 @@
package cn.iocoder.yudao.module.system.controller.admin.outapi.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Schema(description = "管理后台 - ZhuoziSSOLoginVO")
@Data
public class ZhuoziSSOLoginVO {
@Schema(description = "relName")
private String relName;
@Schema(description = "phone")
private String phone;
}

View File

@ -0,0 +1,14 @@
package cn.iocoder.yudao.module.system.controller.admin.outapi.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Schema(description = "管理后台 - ZhuoziSSORegisterVO")
@Data
public class ZhuoziSSORegisterVO {
@Schema(description = "appCode")
private String appCode;
@Schema(description = "thirdCode")
private String thirdCode;
}

View File

@ -0,0 +1,19 @@
package cn.iocoder.yudao.module.system.service.outapi;
import java.util.Map;
public interface Zhuozi_SSOService {
//属性
String App_Code = "FLY_zhuozi_app_CFGKJghcf1165";
String Third_Code1 = "FLY_zhuozi_app_sso_ASEvz2351xw";
Map<String, Object> SSOLogin(String relName, String phone);
String createToken();
boolean verifyToken(String token);
String getEncryptByPlatform(String KEY_PUBLIC);
String getDecryptByKey(String plainText, String key) throws Exception;
}

View File

@ -0,0 +1,192 @@
package cn.iocoder.yudao.module.system.service.outapi.impl;
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
import cn.iocoder.yudao.framework.common.util.monitor.TracerUtils;
import cn.iocoder.yudao.framework.common.util.servlet.ServletUtils;
import cn.iocoder.yudao.module.system.api.logger.dto.LoginLogCreateReqDTO;
import cn.iocoder.yudao.module.system.controller.admin.auth.vo.AuthLoginRespVO;
import cn.iocoder.yudao.module.system.convert.auth.AuthConvert;
import cn.iocoder.yudao.module.system.dal.dataobject.oauth2.OAuth2AccessTokenDO;
import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;
import cn.iocoder.yudao.module.system.enums.logger.LoginLogTypeEnum;
import cn.iocoder.yudao.module.system.enums.logger.LoginResultEnum;
import cn.iocoder.yudao.module.system.enums.oauth2.OAuth2ClientConstants;
import cn.iocoder.yudao.module.system.service.logger.LoginLogService;
import cn.iocoder.yudao.module.system.service.oauth2.OAuth2TokenService;
import cn.iocoder.yudao.module.system.service.outapi.*;
import cn.iocoder.yudao.module.system.service.user.AdminUserService;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.DecodedJWT;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.security.MessageDigest;
import java.util.*;
@Service
public class Zhuozi_SSOServiceImpl implements Zhuozi_SSOService {
@Resource
private AdminUserService userService;
@Resource
private LoginLogService loginLogService;
@Resource
private OAuth2TokenService oauth2TokenService;
//属性
private static final long EXPIRE_DATE = 8 * 60 * 60 * 1000; //8小时
private static final String TOKEN_SECRET = "4b5987503efda54ee658d4a712ebf605";
//接口方法
@Override
public Map<String, Object> SSOLogin(String relName, String phone) {
Map<String, Object> _out = new HashMap<>();
try {
AdminUserDO user = userService.getUserByUsername(relName);
final LoginLogTypeEnum logTypeEnum = LoginLogTypeEnum.LOGIN_USERNAME;
if (user == null) {
createLoginLog(null, relName, logTypeEnum, LoginResultEnum.BAD_CREDENTIALS);
_out.put("status", 400);
_out.put("message", "登录失败,账号不正确!");
_out.put("data", "");
} else if (user != null && CommonStatusEnum.isDisable(user.getStatus())) { //校验是否禁用
createLoginLog(user.getId(), relName, logTypeEnum, LoginResultEnum.USER_DISABLED);
_out.put("status", 400);
_out.put("message", "登录失败,用户被禁用!");
_out.put("data", "");
} else {
createLoginLog(user.getId(), relName, logTypeEnum, LoginResultEnum.SUCCESS);
AuthLoginRespVO authLoginRespVO = null;
OAuth2AccessTokenDO accessTokenDO = oauth2TokenService.createAccessToken(user.getId(), getUserType().getValue(),
OAuth2ClientConstants.CLIENT_ID_DEFAULT, null);
if (accessTokenDO != null)
authLoginRespVO = AuthConvert.INSTANCE.convert(accessTokenDO);
if (authLoginRespVO != null) {
//urlStr
String accessTokenStr = "";
String refreshTokenStr = "";
if (authLoginRespVO.getAccessToken() != null)
accessTokenStr = authLoginRespVO.getAccessToken().trim();
if (authLoginRespVO.getRefreshToken() != null)
refreshTokenStr = authLoginRespVO.getRefreshToken().trim();
final String urlStr = "https://zzxmc.gw12320.com/bl/diagnosis/patientexamlistPathology?accessToken=" + accessTokenStr + "&refreshToken=" + refreshTokenStr;
//_out
_out.put("status", 200);
_out.put("message", "成功");
_out.put("data", new HashMap<String, Object>() {{
put("url", urlStr);
}});
} else {
_out.put("status", 400);
_out.put("message", "登录失败,token生成失败!");
_out.put("data", "");
}
}
} catch (Exception ex) {
System.out.println(ex.getMessage());
_out.clear();
_out.put("status", 400);
_out.put("message", "登录失败,发生异常!");
_out.put("data", "");
}
return _out;
}
@Override
public String createToken() {
String token = null;
try {
//参数
Date date = new Date(System.currentTimeMillis() + EXPIRE_DATE);
Algorithm algorithm = Algorithm.HMAC256(TOKEN_SECRET);
Map<String, Object> header = new HashMap<>();
header.put("typ", "JWT");
header.put("alg", "HS256");
//携带信息,生成签名
token = JWT.create().withHeader(header).withClaim("tokenid", UUID.randomUUID().toString().replace("-", "")).withExpiresAt(date).sign(algorithm);
} catch (Exception ex) {
token = null;
}
return token;
}
@Override
public boolean verifyToken(String token) {
boolean _out = false;
if (token != null && !"".equals(token.trim())) {
try {
Algorithm algorithm = Algorithm.HMAC256(TOKEN_SECRET);
JWTVerifier verifier = JWT.require(algorithm).build();
DecodedJWT jwt = verifier.verify(token.trim());
_out = true;
} catch (Exception ex) {
_out = false;
}
}
return _out;
}
@Override
public String getEncryptByPlatform(String KEY_PUBLIC) {
String _temp = "";
if (KEY_PUBLIC != null && !"".equals(KEY_PUBLIC.trim())) {
try {
MessageDigest md = MessageDigest.getInstance("MD5");
byte[] digest = md.digest(KEY_PUBLIC.trim().getBytes());
StringBuilder sb = new StringBuilder();
for (byte b : digest) {
sb.append(String.format("%02x", b));
}
_temp = sb.toString().trim();
} catch (Exception ex) {
_temp = "";
}
}
if (_temp.length() >= 25) //length:32
_temp = _temp.substring(8, 24);
return _temp;
}
@Override
public String getDecryptByKey(String plainText, String key) throws Exception {
String ENCODING = "utf-8";
String ALGORITHM = "AES";
String PATTERN = "AES/ECB/pkcs5padding";
SecretKey secretKey = new SecretKeySpec(key.getBytes(ENCODING), ALGORITHM);
Cipher cipher = Cipher.getInstance(PATTERN);//获取AES密码器
cipher.init(Cipher.DECRYPT_MODE, secretKey);//初始化密码器(解密模型)
byte[] encryptData = cipher.doFinal(Base64.getDecoder().decode(plainText));//解密数据返回明文
return new String(encryptData, ENCODING);
}
//私有方法
private void createLoginLog(Long userId, String username,
LoginLogTypeEnum logTypeEnum, LoginResultEnum loginResult) {
// 插入登录日志
LoginLogCreateReqDTO reqDTO = new LoginLogCreateReqDTO();
reqDTO.setLogType(logTypeEnum.getType());
reqDTO.setTraceId(TracerUtils.getTraceId());
reqDTO.setUserId(userId);
reqDTO.setUserType(getUserType().getValue());
reqDTO.setUsername(username);
reqDTO.setUserAgent(ServletUtils.getUserAgent());
reqDTO.setUserIp(ServletUtils.getClientIP());
reqDTO.setResult(loginResult.getResult());
loginLogService.createLoginLog(reqDTO);
// 更新最后登录时间
if (userId != null && Objects.equals(LoginResultEnum.SUCCESS.getResult(), loginResult.getResult())) {
userService.updateUserLogin(userId, ServletUtils.getClientIP());
}
}
private UserTypeEnum getUserType() {
return UserTypeEnum.ADMIN;
}
}

View File

@ -172,6 +172,8 @@ yudao:
- /admin-api/tblist/patientexamlist/getplexamiddata
- /admin-api/tblist/patientexamlist/insert
- /admin-api/tblist/ecganalysisparas/insert
- /admin-api/system/zhuoziSSO/login
- /admin-api/system/zhuoziSSO/thirdInfoLogin
websocket:
enable: true # websocket的开关
path: /infra/ws # 路径
@ -229,6 +231,8 @@ yudao:
- /admin-api/tblist/patientexamlist/getplexamiddata
- /admin-api/tblist/patientexamlist/insert
- /admin-api/tblist/ecganalysisparas/insert
- /admin-api/system/zhuoziSSO/login
- /admin-api/system/zhuoziSSO/thirdInfoLogin
ignore-tables:
- system_tenant
- system_tenant_package