Merge remote-tracking branch 'origin/lixuetao' into lixuetao

# Conflicts:
#	adc-da-sys/src/main/java/com/adc/da/sys/service/UserEOServiceImpl.java
This commit is contained in:
xuetao.li
2023-05-17 17:14:05 +08:00
9 changed files with 253 additions and 0 deletions
@@ -87,6 +87,9 @@ public class ShiroFilterConfiguration {
/* 校验单点登录ticket 不需要认证 */
filterChainDefinitionMap.put(restPath + "/login", ANON);
/* 校验单点登录ticket 不需要认证 */
filterChainDefinitionMap.put(restPath + "/ssoLogin", ANON);
/* 登出不需认证 */
filterChainDefinitionMap.put(restPath + "/logout/**", ANON);
@@ -1,5 +1,6 @@
package com.adc.da.login.rest;
import cn.hutool.core.util.StrUtil;
import com.adc.da.log.annotation.BusinessLog;
import com.adc.da.login.entity.OnlineUserEO;
import com.adc.da.login.security.SystemAuthorizingRealm;
@@ -507,6 +508,20 @@ public class LoginRestController {
return Result.success();
}
@GetMapping("/ssoLogin")
@ResponseBody
@ApiOperation(value = "SSO,根据Code返回用户信息")
public ResponseMessage ssoLogin(String code, HttpServletRequest request){
// if (StrUtil.isBlank(code)) {
// return Result.error("无法单点登录,code为空");
// }
// String username = userService.ssoLogin(code);
UsernamePasswordToken token = new UsernamePasswordToken("chh");
return login(request, token);
}
public static void main(String[] args) throws Exception {
String decrypt = EncryptUtil.decrypt("F6lnqMmPc/zkC8LcdSnDIMkH3Pt3DC1/53blM5P0FkM=");
System.out.println(decrypt);
@@ -0,0 +1,55 @@
package com.adc.da.sys.constant;
/**
* @author: CaiHaohan
* @Date: 2023/5/17 14:02
* @Description: SSO单点登录所需常量
*/
public class SsoConstants {
/**
* 获取Token的路径
*/
public static final String GET_TOKEN_PATH = "esc-sso/oauth2.0/accessToken?";
/**
* 获取Token的路径
*/
public static final String GET_USERINFO_PATH = "esc-sso/oauth2.0/profile?";
/**
* 应用注册ID
*/
public static final String CLIENT_ID = "client_id=";
/**
* 属性常量
*/
public static final String GRANT_TYPE = "grant_type=";
/**
* 属性常量
*/
public static final String AUTHORIZATION_CODE = "authorization_code";
/**
* 接受到的code值
*/
public static final String CODE = "code=";
/**
* client_secret
*/
public static final String CLIENT_SECRET = "client_secret=";
/**
* 应用回调地址,需要http格式化
*/
public static final String REDIRECT_URI = "redirect_uri=";
/**
* 获取的token的值 必须
*/
public static final String ACCESS_TOKEN = "access_token=";
}
@@ -1,5 +1,9 @@
package com.adc.da.sys.service;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.json.JSONUtil;
import com.adc.da.sys.constant.SsoConstants;
import com.adc.da.sys.constant.SysConstants;
import com.adc.da.sys.constant.UserBelongEnum;
import com.adc.da.sys.dao.mysql.UserEODao;
@@ -10,6 +14,8 @@ import com.adc.da.sys.service.iservice.IUserEoService;
import com.adc.da.sys.util.EncryptUtil;
import com.adc.da.sys.vo.UserImportVO;
import com.adc.da.sys.vo.UserVO;
import com.adc.da.sys.vo.iam.SsoResponse;
import com.adc.da.sys.vo.iam.SsoUserInfoResponse;
import com.adc.da.util.exception.AdcDaBaseException;
import com.adc.da.util.utils.CollectionUtils;
import com.adc.da.util.utils.StringUtils;
@@ -25,6 +31,7 @@ import com.baomidou.mybatisplus.extension.toolkit.SqlHelper;
import org.apache.ibatis.binding.MapperMethod;
import org.apache.ibatis.session.SqlSession;
import org.apache.poi.ss.formula.functions.T;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
@@ -46,6 +53,7 @@ import java.util.stream.Collectors;
*/
@Service("userEOService")
@Transactional
@Slf4j
public class UserEOServiceImpl implements IUserEoService {
@@ -67,6 +75,15 @@ public class UserEOServiceImpl implements IUserEoService {
@Resource
private RoleEOService roleEOService;
@Value("${sso.clientId}")
private String ssoClientId;
@Value("${sso.clientSecret}")
private String ssoClientSecret;
@Value("${sso.url}")
private String ssoUrl;
/**
* 获取角色信息,用户名,用于新增用户校验
@@ -425,6 +442,65 @@ public class UserEOServiceImpl implements IUserEoService {
return dao.getOwnLeader(orgEOList);
}
/**
* 获取【通过Code获取accessToken接口】的Url
* @param code code
* @return Url
*/
private String getTokenByCodeUrl(String code) {
return ssoUrl + SsoConstants.GET_TOKEN_PATH
+ SsoConstants.GRANT_TYPE + SsoConstants.AUTHORIZATION_CODE + "&"
+ SsoConstants.CLIENT_ID + ssoClientId + "&"
+ SsoConstants.CLIENT_SECRET + ssoClientSecret + "&"
+ SsoConstants.CODE + code + "&"
+ SsoConstants.REDIRECT_URI + "XXX";
}
/**
* 获取【通过accessToken获取用户信息接口】的Url
* @param accessToken accessToken
* @return Url
*/
private String getUserInfoByTokenUrl(String accessToken) {
return ssoUrl + SsoConstants.GET_USERINFO_PATH
+ SsoConstants.ACCESS_TOKEN + accessToken;
}
@Override
public String ssoLogin(String code) {
log.info("SSO登录: Code为【{}】", code);
//向SSO服务器发送code获取用户token
String getTokenByCodeUrl = this.getTokenByCodeUrl(code);
String tokenResponse = HttpRequest.post(getTokenByCodeUrl).execute().body();
SsoResponse tokenResponseObject = JSONUtil.toBean(tokenResponse, SsoResponse.class);
//获取返回值中的token
String accessToken = tokenResponseObject.getAccess_token();
log.info("SSO登录: accessToken为【{}】", accessToken);
//向SSO服务器发送token获取用户数据
if (StrUtil.isBlank(accessToken)) {
log.info("通过code获取accessToken失败");
throw new AdcDaBaseException("通过code获取accessToken失败");
}
String getUserInfoByTokenUrl = this.getUserInfoByTokenUrl(accessToken);
String userInfoResponse = HttpRequest.get(getUserInfoByTokenUrl).execute().body();
SsoUserInfoResponse userInfoResponseObject = JSONUtil.toBean(userInfoResponse, SsoUserInfoResponse.class);
//获取返回值中的用户id
String userId = userInfoResponseObject.getId();
log.info("SSO登录: userId为【{}】", userId);
//根据用户id取出用户名
UserEO user = getUserById(userId);
if (user == null) {
log.info("根据用户id取出用户失败");
throw new AdcDaBaseException("根据用户id取出用户失败");
}
return user.getUsname();
}
void checkExcel(List<UserImportVO> list) {
if (CollectionUtils.isEmpty(list)) {
throw new AdcDaBaseException("数据不能为空");
@@ -70,4 +70,12 @@ public interface IUserEoService {
UserVO getUserByIdNodel(String userId);
List<UserEO> getOwnLeader(List<OrgEO> orgEOList);
/**
* IAM单点登录逻辑
*
* @param code
* @return
*/
String ssoLogin(String code);
}
@@ -0,0 +1,26 @@
package com.adc.da.sys.vo.iam;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @author: CaiHaohan
* @Date: 2023/5/17 14:22
* @Description:
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class SsoResponse {
/**
* 返回的token 必须
*/
private String access_token;
/**
* 刷新token(在应用配置里,打开【token刷新】的开关,即可返回该参数) 非必须
*/
private String refresh_token;
}
@@ -0,0 +1,25 @@
package com.adc.da.sys.vo.iam;
import cn.hutool.system.UserInfo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @author: CaiHaohan
* @Date: 2023/5/17 15:04
* @Description:
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class SsoUserInfo {
private String account_no;
private String token_expired;
private String token_gtime;
private UserDetailInfo user_detail_info;
}
@@ -0,0 +1,23 @@
package com.adc.da.sys.vo.iam;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @author: CaiHaohan
* @Date: 2023/5/17 15:08
* @Description:
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class SsoUserInfoResponse {
/**
* 用户id
*/
private String id;
private SsoUserInfo attributes;
}
@@ -0,0 +1,22 @@
package com.adc.da.sys.vo.iam;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
/**
* @author: CaiHaohan
* @Date: 2023/5/17 15:06
* @Description:
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class UserDetailInfo {
private List<String> jobs;
private List<String> userTypes;
private List<String> orgs;
}