IAM对接

This commit is contained in:
efren
2025-06-16 17:15:56 +08:00
parent 9b35bad200
commit 07c664d7ff
22 changed files with 1003 additions and 11 deletions

View File

@ -1,15 +1,85 @@
package com.chinaunicom.mall.ebtp.extend.iam.client;
import com.chinaunicom.mall.ebtp.extend.iam.entity.AuthRequestDTO;
import com.chinaunicom.mall.ebtp.extend.iam.entity.AuthResponseDTO;
import com.chinaunicom.mall.ebtp.extend.iam.entity.*;
import com.chinaunicom.mall.ebtp.extend.iam.entity.data.IamEmployee;
import com.chinaunicom.mall.ebtp.extend.iam.entity.data.IamUser;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.cloud.openfeign.SpringQueryMap;
import org.springframework.web.bind.annotation.*;
@FeignClient(name = "iam-service", url = "${iam.service.url}")
@FeignClient(name = "iam-service", url = "${spring.iam.url}")
public interface IamClient {
@PostMapping("/access_token")
AuthResponseDTO getAccessToken(@RequestBody AuthRequestDTO request);
/**
* (获取code)oauth2认证接口-未认证跳转统一认证前端已认证则发放code
* @param request 获取授权请求参数
* @return
* {"statusCodeValue":0,"msg":null,"data":"http://10.11.4.13:9999/#/digital?code=501679ca-f036-4ed1-9414-585315d8627d"}
*/
@GetMapping("/authz/oauth/v20/authorize")
IamAuthResponseDTO<String> authorize(@SpringQueryMap IamAuthRequestDTO request);
/**
* jwt使用员工号免密登录
* @param jwt 员工号jwt
* @return
* {
* "statusCodeValue": 0,
* "msg": null,
* "data": {
* "ticket": "string",
* "type": "string",
* "token": "string",
* "redirectUrl": null,
* "remeberMe": null,
* "id": "string",
* "name": "string",
* "username": "string",
* "displayName": "string",
* "email": "string",
* "instId": "string",
* "instName": null,
* "passwordSetType": 0,
* "authorities": [
* "string"
* ],
* "refresh_token": "string",
* "expired": 0
* }
* }
*/
@GetMapping("/login/jwt/employee")
IamAuthResponseDTO<IamEmployee> employee(@RequestParam("jwt") String jwt);
/**
* 获取用户信息接口
* @param authorization Bearer Token
* @return IamUserDTO 用户信息
*/
@GetMapping("/api/oauth/v20/me")
IamUser me(@RequestHeader("Authorization") String authorization);
/**
* code换token
* @param request 获取iamToken
* grant_type * string 固定值 authorization_code
* code * string 跳转Url带的code参数 43d9b6ea-a130-4680-b98c-a5bfec87168d
* redirect_uri * string 跳转地址 http%3A%2F%2F10.11.4.13%3A9999%2F%23%2Fdigital
* client_id * string 应用id 1018630382704132096
* client_secret * string 应用密钥 hT2MMDcwODIwMjQxODM0MzQxMDYsHE
* @return
* {
* "access_token": "efc3ae0f-7a66-40aa-916b-010d83bf46fb",
* "token_type": "bearer",
* "expires_in": 16503,
* "scope": "read all"
* }
*/
@GetMapping("/authz/oauth/v20/token")
IamToken token(@RequestHeader("Authorization") String authorization, IamTokenRequestDTO request);
}

View File

@ -0,0 +1,26 @@
package com.chinaunicom.mall.ebtp.extend.iam.constant;
import lombok.Getter;
/**
* IAM响应码枚举
* 定义与IAM相关的响应码和描述
*/
@Getter
public enum IamEnum {
IAM_RESP_SUCCESS_CODE(0, "IAM响应成功"),
IAM_RESP_SYSTEM_BUSY_CODE(-1, "IAM系统繁忙错误码"),
IAM_RESP_AUTH_ERROR_CODE(400401, "IAM鉴权错误码"),
IAM_RESP_NO_PERMISSION_CODE(400403, "IAM无权限操作错误码"),
IAM_RESP_NOT_FOUND_CODE(400404, "IAM请求资源不存在错误码"),
IAM_RESP_CONFLICT_CODE(400409, "IAM唯一属性被占用错误码");
private final int code;
private final String desc;
IamEnum(int code, String desc) {
this.code = code;
this.desc = desc;
}
}

View File

@ -1,13 +1,20 @@
package com.chinaunicom.mall.ebtp.extend.iam.controller;
import com.chinaunicom.mall.ebtp.common.base.entity.BaseResponse;
import com.chinaunicom.mall.ebtp.extend.iam.client.BidRatioClient;
import com.chinaunicom.mall.ebtp.extend.iam.constant.IamEnum;
import com.chinaunicom.mall.ebtp.extend.iam.entity.*;
import com.chinaunicom.mall.ebtp.extend.iam.entity.data.IamEmployee;
import com.chinaunicom.mall.ebtp.extend.iam.entity.data.IamUser;
import com.chinaunicom.mall.ebtp.extend.iam.service.IamAuthService;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.*;
import java.util.Objects;
@RestController
@Api(tags = "IAM单点登陆接口")
@RequestMapping("/iam/auth")
public class IamAuthController {
@ -35,4 +42,63 @@ public class IamAuthController {
public String getBidRatio(@PathVariable("id") String id) {
return bidRatioClient.getBidRatio(id);
}
/**
* IAM单点登陆 - (获取code)oauth2认证接口-未认证跳转统一认证前端已认证则发放code
* @see com.chinaunicom.mall.ebtp.extend.iam.client.IamClient#authorize(IamAuthRequestDTO)
* @param request 获取授权请求参数
* @return IAM授权响应
*/
@ApiOperation("IAM单点登陆 - (获取code)oauth2认证接口-未认证跳转统一认证前端已认证则发放code")
@GetMapping("/authorize")
public BaseResponse<String> authorize(IamAuthRequestDTO request){
IamAuthResponseDTO<String> authorize = iamAuthService.authorize(request);
if (Objects.equals(authorize.getStatusCodeValue(), IamEnum.IAM_RESP_SUCCESS_CODE.getCode())) {
return BaseResponse.success(authorize.getMsg(), authorize.getData());
} else {
return BaseResponse.fail(authorize.getMsg(), authorize.getData());
}
}
/**
* IAM单点登陆 - jwt使用员工号免密登录
* @see com.chinaunicom.mall.ebtp.extend.iam.client.IamClient#employee(String)
* @param jwt 员工号jwt
* @return IAM员工信息
*/
@ApiOperation("IAM单点登陆 - jwt使用员工号免密登录")
@GetMapping("/jwt")
public BaseResponse<IamEmployee> employee(@RequestParam("jwt") String jwt) {
IamAuthResponseDTO<IamEmployee> response = iamAuthService.employee(jwt);
if (Objects.equals(response.getStatusCodeValue(), IamEnum.IAM_RESP_SUCCESS_CODE.getCode())) {
return BaseResponse.success(response.getMsg(), response.getData());
} else {
return BaseResponse.fail(response.getMsg(), response.getData());
}
}
/**
* IAM单点登陆 - 获取用户信息接口
* @see com.chinaunicom.mall.ebtp.extend.iam.client.IamClient#me(String)
* @return iam用户信息
*/
@ApiOperation("IAM单点登陆 - 获取用户信息接口")
@GetMapping("/getUser")
public BaseResponse<IamUser> getUser(){
return BaseResponse.success(iamAuthService.me());
}
/**
* IAM单点登陆 - code换token
* @see com.chinaunicom.mall.ebtp.extend.iam.client.IamClient#token(String, IamTokenRequestDTO)
* @param request 获取iamToken
* @return iamToken
*/
@ApiOperation("IAM单点登陆 - code换token")
@GetMapping("/getTokenByCode")
public BaseResponse<IamToken> getTokenByCode(IamTokenRequestDTO request) {
String authorization = "";
return BaseResponse.success(iamAuthService.getToken(authorization, request));
}
}

View File

@ -0,0 +1,148 @@
package com.chinaunicom.mall.ebtp.extend.iam.controller;
import com.chinaunicom.mall.ebtp.extend.iam.entity.IamApiRequestDTO;
import com.chinaunicom.mall.ebtp.extend.iam.entity.IamApiResponseDTO;
import com.chinaunicom.mall.ebtp.extend.iam.entity.data.IamApiDepartment;
import com.chinaunicom.mall.ebtp.extend.iam.service.IamDepartmentService;
import com.baomidou.mybatisplus.core.metadata.IPage;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.util.List;
/**
* 参考IAM系统组织架构同步接口标准.docx
* 提供给IAM的同步组织的接口
* 组织架构管理接口
* - 获取组织架构列表接口
* - 新增组织架构接口
* - 更新组织架构接口
* - 删除/停用组织架构接口
*/
@RestController
@Api(tags = "IAM同步组织架构接口")
@RequestMapping("/iam/api")
@Slf4j
public class IamDepartmentController {
@Resource
private IamDepartmentService iamDepartmentService;
/**
* 获取人员列表接口
* 请求方式GET
* 请求地址:
* {url}/departments?pageIndex={pageIndex}&pageSize={pageSize}&startTime={startTime}&endTime={endTime}
* @param departmentRequestDTO 组织架构列表请求参数实体
* 名称 格式 描述
* url string 合作方应用接口地址,例如 <a href="https://iam.com/api/">文档样例</a> <a href="http://localhost:18018/iam/api/departments">本地接口</a>
* pageIndex number 分页索引从0开始
* pageSize number 分页大小支持至少300
* startTime number 最近变更时间的起始时间unix毫秒时间戳用于增量
* endTime number 最近变更时间的终止时间unix毫秒时间戳用于增量
* @return 组织架构列表信息 样例:
* {
* "errorCode": 0, // success
* "total":100,//组织架构总数
* "data":[
* {
* "id":"xxx",
* "name":"xxx",
* "parentId":"xxx"//上级组织架构的ID
* "status":"xxx"//标识组织架构的停启用
* },
* ……
* ]
* }
*/
@ApiOperation("获取组织架构列表接口")
@GetMapping("/departments")
public IamApiResponseDTO<List<IamApiDepartment>> getDepartments(IamApiRequestDTO departmentRequestDTO){
log.debug("departments请求参数:{}", departmentRequestDTO);
IPage<IamApiDepartment> page = iamDepartmentService.getDepartments(departmentRequestDTO);
List<IamApiDepartment> depts = page.getRecords();
log.debug("departments返回结果:{}", depts);
IamApiResponseDTO<List<IamApiDepartment>> iamApiResponse = IamApiResponseDTO.success(depts);
iamApiResponse.setTotal((int) page.getTotal());
return iamApiResponse;
}
/**
* 新增组织架构接口
* 请求方式POST
* 请求地址:
* {url}/user
* @param iamApiDepartment 组织架构请求参数实体
* 请求体Request Body
* {
* "name":"xxx",
* "parentId":"xxx"//上级组织架构的ID
* }
* @return 新增组织架构ID 样例:
* 请求返回体Response Body
* {
* "errorCode": 0, // success
* "errorMsg":null,//若errorCode不为0此处应有错误描述
* "id":"xxx"//返回新增的组织架构的id必须
* }
*/
@ApiOperation("新增组织架构接口")
@PostMapping("/department")
public IamApiResponseDTO<String> saveDepartment(@RequestBody IamApiDepartment iamApiDepartment){
log.debug("saveUser请求参数:{}", iamApiDepartment);
Boolean saveResult = iamDepartmentService.save(iamApiDepartment);
log.debug("saveUser返回结果:{}, {}", saveResult, iamApiDepartment);
return IamApiResponseDTO.success(iamApiDepartment.getId());
}
/**
* 更新组织架构接口
* 请求方式PUT
* 请求地址:
* {url}/user/{id}
* @param iamApiDepartment 组织架构请求参数实体
* 请求体Request Body
* {
* "name":"xxx",
* "parentId":"xxx"//上级组织架构的ID
* }
* @return 更新结果 样例:
* {
* "errorCode": 0, // success
* "errorMsg":null//若errorCode不为0此处应有错误描述
* }
*/
@ApiOperation("更新组织架构接口")
@PutMapping("/department")
public IamApiResponseDTO<Object> updateDepartment(@RequestBody IamApiDepartment iamApiDepartment) {
log.debug("updateDepartment请求参数:{}", iamApiDepartment);
boolean updateResult = iamDepartmentService.updateById(iamApiDepartment);
log.debug("updateDepartment返回结果:{}", updateResult);
return IamApiResponseDTO.success();
}
/**
* 删除/停用组织架构接口
* 请求方式DELETE
* 请求地址:
* {url}/department/{id}
* @param id 组织架构ID
* @return 删除/停用结果 样例:
* {
* "errorCode": 0, // success
* "errorMsg":null//若errorCode不为0此处应有错误描述
* }
*/
@ApiOperation("删除/停用组织架构接口")
@DeleteMapping("/department/{id}")
public IamApiResponseDTO<Object> deleteDepartment(@PathVariable("id") String id) {
log.debug("deleteDepartment请求参数:{}", id);
boolean deleteResult = iamDepartmentService.removeById(id);
log.debug("deleteDepartment返回结果:{}", deleteResult);
return IamApiResponseDTO.success();
}
}

View File

@ -0,0 +1,155 @@
package com.chinaunicom.mall.ebtp.extend.iam.controller;
import com.chinaunicom.mall.ebtp.extend.iam.entity.data.IamApiUser;
import com.chinaunicom.mall.ebtp.extend.iam.entity.IamApiResponseDTO;
import com.chinaunicom.mall.ebtp.extend.iam.entity.IamApiRequestDTO;
import com.chinaunicom.mall.ebtp.extend.iam.service.IamUserService;
import com.baomidou.mybatisplus.core.metadata.IPage;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.util.List;
/**
* 参考IAM系统组织架构同步接口标准.docx
* 提供给IAM的同步人员的接口
* 人员管理接口
* - 获取人员列表接口
* - 新增人员接口
* - 更新人员接口
* - 删除/停用人员接口
*/
@RestController
@Api(tags = "IAM同步人员接口")
@RequestMapping("/iam/api")
@Slf4j
public class IamUserController {
@Resource
private IamUserService iamUserService;
/**
* 获取人员列表接口
* 请求方式GET
* 请求地址:
* {url}/users?pageIndex={pageIndex}&pageSize={pageSize}&startTime={startTime}&endTime={endTime}
* @param userRequestDTO 人员列表请求参数实体
* 名称 格式 描述
* url string 合作方应用接口地址,例如 <a href="https://iam.com/api/">文档样例</a> <a href="http://localhost:18018/iam/api/users">本地接口</a>
* pageIndex number 分页索引从0开始
* pageSize number 分页大小支持至少300
* startTime number 最近变更时间的起始时间unix毫秒时间戳用于增量
* endTime number 最近变更时间的终止时间unix毫秒时间戳用于增量
* @return 人员列表信息 样例:
* {
* "errorCode": 0, // success
* "total":1000,//人员总数
* "data":[
* {
* "id":"xxx",
* "name":"xxx",
* "email":"xxx",
* "mobile":"xxx",
* "departmentId":"xxx"//所在组织架构的 ID
* "status":"xxx"//标识人员的停启用
* },
* ……
* ]
* }
*/
@ApiOperation("获取人员列表接口")
@GetMapping("/users")
public IamApiResponseDTO<List<IamApiUser>> getUsers(IamApiRequestDTO userRequestDTO){
log.debug("users请求参数:{}", userRequestDTO);
IPage<IamApiUser> page = iamUserService.getUsers(userRequestDTO);
List<IamApiUser> users = page.getRecords();
log.debug("users返回结果:{}", users);
IamApiResponseDTO<List<IamApiUser>> iamApiResponse = IamApiResponseDTO.success(users);
iamApiResponse.setTotal((int) page.getTotal());
return iamApiResponse;
}
/**
* 新增人员接口
* 请求方式POST
* 请求地址:
* {url}/user
* @param iamApiUser 人员请求参数实体
* 请求体Request Body
* {
* "name":"xxx",
* "email":"xxx",
* "mobile":"xxx",
* "departmentId":"xxx"//所在组织架构的ID
* }
* @return 新增人员ID 样例:
* 请求返回体Response Body
* {
* "errorCode": 0, // success
* "errorMsg":null,//若errorCode不为0此处应有错误描述
* "id":"xxx"//返回新增的人员的id必须
* }
*/
@ApiOperation("新增人员接口")
@PostMapping("/user")
public IamApiResponseDTO<String> saveUser(@RequestBody IamApiUser iamApiUser){
log.debug("saveUser请求参数:{}", iamApiUser);
Boolean saveResult = iamUserService.save(iamApiUser);
log.debug("saveUser返回结果:{}, {}", saveResult, iamApiUser);
return IamApiResponseDTO.success(iamApiUser.getId());
}
/**
* 更新人员接口
* 请求方式PUT
* 请求地址:
* {url}/user/{id}
* @param iamApiUser 人员请求参数实体
* 请求体Request Body
* {
* "name":"xxx",
* "email":"xxx",
* "mobile":"xxx",
* "departmentId":"xxx"//所在组织架构的ID
* }
* @return 更新结果 样例:
* {
* "errorCode": 0, // success
* "errorMsg":null,//若errorCode不为0此处应有错误描述
* }
*/
@ApiOperation("更新人员接口")
@PutMapping("/user/{id}")
public IamApiResponseDTO<Object> updateUser(@PathVariable("id") String id, @RequestBody IamApiUser iamApiUser) {
log.debug("updateUser请求参数:id={}, user={}", id, iamApiUser);
iamApiUser.setId(id);
boolean updateResult = iamUserService.updateById(iamApiUser);
log.debug("updateUser返回结果:{}", updateResult);
return IamApiResponseDTO.success();
}
/**
* 删除/停用人员接口
* 请求方式DELETE
* 请求地址:
* {url}/user/{id}
* @param id 人员ID
* @return 删除/停用结果 样例:
* {
* "errorCode": 0, // success
* "errorMsg":null//若errorCode不为0此处应有错误描述
* }
*/
@ApiOperation("删除/停用人员接口")
@DeleteMapping("/user/{id}")
public IamApiResponseDTO<Object> deleteUser(@PathVariable("id") String id) {
log.debug("deleteUser请求参数:{}", id);
boolean deleteResult = iamUserService.removeById(id);
log.debug("deleteUser返回结果:{}", deleteResult);
return IamApiResponseDTO.success();
}
}

View File

@ -0,0 +1,7 @@
package com.chinaunicom.mall.ebtp.extend.iam.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.chinaunicom.mall.ebtp.extend.iam.entity.data.IamApiDepartment;
public interface IamDepartmentMapper extends BaseMapper<IamApiDepartment> {
}

View File

@ -0,0 +1,7 @@
package com.chinaunicom.mall.ebtp.extend.iam.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.chinaunicom.mall.ebtp.extend.iam.entity.data.IamApiUser;
public interface IamUserMapper extends BaseMapper<IamApiUser> {
}

View File

@ -0,0 +1,20 @@
package com.chinaunicom.mall.ebtp.extend.iam.entity;
import lombok.Data;
/**
* IAM用户请求DTO
* 用于分页查询IAM用户信息
*/
@Data
public class IamApiRequestDTO {
/* 分页索引从0开始 */
private Integer pageIndex = 0;
/* 分页大小支持至少300 */
private Integer pageSize = 10;
/* 最近变更时间的起始时间unix毫秒时间戳用于增量 */
private Long startTime;
/* 最近变更时间的终止时间unix毫秒时间戳用于增量 */
private Long endTime;
}

View File

@ -0,0 +1,116 @@
package com.chinaunicom.mall.ebtp.extend.iam.entity;
import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.Data;
import java.io.Serializable;
/**
* IAM基础响应DTO
* 用于统一处理IAM接口的响应格式
* @param <T> 响应数据类型
*/
@Data
public class IamApiResponseDTO<T> implements Serializable {
private static final long serialVersionUID = 6769157532172136264L;
/**
* 错误码
* 0表示成功其他值表示失败
*/
private Integer errorCode;
/**
* 错误信息
*/
private String errorMsg;
/**
* 总记录数
*/
@JsonInclude(JsonInclude.Include.NON_NULL)
private Integer total;
/**
* 响应数据
* 泛型类型,具体数据结构由调用方定义
*/
@JsonInclude(JsonInclude.Include.NON_NULL)
private T data;
public static IamApiResponseDTO<Object> success() {
IamApiResponseDTO<Object> resp = new IamApiResponseDTO<>();
resp.setErrorCode(0);
resp.setErrorMsg(null);
return resp;
}
public static <T> IamApiResponseDTO<T> success(T data) {
IamApiResponseDTO<T> resp = new IamApiResponseDTO<>();
resp.setErrorCode(0);
resp.setErrorMsg(null);
resp.setData(data);
return resp;
}
public static <T> IamApiResponseDTO<T> success(String errorMsg, T data) {
IamApiResponseDTO<T> resp = new IamApiResponseDTO<>();
resp.setErrorCode(0);
resp.setErrorMsg(errorMsg);
resp.setData(data);
return resp;
}
public static IamApiResponseDTO<Object> fail() {
IamApiResponseDTO<Object> resp = new IamApiResponseDTO<>();
resp.setErrorCode(-1);
resp.setErrorMsg("error");
return resp;
}
public static IamApiResponseDTO<String> fail(String errorMsg) {
IamApiResponseDTO<String> resp = new IamApiResponseDTO<>();
resp.setErrorCode(-1);
resp.setErrorMsg(errorMsg);
resp.setData(null);
return resp;
}
public static IamApiResponseDTO<String> fail(Integer errorCode, String errorMsg) {
IamApiResponseDTO<String> resp = new IamApiResponseDTO<>();
resp.setErrorCode(errorCode);
resp.setErrorMsg(errorMsg);
resp.setData(null);
return resp;
}
public static <T> IamApiResponseDTO<T> fail(T data) {
IamApiResponseDTO<T> resp = new IamApiResponseDTO<>();
resp.setErrorCode(-1);
resp.setErrorMsg("error");
resp.setData(null);
return resp;
}
public static <T> IamApiResponseDTO<T> fail(String errorMsg, T data) {
IamApiResponseDTO<T> resp = new IamApiResponseDTO<>();
resp.setErrorCode(-1);
resp.setErrorMsg(errorMsg);
resp.setData(null);
return resp;
}
public static <T> IamApiResponseDTO<T> fail(Integer errorCode, String errorMsg, T data) {
IamApiResponseDTO<T> resp = new IamApiResponseDTO<>();
resp.setErrorCode(errorCode);
resp.setErrorMsg(errorMsg);
resp.setData(null);
return resp;
}
public IamApiResponseDTO() {
}
public IamApiResponseDTO(final Integer errorCode, final String errorMsg, final Integer total, final T data) {
this.errorCode = errorCode;
this.errorMsg = errorMsg;
this.total = total;
this.data = data;
}
}

View File

@ -0,0 +1,12 @@
package com.chinaunicom.mall.ebtp.extend.iam.entity;
import lombok.Data;
@Data
public class IamAuthRequestDTO {
private String client_id;
private String response_type = "code";
private String redirect_uri;
private String approval_prompt = "auto";
private String approved = "true";
}

View File

@ -0,0 +1,44 @@
package com.chinaunicom.mall.ebtp.extend.iam.entity;
import lombok.Data;
/**
* (获取code)oauth2认证接口-未认证跳转统一认证前端已认证则发放code
* {
* "statusCodeValue":0,
* "msg":null,
* "data":"http://10.11.4.13:9999/#/digital?code=501679ca-f036-4ed1-9414-585315d8627d"
* }
* jwt使用员工号免密登录
* {
* "statusCodeValue": 0,
* "msg": null,
* "data": {
* "ticket": "string",
* "type": "string",
* "token": "string",
* "redirectUrl": null,
* "remeberMe": null,
* "id": "string",
* "name": "string",
* "username": "string",
* "displayName": "string",
* "email": "string",
* "instId": "string",
* "instName": null,
* "passwordSetType": 0,
* "authorities": [
* "string"
* ],
* "refresh_token": "string",
* "expired": 0
* }
* }
*/
@Data
public class IamAuthResponseDTO<T> {
private T data;
private String msg;
private Integer statusCodeValue;
}

View File

@ -0,0 +1,20 @@
package com.chinaunicom.mall.ebtp.extend.iam.entity;
import lombok.Data;
/**
* IAM单点登陆Token令牌实体类
*/
@Data
public class IamToken {
// 访问令牌
private String access_token;
// 刷新令牌
private String refresh_token;
// 令牌类型
private String token_type;
// 过期时间(秒)
private Integer expires_in;
// 授权范围
private String scope;
}

View File

@ -0,0 +1,30 @@
package com.chinaunicom.mall.ebtp.extend.iam.entity;
import lombok.Data;
/**
* 获取IAM token的请求实体
*/
@Data
public class IamTokenRequestDTO {
/**
* 固定值 authorization_code
*/
private String grant_type;
/**
* 跳转Url带的code参数
*/
private String code;
/**
* 跳转地址
*/
private String redirect_uri;
/**
* 应用id
*/
private String client_id;
/**
* 应用密钥
*/
private String client_secret;
}

View File

@ -0,0 +1,43 @@
package com.chinaunicom.mall.ebtp.extend.iam.entity.data;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModel;
import lombok.Data;
import lombok.experimental.Accessors;
import java.util.Date;
/**
* {
* "errorCode": 0, // success
* "total":100,//组织架构总数
* "data":[
* {
* "id":"xxx",
* "name":"xxx",
* "parentId":"xxx"//上级组织架构的ID
* "status":"xxx"//标识组织架构的停启用
* },
* ……
* ]
* }
*/
@Data
@Accessors(chain = true)
@TableName(value = "iam_api_department", autoResultMap = true)
@ApiModel(value = "IamApiDepartment对象", description = "组织架构基本信息表")
public class IamApiDepartment {
@TableId(value = "id", type = IdType.ASSIGN_UUID)
private String id;
private String name;
private String parentId; // 上级组织架构的ID
private String status; // 标识组织架构的停启用
/** 创建时间 */
private Date createTime;
/** 修改时间 */
private Date updateTime;
}

View File

@ -0,0 +1,38 @@
package com.chinaunicom.mall.ebtp.extend.iam.entity.data;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModel;
import lombok.Data;
import lombok.experimental.Accessors;
import java.util.Date;
/**
* 提供给IAM同步的用户信息实体
*/
@Data
@Accessors(chain = true)
@TableName(value = "iam_api_user", autoResultMap = true)
@ApiModel(value = "IamApiUser对象", description = "人员基本信息表")
public class IamApiUser {
/** 用户ID */
@TableId(value = "id", type = IdType.ASSIGN_UUID)
private String id;
/** 用户名 */
private String name;
/** 邮箱 */
private String email;
/** 手机号 */
private String mobile;
/** 所在组织架构的ID */
private String departmentId;
/** 标识人员的停启用 */
private String status;
/** 创建时间 */
private Date createTime;
/** 修改时间 */
private Date updateTime;
}

View File

@ -0,0 +1,23 @@
package com.chinaunicom.mall.ebtp.extend.iam.entity.data;
import lombok.Data;
@Data
public class IamEmployee {
private String[] authorities;
private String displayName;
private String email;
private long expired;
private String id;
private String instId;
private Object instName;
private String name;
private long passwordSetType;
private Object redirectUrl;
private String refreshToken;
private Object remeberMe;
private String ticket;
private String token;
private String type;
private String username;
}

View File

@ -0,0 +1,47 @@
package com.chinaunicom.mall.ebtp.extend.iam.entity.data;
import io.swagger.annotations.ApiModel;
import lombok.Data;
import lombok.experimental.Accessors;
import java.io.Serializable;
/**
* IAM单点登录用户信息实体
*/
@Data
@Accessors(chain = true)
@ApiModel(value = "IamUser对象", description = "人员基本信息表")
public class IamUser implements Serializable {
private static final long serialVersionUID = 1L;
/** 生日 */
private String birthday;
/** 性别 */
private Integer gender;
/** 展示名称 */
private String displayName;
/** 创建日期 */
private String createdate;
/** 职务 */
private String title;
/** 用户唯一标识 */
private String userId;
/** 在线票据 */
private String online_ticket;
/** 工号 */
private String employeeNumber;
/** 真实姓名 */
private String realname;
/** 机构ID */
private String institution;
/** 随机ID */
private String randomId;
/** 所在省市/州 */
private String state;
/** 部门名称 */
private String department;
/** 用户名(登录名) */
private String user;
/** 用户名(登录名,冗余) */
private String username;
}

View File

@ -1,8 +1,9 @@
package com.chinaunicom.mall.ebtp.extend.iam.service;
import com.chinaunicom.mall.ebtp.extend.iam.client.IamClient;
import com.chinaunicom.mall.ebtp.extend.iam.entity.AuthRequestDTO;
import com.chinaunicom.mall.ebtp.extend.iam.entity.AuthResponseDTO;
import com.chinaunicom.mall.ebtp.extend.iam.entity.*;
import com.chinaunicom.mall.ebtp.extend.iam.entity.data.IamEmployee;
import com.chinaunicom.mall.ebtp.extend.iam.entity.data.IamUser;
import org.springframework.stereotype.Service;
@Service
@ -24,4 +25,21 @@ public class IamAuthService {
}
throw new RuntimeException("Failed to get access token, error code: " + response.getErrorCode());
}
public IamAuthResponseDTO<String> authorize(IamAuthRequestDTO request) {
return iamClient.authorize(request);
}
public IamAuthResponseDTO<IamEmployee> employee(String jwt) {
return iamClient.employee(jwt);
}
public IamUser me(){
String authToken = "your_auth_token_here"; // Replace with actual auth token retrieval logic
return iamClient.me(authToken);
}
public IamToken getToken(String authorization, IamTokenRequestDTO request) {
return iamClient.token(authorization, request);
}
}

View File

@ -0,0 +1,13 @@
package com.chinaunicom.mall.ebtp.extend.iam.service;
import com.chinaunicom.mall.ebtp.common.base.service.IBaseService;
import com.chinaunicom.mall.ebtp.extend.iam.entity.IamApiRequestDTO;
import com.chinaunicom.mall.ebtp.extend.iam.entity.data.IamApiDepartment;
import com.baomidou.mybatisplus.core.metadata.IPage;
import java.util.List;
public interface IamDepartmentService extends IBaseService<IamApiDepartment> {
IPage<IamApiDepartment> getDepartments(IamApiRequestDTO iamDepartmentRequestDTO);
}

View File

@ -0,0 +1,13 @@
package com.chinaunicom.mall.ebtp.extend.iam.service;
import com.chinaunicom.mall.ebtp.common.base.service.IBaseService;
import com.chinaunicom.mall.ebtp.extend.iam.entity.data.IamApiUser;
import com.chinaunicom.mall.ebtp.extend.iam.entity.IamApiRequestDTO;
import com.baomidou.mybatisplus.core.metadata.IPage;
import java.util.List;
public interface IamUserService extends IBaseService<IamApiUser> {
IPage<IamApiUser> getUsers(IamApiRequestDTO iamUserRequestDTO);
}

View File

@ -0,0 +1,39 @@
package com.chinaunicom.mall.ebtp.extend.iam.service.impl;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.chinaunicom.mall.ebtp.extend.iam.dao.IamDepartmentMapper;
import com.chinaunicom.mall.ebtp.extend.iam.entity.IamApiRequestDTO;
import com.chinaunicom.mall.ebtp.extend.iam.entity.data.IamApiDepartment;
import com.chinaunicom.mall.ebtp.extend.iam.service.IamDepartmentService;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.Collections;
import java.util.List;
@Service
public class IamDepartmentServiceImpl extends ServiceImpl<IamDepartmentMapper, IamApiDepartment> implements IamDepartmentService {
@Resource
private IamDepartmentMapper iamDepartmentMapper;
@Override
public IPage<IamApiDepartment> getDepartments(IamApiRequestDTO iamDepartmentRequestDTO) {
int pageIndex = iamDepartmentRequestDTO.getPageIndex() != null ? iamDepartmentRequestDTO.getPageIndex() : 0;
int pageSize = iamDepartmentRequestDTO.getPageSize() != null ? iamDepartmentRequestDTO.getPageSize() : 10;
Page<IamApiDepartment> page = new Page<>(pageIndex + 1, pageSize); // MyBatis-Plus页码从1开始
QueryWrapper<IamApiDepartment> queryWrapper = new QueryWrapper<>();
// 可根据startTime、endTime等条件添加查询条件
if (iamDepartmentRequestDTO.getStartTime() != null) {
queryWrapper.ge("update_time", iamDepartmentRequestDTO.getStartTime());
}
if (iamDepartmentRequestDTO.getEndTime() != null) {
queryWrapper.le("update_time", iamDepartmentRequestDTO.getEndTime());
}
return iamDepartmentMapper.selectPage(page, queryWrapper);
}
}

View File

@ -0,0 +1,37 @@
package com.chinaunicom.mall.ebtp.extend.iam.service.impl;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.chinaunicom.mall.ebtp.extend.iam.dao.IamUserMapper;
import com.chinaunicom.mall.ebtp.extend.iam.entity.data.IamApiUser;
import com.chinaunicom.mall.ebtp.extend.iam.entity.IamApiRequestDTO;
import com.chinaunicom.mall.ebtp.extend.iam.service.IamUserService;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
@Service
public class IamUserServiceImpl extends ServiceImpl<IamUserMapper, IamApiUser> implements IamUserService {
@Resource
private IamUserMapper iamUserMapper;
@Override
public IPage<IamApiUser> getUsers(IamApiRequestDTO iamUserRequestDTO) {
int pageIndex = iamUserRequestDTO.getPageIndex() != null ? iamUserRequestDTO.getPageIndex() : 0;
int pageSize = iamUserRequestDTO.getPageSize() != null ? iamUserRequestDTO.getPageSize() : 10;
Page<IamApiUser> page = new Page<>(pageIndex + 1, pageSize); // MyBatis-Plus页码从1开始接口从0开始
QueryWrapper<IamApiUser> queryWrapper = new QueryWrapper<>();
// 可根据startTime、endTime等条件添加查询条件
if (iamUserRequestDTO.getStartTime() != null) {
queryWrapper.ge("update_time", iamUserRequestDTO.getStartTime());
}
if (iamUserRequestDTO.getEndTime() != null) {
queryWrapper.le("update_time", iamUserRequestDTO.getEndTime());
}
return iamUserMapper.selectPage(page, queryWrapper);
}
}