diff --git a/adc-da-login/src/main/java/com/adc/da/login/config/ShiroFilterConfiguration.java b/adc-da-login/src/main/java/com/adc/da/login/config/ShiroFilterConfiguration.java index f60ca75..d6744d3 100644 --- a/adc-da-login/src/main/java/com/adc/da/login/config/ShiroFilterConfiguration.java +++ b/adc-da-login/src/main/java/com/adc/da/login/config/ShiroFilterConfiguration.java @@ -87,6 +87,9 @@ public class ShiroFilterConfiguration { /* 校验单点登录ticket 不需要认证 */ filterChainDefinitionMap.put(restPath + "/login", ANON); + /* 校验单点登录ticket 不需要认证 */ + filterChainDefinitionMap.put(restPath + "/ssoLogin", ANON); + /* 登出不需认证 */ filterChainDefinitionMap.put(restPath + "/logout/**", ANON); diff --git a/adc-da-login/src/main/java/com/adc/da/login/rest/LoginRestController.java b/adc-da-login/src/main/java/com/adc/da/login/rest/LoginRestController.java index 0edb2ef..8cd8225 100644 --- a/adc-da-login/src/main/java/com/adc/da/login/rest/LoginRestController.java +++ b/adc-da-login/src/main/java/com/adc/da/login/rest/LoginRestController.java @@ -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); diff --git a/adc-da-sys/src/main/java/com/adc/da/sys/constant/SsoConstants.java b/adc-da-sys/src/main/java/com/adc/da/sys/constant/SsoConstants.java new file mode 100644 index 0000000..c9f3764 --- /dev/null +++ b/adc-da-sys/src/main/java/com/adc/da/sys/constant/SsoConstants.java @@ -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="; + +} diff --git a/adc-da-sys/src/main/java/com/adc/da/sys/service/UserEOServiceImpl.java b/adc-da-sys/src/main/java/com/adc/da/sys/service/UserEOServiceImpl.java index 0440713..8751dc6 100644 --- a/adc-da-sys/src/main/java/com/adc/da/sys/service/UserEOServiceImpl.java +++ b/adc-da-sys/src/main/java/com/adc/da/sys/service/UserEOServiceImpl.java @@ -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 list) { if (CollectionUtils.isEmpty(list)) { throw new AdcDaBaseException("数据不能为空"); diff --git a/adc-da-sys/src/main/java/com/adc/da/sys/service/iservice/IUserEoService.java b/adc-da-sys/src/main/java/com/adc/da/sys/service/iservice/IUserEoService.java index d01cf28..70004ea 100644 --- a/adc-da-sys/src/main/java/com/adc/da/sys/service/iservice/IUserEoService.java +++ b/adc-da-sys/src/main/java/com/adc/da/sys/service/iservice/IUserEoService.java @@ -70,4 +70,12 @@ public interface IUserEoService { UserVO getUserByIdNodel(String userId); List getOwnLeader(List orgEOList); + + /** + * IAM单点登录逻辑 + * + * @param code + * @return + */ + String ssoLogin(String code); } diff --git a/adc-da-sys/src/main/java/com/adc/da/sys/vo/iam/SsoResponse.java b/adc-da-sys/src/main/java/com/adc/da/sys/vo/iam/SsoResponse.java new file mode 100644 index 0000000..cd566b7 --- /dev/null +++ b/adc-da-sys/src/main/java/com/adc/da/sys/vo/iam/SsoResponse.java @@ -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; +} diff --git a/adc-da-sys/src/main/java/com/adc/da/sys/vo/iam/SsoUserInfo.java b/adc-da-sys/src/main/java/com/adc/da/sys/vo/iam/SsoUserInfo.java new file mode 100644 index 0000000..ea75078 --- /dev/null +++ b/adc-da-sys/src/main/java/com/adc/da/sys/vo/iam/SsoUserInfo.java @@ -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; +} diff --git a/adc-da-sys/src/main/java/com/adc/da/sys/vo/iam/SsoUserInfoResponse.java b/adc-da-sys/src/main/java/com/adc/da/sys/vo/iam/SsoUserInfoResponse.java new file mode 100644 index 0000000..698f7e2 --- /dev/null +++ b/adc-da-sys/src/main/java/com/adc/da/sys/vo/iam/SsoUserInfoResponse.java @@ -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; +} diff --git a/adc-da-sys/src/main/java/com/adc/da/sys/vo/iam/UserDetailInfo.java b/adc-da-sys/src/main/java/com/adc/da/sys/vo/iam/UserDetailInfo.java new file mode 100644 index 0000000..8921572 --- /dev/null +++ b/adc-da-sys/src/main/java/com/adc/da/sys/vo/iam/UserDetailInfo.java @@ -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 jobs; + private List userTypes; + private List orgs; +}