🎉 1.1.0

pull/83/head v1.1.0
awenes 2024-05-09 22:21:58 +08:00
parent 25f55cf18b
commit 1774e0c056
1184 changed files with 19782 additions and 20930 deletions

View File

@ -66,8 +66,7 @@
## 技术架构
- **后端
**[Spring Boot](https://spring.io/projects/spring-boot/) 、[Spring Security](https://spring.io/projects/spring-security/)
- **后端**[Spring Boot](https://spring.io/projects/spring-boot/) 、[Spring Security](https://spring.io/projects/spring-security/)
- **前端**[React.js](https://react.dev/) 、[Ant Design](https://ant.design)
- **中间件**[MySQL](https://www.mysql.com/) 、[Redis](https://redis.io/)
- **基础设施**[Docker](https://www.docker.com/)

View File

@ -1,5 +1,5 @@
#
# TopIAM Employee - Employee Identity and Access Management
# TOPIAM Employee - Employee Identity and Access Management
# Copyright © 2022-Present Jinan Yuanchuang Network Technology Co., Ltd. (support@topiam.cn)
#
# This program is free software: you can redistribute it and/or modify

View File

@ -1,5 +1,5 @@
#
# TopIAM Employee - Employee Identity and Access Management
# TOPIAM Employee - Employee Identity and Access Management
# Copyright © 2022-Present Jinan Yuanchuang Network Technology Co., Ltd. (support@topiam.cn)
#
# This program is free software: you can redistribute it and/or modify

View File

@ -24,7 +24,7 @@
<parent>
<groupId>cn.topiam</groupId>
<artifactId>eiam-application</artifactId>
<version>1.0.2-SNAPSHOT</version>
<version>1.1.0</version>
<relativePath>../pom.xml</relativePath>
</parent>
<packaging>pom</packaging>

View File

@ -24,7 +24,7 @@
<parent>
<groupId>cn.topiam</groupId>
<artifactId>eiam-application</artifactId>
<version>1.0.2-SNAPSHOT</version>
<version>1.1.0</version>
<relativePath>../pom.xml</relativePath>
</parent>
<packaging>jar</packaging>

View File

@ -30,7 +30,6 @@ import cn.topiam.employee.common.entity.app.AppAccountEntity;
import cn.topiam.employee.common.entity.app.AppEntity;
import cn.topiam.employee.common.entity.app.AppGroupAssociationEntity;
import cn.topiam.employee.common.enums.app.AuthorizationType;
import cn.topiam.employee.common.enums.app.InitLoginType;
import cn.topiam.employee.common.exception.app.AppAccountNotExistException;
import cn.topiam.employee.common.repository.app.AppAccountRepository;
import cn.topiam.employee.common.repository.app.AppGroupAssociationRepository;
@ -42,15 +41,24 @@ import lombok.extern.slf4j.Slf4j;
* AbstractApplicationService
*
* @author TopIAM
* Created by support@topiam.cn on 2022/8/31 22:34
* Created by support@topiam.cn on 2022/8/31 22:34
*/
@Slf4j
public abstract class AbstractApplicationService implements ApplicationService {
protected final ObjectMapper mapper = new ObjectMapper();
/**
*
*
* @param appId {@link String}
* @param userId {@link String}
* @return {@link AppAccount} AppAccount
*/
@Override
public AppAccount getAppAccount(Long appId, Long userId) {
AppAccountEntity entity = appAccountRepository.findByAppIdAndUserId(appId, userId)
public AppAccount getDefaultAppAccount(String appId, String userId) {
AppAccountEntity entity = appAccountRepository
.findByAppIdAndUserIdAndDefaultedIsTrue(appId, userId)
.orElseThrow(AppAccountNotExistException::new);
AppAccount account = new AppAccount();
account.setAppId(entity.getAppId());
@ -65,12 +73,11 @@ public abstract class AbstractApplicationService implements ApplicationService {
* @param name {@link String}
* @param icon {@link String}
* @param remark {@link String}
* @param initLoginType {@link InitLoginType}
* @param authorizationType {@link AuthorizationType}
* @return {@link AppEntity}
*/
@Override
public AppEntity createApp(String name, String icon, String remark, InitLoginType initLoginType,
public AppEntity createApp(String name, String icon, String remark,
AuthorizationType authorizationType) {
AppEntity appEntity = new AppEntity();
appEntity.setName(name);
@ -79,25 +86,25 @@ public abstract class AbstractApplicationService implements ApplicationService {
appEntity.setTemplate(getCode());
appEntity.setType(getType());
appEntity.setEnabled(true);
appEntity.setConfigured(false);
appEntity.setProtocol(getProtocol());
appEntity.setClientId(idGenerator.generateId().toString().replace("-", ""));
appEntity.setClientSecret(idGenerator.generateId().toString().replace("-", ""));
appEntity.setInitLoginType(initLoginType);
appEntity.setAuthorizationType(authorizationType);
appEntity.setRemark(remark);
return appRepository.save(appEntity);
}
@Override
public AppEntity createApp(String name, String icon, String remark, List<String> groupIds,
InitLoginType initLoginType, AuthorizationType authorizationType) {
public AppEntity createApp(String name, String icon, String remark, List<String> groups,
AuthorizationType authorizationType) {
AppEntity appEntity = createApp(name, icon, remark, initLoginType, authorizationType);
AppEntity appEntity = createApp(name, icon, remark, authorizationType);
List<AppGroupAssociationEntity> list = new ArrayList<>();
for (String id : groupIds) {
for (String id : groups) {
AppGroupAssociationEntity appGroupAssociationEntity = new AppGroupAssociationEntity();
appGroupAssociationEntity.setGroupId(Long.valueOf(id));
appGroupAssociationEntity.setAppId(appEntity.getId());
appGroupAssociationEntity.setGroupId(id);
appGroupAssociationEntity.setApp(appEntity);
list.add(appGroupAssociationEntity);
}
appGroupAssociationRepository.saveAll(list);
@ -109,16 +116,16 @@ public abstract class AbstractApplicationService implements ApplicationService {
*/
protected final AppAccountRepository appAccountRepository;
/**
* AppGroupAssociationRepository
*/
protected final AppGroupAssociationRepository appGroupAssociationRepository;
/**
* ApplicationRepository
*/
protected final AppRepository appRepository;
/**
* AppGroupAssociationRepository
*/
protected final AppGroupAssociationRepository appGroupAssociationRepository;
/**
* IdGenerator
*/
@ -128,8 +135,8 @@ public abstract class AbstractApplicationService implements ApplicationService {
AppGroupAssociationRepository appGroupAssociationRepository,
AppRepository appRepository) {
this.appAccountRepository = appAccountRepository;
this.appRepository = appRepository;
this.appGroupAssociationRepository = appGroupAssociationRepository;
this.appRepository = appRepository;
this.idGenerator = new AlternativeJdkIdGenerator();
}
}

View File

@ -32,8 +32,8 @@ import com.fasterxml.jackson.databind.ObjectMapper;
import cn.topiam.employee.common.entity.app.AppCertEntity;
import cn.topiam.employee.common.enums.app.AppCertUsingType;
import cn.topiam.employee.common.exception.app.AppCreateCertException;
import cn.topiam.employee.common.repository.app.*;
import cn.topiam.employee.support.exception.TopIamException;
import cn.topiam.employee.support.util.CertUtils;
import cn.topiam.employee.support.util.RsaUtils;
import static cn.topiam.employee.support.util.CertUtils.encodePem;
@ -44,21 +44,21 @@ import static cn.topiam.employee.support.util.RsaUtils.getKeys;
* AbstractCertificateApplicationService
*
* @author TopIAM
* Created by support@topiam.cn on 2022/8/31 22:34
* Created by support@topiam.cn on 2022/8/31 22:34
*/
public abstract class AbstractCertificateApplicationService extends AbstractApplicationService {
public abstract class AbstractCertApplicationService extends AbstractApplicationService {
private final Logger logger = LoggerFactory
.getLogger(AbstractCertificateApplicationService.class);
.getLogger(AbstractCertApplicationService.class);
protected final ObjectMapper mapper = new ObjectMapper();
/**
*
*
* @param appId {@link Long}
* @param appCode {@link Long}
* @param appId {@link String}
* @param appCode {@link String}
* @param usingType {@link AppCertUsingType}
*/
public void createCertificate(Long appId, String appCode, AppCertUsingType usingType) {
public void createCertificate(String appId, String appCode, AppCertUsingType usingType) {
try {
AppCertEntity config = new AppCertEntity();
config.setAppId(appId);
@ -103,7 +103,7 @@ public abstract class AbstractCertificateApplicationService extends AbstractAppl
appCertRepository.save(config);
} catch (Exception e) {
logger.error("创建应用证书异常", e);
throw new TopIamException(e.getMessage(), e);
throw new AppCreateCertException();
}
}
@ -122,11 +122,11 @@ public abstract class AbstractCertificateApplicationService extends AbstractAppl
*/
protected final IdGenerator idGenerator;
protected AbstractCertificateApplicationService(AppCertRepository appCertRepository,
AppAccountRepository appAccountRepository,
AppAccessPolicyRepository appAccessPolicyRepository,
AppGroupAssociationRepository appGroupAssociationRepository,
AppRepository appRepository) {
protected AbstractCertApplicationService(AppCertRepository appCertRepository,
AppGroupAssociationRepository appGroupAssociationRepository,
AppAccountRepository appAccountRepository,
AppAccessPolicyRepository appAccessPolicyRepository,
AppRepository appRepository) {
super(appAccountRepository, appGroupAssociationRepository, appRepository);
this.appCertRepository = appCertRepository;
this.appAccessPolicyRepository = appAccessPolicyRepository;

View File

@ -27,7 +27,7 @@ import lombok.experimental.SuperBuilder;
/**
*
* @author TopIAM
* Created by support@topiam.cn on 2023/7/13 21:32
* Created by support@topiam.cn on 2023/7/13 21:32
*/
@Data
@SuperBuilder
@ -42,6 +42,12 @@ public class AbstractProtocolConfig implements Serializable {
@NonNull
private String appId;
/**
*
*/
@NonNull
private String appName;
/**
* ID
*/

View File

@ -25,7 +25,7 @@ import lombok.Data;
/**
*
* @author TopIAM
* Created by support@topiam.cn on 2023/7/10 21:07
* Created by support@topiam.cn on 2023/7/10 21:07
*/
@Data
public class AppAccount implements Serializable {
@ -36,12 +36,12 @@ public class AppAccount implements Serializable {
/**
* ID
*/
private Long appId;
private String appId;
/**
* ID
*/
private Long userId;
private String userId;
/**
*
@ -52,4 +52,9 @@ public class AppAccount implements Serializable {
*
*/
private String password;
/**
*
*/
private Boolean defaulted;
}

View File

@ -28,13 +28,12 @@ import cn.topiam.employee.common.entity.app.AppEntity;
import cn.topiam.employee.common.enums.app.AppProtocol;
import cn.topiam.employee.common.enums.app.AppType;
import cn.topiam.employee.common.enums.app.AuthorizationType;
import cn.topiam.employee.common.enums.app.InitLoginType;
/**
*
*
* @author TopIAM
* Created by support@topiam.cn on 2022/8/20 23:20
* Created by support@topiam.cn on 2022/8/20 23:20
*/
public interface ApplicationService {
@ -76,9 +75,11 @@ public interface ApplicationService {
/**
* Schema
*
* @return {@link Map}
* @return {@link Object}
*/
List<Map> getFormSchema();
default Object getFormSchema() {
return null;
}
/**
* base64
@ -90,10 +91,10 @@ public interface ApplicationService {
/**
*
*
* @param name {@link String}
* @param icon {@link String}
* @param remark {@link String}
* @return {@link Long} ID
* @param name {@link String}
* @param icon {@link String}
* @param remark {@link String}
* @return {@link String} ID
*/
@Transactional(rollbackFor = Exception.class)
default String create(String name, String icon, String remark) {
@ -103,14 +104,14 @@ public interface ApplicationService {
/**
*
*
* @param name {@link String}
* @param icon {@link String}
* @param remark {@link String}
* @param groupIds {@link String} id
* @return {@link Long} ID
* @param name {@link String}
* @param icon {@link String}
* @param remark {@link String}
* @param groups {@link String}
* @return {@link String} ID
*/
@Transactional(rollbackFor = Exception.class)
String create(String name, String icon, String remark, List<String> groupIds);
String create(String name, String icon, String remark, List<String> groups);
/**
*
@ -137,13 +138,13 @@ public interface ApplicationService {
Object getConfig(String appId);
/**
*
*
*
* @param appId {@link Long}
* @param userId {@link Long}
* @param appId {@link String}
* @param userId {@link String}
* @return {@link AppAccountEntity}
*/
AppAccount getAppAccount(Long appId, Long userId);
AppAccount getDefaultAppAccount(String appId, String userId);
/**
*
@ -151,11 +152,10 @@ public interface ApplicationService {
* @param name {@link String}
* @param icon {@link String}
* @param remark {@link String}
* @param initLoginType {@link InitLoginType}
* @param authorizationType {@link AuthorizationType}
* @return {@link AppEntity}
*/
AppEntity createApp(String name, String icon, String remark, InitLoginType initLoginType,
AppEntity createApp(String name, String icon, String remark,
AuthorizationType authorizationType);
/**
@ -164,11 +164,10 @@ public interface ApplicationService {
* @param name {@link String}
* @param icon {@link String}
* @param remark {@link String}
* @param groupIds {@link Long} id
* @param initLoginType {@link InitLoginType}
* @param groups {@link String}
* @param authorizationType {@link AuthorizationType}
* @return {@link AppEntity}
*/
AppEntity createApp(String name, String icon, String remark, List<String> groupIds,
InitLoginType initLoginType, AuthorizationType authorizationType);
AppEntity createApp(String name, String icon, String remark, List<String> groups,
AuthorizationType authorizationType);
}

View File

@ -36,7 +36,7 @@ import cn.topiam.employee.common.repository.app.AppRepository;
*
*
* @author TopIAM
* Created by support@topiam.cn on 2022/8/20 21:08
* Created by support@topiam.cn on 2022/8/20 21:08
*/
@Configuration
public class ApplicationServiceLoader implements ApplicationContextAware {
@ -78,9 +78,8 @@ public class ApplicationServiceLoader implements ApplicationContextAware {
*
* @return {@link List}
*/
public Set<ApplicationService> getApplicationServiceList() {
List<ApplicationService> values = loadMap.values().stream().toList();
return new HashSet<>(values);
public List<ApplicationService> getApplicationServiceList() {
return loadMap.values().stream().toList();
}
/**
@ -111,7 +110,7 @@ public class ApplicationServiceLoader implements ApplicationContextAware {
*/
public ApplicationService getApplicationServiceByAppId(String appId) {
AppRepository repository = applicationContext.getBean(AppRepository.class);
Optional<AppEntity> optional = repository.findById(Long.valueOf(appId));
Optional<AppEntity> optional = repository.findById(appId);
if (optional.isEmpty()) {
throw new AppNotExistException();
}

View File

@ -23,15 +23,15 @@ import java.util.Map;
*
*
* @author TopIAM
* Created by support@topiam.cn on 2023/6/30 23:52
* Created by support@topiam.cn on 2023/6/30 23:52
*/
public interface ApplicationContext {
/**
* ID
*
* @return {@link Long}
* @return {@link String}
*/
Long getAppId();
String getAppId();
/**
* ID

View File

@ -21,7 +21,7 @@ package cn.topiam.employee.application.context;
* ApplicationContextHolder
*
* @author TopIAM
* Created by support@topiam.cn on 2022/10/29 22:37
* Created by support@topiam.cn on 2022/10/29 22:37
*/
public final class ApplicationContextHolder {
private static final ThreadLocal<ApplicationContext> HOLDER = new ThreadLocal<>();

View File

@ -23,7 +23,7 @@ import cn.topiam.employee.support.exception.TopIamException;
*
*
* @author TopIAM
* Created by support@topiam.cn on 2022/7/8 22:21
* Created by support@topiam.cn on 2022/7/8 22:21
*/
public class AppCertNotExistException extends TopIamException {
public AppCertNotExistException() {

View File

@ -23,7 +23,7 @@ import cn.topiam.employee.support.exception.TopIamException;
*
*
* @author TopIAM
* Created by support@topiam.cn on 2022/7/8 22:21
* Created by support@topiam.cn on 2022/7/8 22:21
*/
public class AppConfigNotExistException extends TopIamException {
public AppConfigNotExistException() {

View File

@ -1,5 +1,5 @@
/*
* eiam-protocol-core - Employee Identity and Access Management
* eiam-application-core - Employee Identity and Access Management
* Copyright © 2022-Present Jinan Yuanchuang Network Technology Co., Ltd. (support@topiam.cn)
*
* This program is free software: you can redistribute it and/or modify
@ -15,18 +15,18 @@
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package cn.topiam.employee.protocol.code.exception;
package cn.topiam.employee.application.exception;
import cn.topiam.employee.support.exception.TopIamException;
/**
*
*
* @author TopIAM
* Created by support@topiam.cn on 2023/7/8 21:04
* Created by support@topiam.cn on 2022/7/8 22:23
*/
public class TemplateNotExistException extends TopIamException {
public TemplateNotExistException(Throwable throwable) {
super("JWT模版不存在", throwable);
public class AppNotConfigException extends TopIamException {
public AppNotConfigException() {
super("app_not_config", "应用未配置", DEFAULT_STATUS);
}
}

View File

@ -23,7 +23,7 @@ import cn.topiam.employee.support.exception.TopIamException;
*
*
* @author TopIAM
* Created by support@topiam.cn on 2022/7/8 22:23
* Created by support@topiam.cn on 2022/7/8 22:23
*/
public class AppNotEnableException extends TopIamException {
public AppNotEnableException() {

View File

@ -23,7 +23,7 @@ import cn.topiam.employee.support.exception.TopIamException;
*
*
* @author TopIAM
* Created by support@topiam.cn on 2022/7/8 22:23
* Created by support@topiam.cn on 2022/7/8 22:23
*/
public class AppNotExistException extends TopIamException {
public AppNotExistException() {

View File

@ -24,7 +24,7 @@ import static org.springframework.http.HttpStatus.BAD_REQUEST;
*
*
* @author TopIAM
* Created by support@topiam.cn on 2022/7/8 22:49
* Created by support@topiam.cn on 2022/7/8 22:49
*/
public class AppTemplateNotExistException extends TopIamException {

View File

@ -24,7 +24,7 @@
<parent>
<groupId>cn.topiam</groupId>
<artifactId>eiam-application</artifactId>
<version>1.0.2-SNAPSHOT</version>
<version>1.1.0</version>
<relativePath>../pom.xml</relativePath>
</parent>
<packaging>jar</packaging>

View File

@ -33,7 +33,7 @@ import cn.topiam.employee.common.repository.app.AppRepository;
* Form
*
* @author TopIAM
* Created by support@topiam.cn on 2022/8/23 21:58
* Created by support@topiam.cn on 2022/8/23 21:58
*/
public abstract class AbstractFormApplicationService extends AbstractApplicationService
implements FormApplicationService {
@ -41,11 +41,11 @@ public abstract class AbstractFormApplicationService extends AbstractApplication
@Override
public void delete(String appId) {
//删除应用
appRepository.deleteById(Long.valueOf(appId));
appRepository.deleteById(appId);
//删除应用账户
appAccountRepository.deleteAllByAppId(Long.valueOf(appId));
appAccountRepository.deleteAllByAppId(appId);
// 删除应用配置
appFormConfigRepository.deleteByAppId(Long.valueOf(appId));
appFormConfigRepository.deleteByAppId(appId);
}
@Override
@ -61,6 +61,7 @@ public abstract class AbstractFormApplicationService extends AbstractApplication
configBuilder.clientId(configPo.getClientId());
configBuilder.clientSecret(configPo.getClientSecret());
configBuilder.appCode(configPo.getAppCode());
configBuilder.appName(configPo.getAppName());
configBuilder.appTemplate(configPo.getAppTemplate());
configBuilder.loginUrl(configPo.getLoginUrl());
configBuilder.usernameField(configPo.getUsernameField());
@ -74,6 +75,7 @@ public abstract class AbstractFormApplicationService extends AbstractApplication
if (list != null) {
configBuilder.otherField(new ArrayList<>(list));
}
configBuilder.configured(configPo.getConfigured());
return configBuilder.build();
}
@ -83,8 +85,8 @@ public abstract class AbstractFormApplicationService extends AbstractApplication
protected final AppFormConfigRepository appFormConfigRepository;
protected AbstractFormApplicationService(AppRepository appRepository,
AppAccountRepository appAccountRepository,
AppGroupAssociationRepository appGroupAssociationRepository,
AppAccountRepository appAccountRepository,
AppFormConfigRepository appFormConfigRepository) {
super(appAccountRepository, appGroupAssociationRepository, appRepository);
this.appFormConfigRepository = appFormConfigRepository;

View File

@ -24,7 +24,7 @@ import cn.topiam.employee.application.form.model.FormProtocolConfig;
*
*
* @author TopIAM
* Created by support@topiam.cn on 2022/8/20 23:20
* Created by support@topiam.cn on 2022/8/20 23:20
*/
public interface FormApplicationService extends ApplicationService {

View File

@ -32,7 +32,10 @@ import cn.topiam.employee.audit.context.AuditContext;
import cn.topiam.employee.common.entity.app.AppEntity;
import cn.topiam.employee.common.entity.app.AppFormConfigEntity;
import cn.topiam.employee.common.entity.app.po.AppFormConfigPO;
import cn.topiam.employee.common.enums.app.*;
import cn.topiam.employee.common.enums.app.AppProtocol;
import cn.topiam.employee.common.enums.app.AppType;
import cn.topiam.employee.common.enums.app.AuthorizationType;
import cn.topiam.employee.common.enums.app.FormSubmitType;
import cn.topiam.employee.common.repository.app.AppAccountRepository;
import cn.topiam.employee.common.repository.app.AppFormConfigRepository;
import cn.topiam.employee.common.repository.app.AppGroupAssociationRepository;
@ -49,7 +52,7 @@ import static com.fasterxml.jackson.databind.DeserializationFeature.FAIL_ON_UNKN
* Form
*
* @author TopIAM
* Created by support@topiam.cn on 2022/8/20 23:20
* Created by support@topiam.cn on 2022/8/20 23:20
*/
@Slf4j
@Component
@ -80,18 +83,18 @@ public class FormStandardApplicationServiceImpl extends AbstractFormApplicationS
}
//@formatter:on
//1、修改基本信息
Optional<AppEntity> optional = appRepository.findById(Long.valueOf(appId));
Optional<AppEntity> optional = appRepository.findById(appId);
if (optional.isEmpty()) {
AuditContext.setContent("保存配置失败,应用 [" + appId + "] 不存在!");
log.error(AuditContext.getContent());
throw new AppNotExistException();
}
AppEntity appEntity = optional.get();
appEntity.setAuthorizationType(model.getAuthorizationType());
appEntity.setConfigured(true);
appEntity.setInitLoginUrl(model.getInitLoginUrl());
appRepository.save(appEntity);
//2、修改 表单代填 配置
Optional<AppFormConfigEntity> form = appFormConfigRepository
.findByAppId(Long.valueOf(appId));
Optional<AppFormConfigEntity> form = appFormConfigRepository.findByAppId(appId);
if (form.isEmpty()) {
AuditContext.setContent("保存配置失败,应用 [" + appId + "] 不存在!");
log.error(AuditContext.getContent());
@ -105,7 +108,6 @@ public class FormStandardApplicationServiceImpl extends AbstractFormApplicationS
formConfig.setRemark(entity.getRemark());
formConfig.setCreateBy(entity.getCreateBy());
formConfig.setCreateTime(entity.getCreateTime());
formConfig.setDeleted(entity.getDeleted());
appFormConfigRepository.save(formConfig);
}
@ -117,7 +119,7 @@ public class FormStandardApplicationServiceImpl extends AbstractFormApplicationS
*/
@Override
public Object getConfig(String appId) {
AppFormConfigPO po = appFormConfigRepository.getByAppId(Long.valueOf(appId));
AppFormConfigPO po = appFormConfigRepository.getByAppId(appId);
return appFormConfigConverter.entityConverterToFormConfigResult(po);
}
@ -148,7 +150,7 @@ public class FormStandardApplicationServiceImpl extends AbstractFormApplicationS
*/
@Override
public String getDescription() {
return "表单代填可以模拟用户在登录页输入用户名和密码,再通过表单提交的一种登录方式。应用的账号密码在 TopIAM 中使用 AES256 加密算法本地加密存储。很多旧系统、不支持标准认证协议的系统或不支持改造的系统可以使用表单代填实现统一身份管理。表单中有图片验证码、CSRF token、动态参数的场景不适用。";
return "表单代填可以模拟用户在登录页输入用户名和密码,再通过表单提交的一种登录方式。应用的账号密码在 TOPIAM 中使用 AES256 加密算法本地加密存储。很多旧系统、不支持标准认证协议的系统或不支持改造的系统可以使用表单代填实现统一身份管理。表单中有图片验证码、CSRF token、动态参数的场景不适用。";
}
/**
@ -171,16 +173,6 @@ public class FormStandardApplicationServiceImpl extends AbstractFormApplicationS
return AppProtocol.FORM;
}
/**
* Schema
*
* @return {@link Map}
*/
@Override
public List<Map> getFormSchema() {
return null;
}
/**
* base64
*
@ -194,15 +186,15 @@ public class FormStandardApplicationServiceImpl extends AbstractFormApplicationS
/**
*
*
* @param name {@link String}
* @param icon {@link String}
* @param remark {@link String}
* @param groupIds {@link Long} id
* @param name {@link String}
* @param icon {@link String}
* @param remark {@link String}
* @param groups {@link String}
*/
@Override
public String create(String name, String icon, String remark, List<String> groupIds) {
public String create(String name, String icon, String remark, List<String> groups) {
//1、创建应用
AppEntity appEntity = createApp(name, icon, remark, groupIds, InitLoginType.PORTAL_OR_APP,
AppEntity appEntity = createApp(name, icon, remark, groups,
AuthorizationType.AUTHORIZATION);
AppFormConfigEntity appFormConfig = new AppFormConfigEntity();
appFormConfig.setAppId(appEntity.getId());
@ -215,11 +207,11 @@ public class FormStandardApplicationServiceImpl extends AbstractFormApplicationS
private final AppFormConfigConverter appFormConfigConverter;
protected FormStandardApplicationServiceImpl(AppAccountRepository appAccountRepository,
AppGroupAssociationRepository appGroupAssociationRepository,
AppFormConfigRepository appFormConfigRepository,
AppRepository appRepository,
AppGroupAssociationRepository appGroupAssociationRepository,
AppFormConfigConverter appFormConfigConverter) {
super(appRepository, appAccountRepository, appGroupAssociationRepository,
super(appRepository, appGroupAssociationRepository, appAccountRepository,
appFormConfigRepository);
this.appFormConfigConverter = appFormConfigConverter;
}

View File

@ -31,8 +31,8 @@ import cn.topiam.employee.application.form.pojo.AppFormProtocolEndpoint;
import cn.topiam.employee.application.form.pojo.AppFormSaveConfigParam;
import cn.topiam.employee.common.entity.app.AppFormConfigEntity;
import cn.topiam.employee.common.entity.app.po.AppFormConfigPO;
import cn.topiam.employee.core.help.ServerHelp;
import static cn.topiam.employee.common.constant.AppConstants.APP_CODE;
import cn.topiam.employee.core.context.ContextService;
import static cn.topiam.employee.common.constant.ProtocolConstants.APP_CODE;
import static cn.topiam.employee.common.constant.ProtocolConstants.FormEndpointConstants.FORM_SSO_PATH;
/**
@ -50,7 +50,7 @@ public interface AppFormConfigConverter {
* @param config {@link AppFormSaveConfigParam}
* @return {@link AppFormConfigEntity}
*/
@Mapping(target = "deleted", ignore = true)
@Mapping(target = "updateTime", ignore = true)
@Mapping(target = "updateBy", ignore = true)
@Mapping(target = "remark", ignore = true)
@ -72,11 +72,9 @@ public interface AppFormConfigConverter {
}
AppFormConfigGetResult result = new AppFormConfigGetResult();
if (po.getAppId() != null) {
result.setAppId(String.valueOf(po.getAppId()));
result.setAppId(po.getAppId());
}
result.setInitLoginType(po.getInitLoginType());
result.setInitLoginUrl(po.getInitLoginUrl());
result.setAuthorizationType(po.getAuthorizationType());
result.setLoginUrl(po.getLoginUrl());
result.setUsernameField(po.getUsernameField());
result.setPasswordField(po.getPasswordField());
@ -106,7 +104,7 @@ public interface AppFormConfigConverter {
variables.put(APP_CODE,appCode);
StringSubstitutor sub = new StringSubstitutor(variables, "{", "}");
//IDP SSO 端点
domain.setIdpSsoEndpoint(sub.replace(ServerHelp.getPortalPublicBaseUrl()+FORM_SSO_PATH));
domain.setIdpSsoEndpoint(sub.replace(ContextService.getPortalPublicBaseUrl()+FORM_SSO_PATH));
return domain;
//@formatter:on
}

View File

@ -20,6 +20,8 @@ package cn.topiam.employee.application.form.model;
import java.io.Serial;
import java.util.List;
import org.springframework.util.CollectionUtils;
import cn.topiam.employee.application.AbstractProtocolConfig;
import cn.topiam.employee.common.entity.app.AppFormConfigEntity;
import cn.topiam.employee.common.enums.app.FormEncryptType;
@ -28,18 +30,16 @@ import cn.topiam.employee.common.enums.app.FormSubmitType;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.SuperBuilder;
import lombok.extern.jackson.Jacksonized;
/**
* Form
*
* @author TopIAM
* Created by support@topiam.cn on 2022/8/28 21:43
* Created by support@topiam.cn on 2022/8/28 21:43
*/
@EqualsAndHashCode(callSuper = true)
@Data
@SuperBuilder
@Jacksonized
public class FormProtocolConfig extends AbstractProtocolConfig {
@Serial
@ -89,4 +89,13 @@ public class FormProtocolConfig extends AbstractProtocolConfig {
*
*/
private List<AppFormConfigEntity.OtherField> otherField;
/**
*
*/
private Boolean configured;
public List<AppFormConfigEntity.OtherField> getOtherField() {
return CollectionUtils.isEmpty(otherField) ? List.of() : otherField;
}
}

View File

@ -21,10 +21,8 @@ import java.io.Serializable;
import java.util.List;
import cn.topiam.employee.common.entity.app.AppFormConfigEntity;
import cn.topiam.employee.common.enums.app.AuthorizationType;
import cn.topiam.employee.common.enums.app.FormEncryptType;
import cn.topiam.employee.common.enums.app.FormSubmitType;
import cn.topiam.employee.common.enums.app.InitLoginType;
import lombok.Data;
@ -34,7 +32,7 @@ import io.swagger.v3.oas.annotations.media.Schema;
* Form
*
* @author TopIAM
* Created by support@topiam.cn on 2022/5/31 22:46
* Created by support@topiam.cn on 2022/5/31 22:46
*/
@Data
@Schema(description = "Form 配置返回响应")
@ -45,24 +43,12 @@ public class AppFormConfigGetResult implements Serializable {
@Schema(description = "应用id")
private String appId;
/**
* SSO
*/
@Schema(description = "SSO 发起方")
private InitLoginType initLoginType;
/**
* SSO
*/
@Schema(description = "SSO 登录链接")
private String initLoginUrl;
/**
*
*/
@Schema(description = "SSO 授权范围")
private AuthorizationType authorizationType;
/**
* URL
*/

View File

@ -22,14 +22,13 @@ import java.io.Serializable;
import lombok.Data;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.Schema;
/**
*
*
* @author TopIAM
* Created by support@topiam.cn on 2022/6/4 23:37
* Created by support@topiam.cn on 2022/6/4 23:37
*/
@Data
@Schema(description = "协议端点")
@ -41,6 +40,6 @@ public class AppFormProtocolEndpoint implements Serializable {
/**
* IDP SSO
*/
@Parameter(description = "IDP SSO 端点")
@Schema(description = "IDP SSO 端点")
private String idpSsoEndpoint;
}

View File

@ -22,7 +22,6 @@ import java.io.Serializable;
import java.util.List;
import cn.topiam.employee.common.entity.app.AppFormConfigEntity;
import cn.topiam.employee.common.enums.app.AuthorizationType;
import cn.topiam.employee.common.enums.app.FormEncryptType;
import cn.topiam.employee.common.enums.app.FormSubmitType;
@ -34,7 +33,7 @@ import jakarta.validation.constraints.NotNull;
/**
* @author TopIAM
* Created by support@topiam.cn on 2022/12/13 22:45
* Created by support@topiam.cn on 2022/12/13 22:45
*/
@Data
@Schema(description = "保存 表单代填 应用配置参数")
@ -44,11 +43,10 @@ public class AppFormSaveConfigParam implements Serializable {
private static final long serialVersionUID = 7257798528680745281L;
/**
* SSO
* URL
*/
@NotNull(message = "SSO范围不能为空")
@Schema(description = "SSO范围")
private AuthorizationType authorizationType;
@Schema(description = "登录发起登录URL")
private String initLoginUrl;
/**
* URL

View File

@ -24,7 +24,7 @@
<parent>
<groupId>cn.topiam</groupId>
<artifactId>eiam-application</artifactId>
<version>1.0.2-SNAPSHOT</version>
<version>1.1.0</version>
<relativePath>../pom.xml</relativePath>
</parent>
<packaging>jar</packaging>

View File

@ -20,7 +20,7 @@ package cn.topiam.employee.application.jwt;
import java.util.Objects;
import java.util.Optional;
import cn.topiam.employee.application.AbstractCertificateApplicationService;
import cn.topiam.employee.application.AbstractCertApplicationService;
import cn.topiam.employee.application.exception.AppCertNotExistException;
import cn.topiam.employee.application.exception.AppNotExistException;
import cn.topiam.employee.application.jwt.model.JwtProtocolConfig;
@ -33,11 +33,10 @@ import cn.topiam.employee.common.repository.app.*;
* JWT
*
* @author TopIAM
* Created by support@topiam.cn on 2022/8/23 21:58
* Created by support@topiam.cn on 2022/8/23 21:58
*/
public abstract class AbstractJwtCertificateApplicationService extends
AbstractCertificateApplicationService
implements JwtApplicationService {
public abstract class AbstractJwtApplicationService extends AbstractCertApplicationService
implements JwtApplicationService {
/**
* AppCertRepository
@ -53,13 +52,13 @@ public abstract class AbstractJwtCertificateApplicationService extends
@Override
public void delete(String appId) {
//删除应用
appRepository.deleteById(Long.valueOf(appId));
appRepository.deleteById(appId);
//删除应用账户
appAccountRepository.deleteAllByAppId(Long.valueOf(appId));
appAccountRepository.deleteAllByAppId(appId);
// 删除应用配置
appJwtConfigRepository.deleteByAppId(Long.valueOf(appId));
appJwtConfigRepository.deleteByAppId(appId);
// 删除证书
appCertRepository.deleteByAppId(Long.valueOf(appId));
appCertRepository.deleteByAppId(appId);
}
@Override
@ -68,15 +67,11 @@ public abstract class AbstractJwtCertificateApplicationService extends
if (Objects.isNull(configPo)) {
throw new AppNotExistException();
}
Optional<AppCertEntity> appCertEntity = appCertRepository
Optional<AppCertEntity> entity = appCertRepository
.findByAppIdAndUsingType(configPo.getAppId(), AppCertUsingType.JWT_ENCRYPT);
if (appCertEntity.isEmpty()) {
if (entity.isEmpty()) {
throw new AppCertNotExistException();
}
appCertEntity.ifPresent(appCert -> {
configPo.setJwtPrivateKey(appCert.getPrivateKey());
configPo.setJwtPublicKey(appCert.getPublicKey());
});
JwtProtocolConfig.JwtProtocolConfigBuilder<?, ?> jwtProtocolConfig = JwtProtocolConfig
.builder();
@ -84,28 +79,33 @@ public abstract class AbstractJwtCertificateApplicationService extends
//@formatter:off
jwtProtocolConfig.appId(String.valueOf(configPo.getAppId()))
.clientId(configPo.getClientId())
.appName(configPo.getAppName())
.clientSecret(configPo.getClientSecret())
.appCode(configPo.getAppCode())
.appTemplate(configPo.getAppTemplate())
.redirectUrl(configPo.getRedirectUrl())
.targetLinkUrl(configPo.getTargetLinkUrl())
.bindingType(configPo.getBindingType())
.idTokenTimeToLive(configPo.getIdTokenTimeToLive())
.jwtPublicKey(configPo.getJwtPublicKey())
.jwtPrivateKey(configPo.getJwtPrivateKey())
.idTokenSubjectType(configPo.getIdTokenSubjectType());
.idTokenTimeToLive(Objects.toString(configPo.getIdTokenTimeToLive().toSeconds(),""))
.idTokenSubjectType(configPo.getIdTokenSubjectType())
.configured(configPo.getConfigured());
entity.ifPresent(appCert -> {
jwtProtocolConfig.jwtPrivateKey(appCert.getPrivateKey());
jwtProtocolConfig.jwtPublicKey(appCert.getPublicKey());
});
//@formatter:on
return jwtProtocolConfig.build();
}
protected AbstractJwtCertificateApplicationService(AppJwtConfigRepository appJwtConfigRepository,
AppCertRepository appCertRepository,
AppRepository appRepository,
AppAccountRepository appAccountRepository,
AppGroupAssociationRepository appGroupAssociationRepository,
AppAccessPolicyRepository appAccessPolicyRepository) {
super(appCertRepository, appAccountRepository, appAccessPolicyRepository,
appGroupAssociationRepository, appRepository);
protected AbstractJwtApplicationService(AppJwtConfigRepository appJwtConfigRepository,
AppGroupAssociationRepository appGroupAssociationRepository,
AppCertRepository appCertRepository,
AppRepository appRepository,
AppAccountRepository appAccountRepository,
AppAccessPolicyRepository appAccessPolicyRepository) {
super(appCertRepository, appGroupAssociationRepository, appAccountRepository,
appAccessPolicyRepository, appRepository);
this.appCertRepository = appCertRepository;
this.appRepository = appRepository;
this.appJwtConfigRepository = appJwtConfigRepository;

View File

@ -24,7 +24,7 @@ import cn.topiam.employee.application.jwt.model.JwtProtocolConfig;
*
*
* @author TopIAM
* Created by support@topiam.cn on 2022/8/20 23:20
* Created by support@topiam.cn on 2022/8/20 23:20
*/
public interface JwtApplicationService extends ApplicationService {

View File

@ -17,6 +17,7 @@
*/
package cn.topiam.employee.application.jwt;
import java.time.Duration;
import java.util.List;
import java.util.Map;
import java.util.Optional;
@ -29,7 +30,6 @@ import cn.topiam.employee.application.exception.AppNotExistException;
import cn.topiam.employee.application.jwt.converter.AppJwtConfigConverter;
import cn.topiam.employee.application.jwt.pojo.AppJwtSaveConfigParam;
import cn.topiam.employee.audit.context.AuditContext;
import cn.topiam.employee.common.entity.app.AppCertEntity;
import cn.topiam.employee.common.entity.app.AppEntity;
import cn.topiam.employee.common.entity.app.AppJwtConfigEntity;
import cn.topiam.employee.common.entity.app.po.AppJwtConfigPO;
@ -44,20 +44,18 @@ import lombok.extern.slf4j.Slf4j;
import jakarta.validation.ConstraintViolationException;
import static com.fasterxml.jackson.databind.DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES;
import static cn.topiam.employee.common.enums.app.InitLoginType.PORTAL_OR_APP;
import static cn.topiam.employee.support.repository.domain.BaseEntity.LAST_MODIFIED_BY;
import static cn.topiam.employee.support.repository.domain.BaseEntity.LAST_MODIFIED_TIME;
import static cn.topiam.employee.support.repository.base.BaseEntity.LAST_MODIFIED_BY;
import static cn.topiam.employee.support.repository.base.BaseEntity.LAST_MODIFIED_TIME;
/**
* JWT
*
* @author TopIAM
* Created by support@topiam.cn on 2022/8/20 23:20
* Created by support@topiam.cn on 2022/8/20 23:20
*/
@Component
@Slf4j
public class JwtStandardCertificateApplicationServiceImpl extends
AbstractJwtCertificateApplicationService {
public class JwtStandardApplicationServiceImpl extends AbstractJwtApplicationService {
/**
*
@ -84,18 +82,18 @@ public class JwtStandardCertificateApplicationServiceImpl extends
}
//@formatter:on
//1、修改基本信息
Optional<AppEntity> optional = appRepository.findById(Long.valueOf(appId));
Optional<AppEntity> optional = appRepository.findById(appId);
if (optional.isEmpty()) {
AuditContext.setContent("保存配置失败,应用 [" + appId + "] 不存在!");
log.error(AuditContext.getContent());
throw new AppNotExistException();
}
AppEntity appEntity = optional.get();
appEntity.setAuthorizationType(model.getAuthorizationType());
appEntity.setInitLoginType(PORTAL_OR_APP);
appEntity.setInitLoginUrl(model.getInitLoginUrl());
appEntity.setConfigured(true);
appRepository.save(appEntity);
//2、修改 JWT 配置
Optional<AppJwtConfigEntity> jwt = appJwtConfigRepository.findByAppId(Long.valueOf(appId));
Optional<AppJwtConfigEntity> jwt = appJwtConfigRepository.findByAppId(appId);
if (jwt.isEmpty()) {
AuditContext.setContent("保存配置失败,应用 [" + appId + "] 不存在!");
log.error(AuditContext.getContent());
@ -115,13 +113,7 @@ public class JwtStandardCertificateApplicationServiceImpl extends
*/
@Override
public Object getConfig(String appId) {
AppJwtConfigPO configPo = appJwtConfigRepository.getByAppId(Long.valueOf(appId));
Optional<AppCertEntity> appCertEntity = appCertRepository
.findByAppIdAndUsingType(configPo.getAppId(), AppCertUsingType.JWT_ENCRYPT);
appCertEntity.ifPresent(appCert -> {
configPo.setJwtPrivateKey(appCert.getPrivateKey());
configPo.setJwtPublicKey(appCert.getPublicKey());
});
AppJwtConfigPO configPo = appJwtConfigRepository.getByAppId(appId);
return appJwtConfigConverter.entityConverterToFormConfigResult(configPo);
}
@ -175,16 +167,6 @@ public class JwtStandardCertificateApplicationServiceImpl extends
return AppProtocol.JWT;
}
/**
* Schema
*
* @return {@link Map}
*/
@Override
public List<Map> getFormSchema() {
return null;
}
/**
* base64
*
@ -198,15 +180,15 @@ public class JwtStandardCertificateApplicationServiceImpl extends
/**
*
*
* @param name {@link String}
* @param icon {@link String}
* @param remark {@link String}
* @param groupIds {@link Long} id
* @param name {@link String}
* @param icon {@link String}
* @param remark {@link String}
* @param groups {@link String}
*/
@Override
public String create(String name, String icon, String remark, List<String> groupIds) {
public String create(String name, String icon, String remark, List<String> groups) {
//1、创建应用
AppEntity appEntity = createApp(name, icon, remark, groupIds, InitLoginType.PORTAL_OR_APP,
AppEntity appEntity = createApp(name, icon, remark, groups,
AuthorizationType.AUTHORIZATION);
//jwt配置
AppJwtConfigEntity jwtConfigEntity = new AppJwtConfigEntity();
@ -214,8 +196,8 @@ public class JwtStandardCertificateApplicationServiceImpl extends
jwtConfigEntity.setBindingType(JwtBindingType.POST);
//id_token sub 类型
jwtConfigEntity.setIdTokenSubjectType(JwtIdTokenSubjectType.USER_ID);
//token有效期
jwtConfigEntity.setIdTokenTimeToLive(600);
//token有效期(秒)
jwtConfigEntity.setIdTokenTimeToLive(Duration.ofSeconds(600));
appJwtConfigRepository.save(jwtConfigEntity);
// 创建RSA证书
createCertificate(appEntity.getId(), appEntity.getCode(), AppCertUsingType.JWT_ENCRYPT);
@ -224,15 +206,15 @@ public class JwtStandardCertificateApplicationServiceImpl extends
private final AppJwtConfigConverter appJwtConfigConverter;
public JwtStandardCertificateApplicationServiceImpl(AppJwtConfigRepository appJwtConfigRepository,
AppJwtConfigConverter appJwtConfigConverter,
AppCertRepository appCertRepository,
AppRepository appRepository,
AppAccountRepository appAccountRepository,
AppGroupAssociationRepository appGroupAssociationRepository,
AppAccessPolicyRepository appAccessPolicyRepository) {
super(appJwtConfigRepository, appCertRepository, appRepository, appAccountRepository,
appGroupAssociationRepository, appAccessPolicyRepository);
public JwtStandardApplicationServiceImpl(AppJwtConfigRepository appJwtConfigRepository,
AppGroupAssociationRepository appGroupAssociationRepository,
AppJwtConfigConverter appJwtConfigConverter,
AppCertRepository appCertRepository,
AppRepository appRepository,
AppAccountRepository appAccountRepository,
AppAccessPolicyRepository appAccessPolicyRepository) {
super(appJwtConfigRepository, appGroupAssociationRepository, appCertRepository,
appRepository, appAccountRepository, appAccessPolicyRepository);
this.appJwtConfigConverter = appJwtConfigConverter;
}
}

View File

@ -17,21 +17,21 @@
*/
package cn.topiam.employee.application.jwt.converter;
import java.time.Duration;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import org.apache.commons.text.StringSubstitutor;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import cn.topiam.employee.application.jwt.pojo.AppJwtConfigGetResult;
import cn.topiam.employee.application.jwt.pojo.AppJwtProtocolEndpoint;
import cn.topiam.employee.application.jwt.pojo.AppJwtSaveConfigParam;
import cn.topiam.employee.common.entity.app.AppJwtConfigEntity;
import cn.topiam.employee.common.entity.app.po.AppJwtConfigPO;
import cn.topiam.employee.core.help.ServerHelp;
import static cn.topiam.employee.common.constant.AppConstants.APP_CODE;
import static cn.topiam.employee.common.constant.ProtocolConstants.JwtEndpointConstants.JWT_SLO_PATH;
import cn.topiam.employee.core.context.ContextService;
import static cn.topiam.employee.common.constant.ProtocolConstants.APP_CODE;
import static cn.topiam.employee.common.constant.ProtocolConstants.JwtEndpointConstants.JWT_SSO_PATH;
/**
@ -49,15 +49,19 @@ public interface AppJwtConfigConverter {
* @param config {@link AppJwtSaveConfigParam}
* @return {@link AppJwtConfigEntity}
*/
@Mapping(target = "deleted", ignore = true)
@Mapping(target = "updateTime", ignore = true)
@Mapping(target = "updateBy", ignore = true)
@Mapping(target = "remark", ignore = true)
@Mapping(target = "id", ignore = true)
@Mapping(target = "createTime", ignore = true)
@Mapping(target = "createBy", ignore = true)
@Mapping(target = "appId", ignore = true)
AppJwtConfigEntity appJwtSaveConfigParamToEntity(AppJwtSaveConfigParam config);
default AppJwtConfigEntity appJwtSaveConfigParamToEntity(AppJwtSaveConfigParam config) {
if (config == null) {
return null;
}
AppJwtConfigEntity entity = new AppJwtConfigEntity();
entity.setRedirectUrl(config.getRedirectUrl());
entity.setTargetLinkUrl(config.getTargetLinkUrl());
entity.setBindingType(config.getBindingType());
entity.setIdTokenSubjectType(config.getIdTokenSubjectType());
entity.setIdTokenTimeToLive(Duration.ofSeconds(config.getIdTokenTimeToLive()));
return entity;
}
/**
* po result
@ -71,16 +75,14 @@ public interface AppJwtConfigConverter {
}
AppJwtConfigGetResult result = new AppJwtConfigGetResult();
if (po.getAppId() != null) {
result.setAppId(String.valueOf(po.getAppId()));
result.setAppId(po.getAppId());
}
result.setInitLoginType(po.getInitLoginType());
result.setInitLoginUrl(po.getInitLoginUrl());
result.setAuthorizationType(po.getAuthorizationType());
result.setRedirectUrl(po.getRedirectUrl());
result.setTargetLinkUrl(po.getTargetLinkUrl());
result.setBindingType(po.getBindingType());
result.setIdTokenSubjectType(po.getIdTokenSubjectType());
result.setIdTokenTimeToLive(po.getIdTokenTimeToLive());
result.setIdTokenTimeToLive(Objects.toString(po.getIdTokenTimeToLive().toSeconds(), ""));
result.setProtocolEndpoint(getProtocolEndpointDomain(po.getAppCode()));
return result;
}
@ -98,9 +100,7 @@ public interface AppJwtConfigConverter {
variables.put(APP_CODE,appCode);
StringSubstitutor sub = new StringSubstitutor(variables, "{", "}");
//IDP SSO 端点
domain.setIdpSsoEndpoint(sub.replace(ServerHelp.getPortalPublicBaseUrl()+JWT_SSO_PATH));
//IDP SLO 端点
domain.setIdpSloEndpoint(sub.replace(ServerHelp.getPortalPublicBaseUrl()+JWT_SLO_PATH));
domain.setIdpSsoEndpoint(sub.replace(ContextService.getPortalPublicBaseUrl()+JWT_SSO_PATH));
return domain;
//@formatter:on
}

View File

@ -1,56 +0,0 @@
/*
* eiam-application-jwt - Employee Identity and Access Management
* Copyright © 2022-Present Jinan Yuanchuang Network Technology Co., Ltd. (support@topiam.cn)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package cn.topiam.employee.application.jwt.model;
import java.io.Serializable;
import cn.topiam.employee.common.enums.app.AuthorizationType;
import cn.topiam.employee.common.enums.app.InitLoginType;
import lombok.Data;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.Schema;
/**
* JWT
*
* @author TopIAM
* Created by support@topiam.cn on 2022/5/31 22:46
*/
@Data
@Schema(description = "JWT 配置返回响应")
public class AppJwtGetResult implements Serializable {
/**
* SSO
*/
@Parameter(description = "SSO 发起方")
private InitLoginType initLoginType;
/**
* SSO
*/
@Parameter(description = "SSO 登录链接")
private String initLoginUrl;
/**
*
*/
@Parameter(description = "SSO 授权范围")
private AuthorizationType authorizationType;
}

View File

@ -26,18 +26,16 @@ import cn.topiam.employee.common.enums.app.JwtIdTokenSubjectType;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.SuperBuilder;
import lombok.extern.jackson.Jacksonized;
/**
* Form
*
* @author TopIAM
* Created by support@topiam.cn on 2023/02/12 21:43
* Created by support@topiam.cn on 2023/02/12 21:43
*/
@EqualsAndHashCode(callSuper = true)
@Data
@SuperBuilder
@Jacksonized
public class JwtProtocolConfig extends AbstractProtocolConfig {
@Serial
@ -65,7 +63,7 @@ public class JwtProtocolConfig extends AbstractProtocolConfig {
/**
* Token
*/
private Integer idTokenTimeToLive;
private String idTokenTimeToLive;
/**
* JWT
@ -81,4 +79,14 @@ public class JwtProtocolConfig extends AbstractProtocolConfig {
* id_token
*/
private JwtIdTokenSubjectType idTokenSubjectType;
/**
*
*/
private String postLogoutRedirectUri;
/**
*
*/
private Boolean configured;
}

View File

@ -19,21 +19,18 @@ package cn.topiam.employee.application.jwt.pojo;
import java.io.Serializable;
import cn.topiam.employee.common.enums.app.AuthorizationType;
import cn.topiam.employee.common.enums.app.InitLoginType;
import cn.topiam.employee.common.enums.app.JwtBindingType;
import cn.topiam.employee.common.enums.app.JwtIdTokenSubjectType;
import lombok.Data;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.Schema;
/**
* JWT
*
* @author TopIAM
* Created by support@topiam.cn on 2023/02/12 22:46
* Created by support@topiam.cn on 2023/02/12 22:46
*/
@Data
@Schema(description = "JWT 配置返回响应")
@ -44,24 +41,12 @@ public class AppJwtConfigGetResult implements Serializable {
@Schema(description = "应用id")
private String appId;
/**
* SSO
*/
@Parameter(description = "SSO 发起方")
private InitLoginType initLoginType;
/**
* SSO
*/
@Parameter(description = "SSO 登录链接")
@Schema(description = "SSO 登录链接")
private String initLoginUrl;
/**
*
*/
@Parameter(description = "SSO 授权范围")
private AuthorizationType authorizationType;
/**
* PCJWT SSO[GET]id_tokenid_token
* id_tokenPublic KeySPSPservice
@ -88,7 +73,7 @@ public class AppJwtConfigGetResult implements Serializable {
* ID_token
*/
@Schema(description = "Token 过期时间(秒)")
private Integer idTokenTimeToLive;
private String idTokenTimeToLive;
/**
*

View File

@ -22,14 +22,13 @@ import java.io.Serializable;
import lombok.Data;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.Schema;
/**
*
*
* @author TopIAM
* Created by support@topiam.cn on 2023/02/12 23:37
* Created by support@topiam.cn on 2023/02/12 23:37
*/
@Data
@Schema(description = "协议端点")
@ -41,12 +40,6 @@ public class AppJwtProtocolEndpoint implements Serializable {
/**
* IDP SSO
*/
@Parameter(description = "IDP SSO 端点")
@Schema(description = "IDP SSO 端点")
private String idpSsoEndpoint;
/**
* IDP SLO
*/
@Parameter(description = "IDP SLO 端点")
private String idpSloEndpoint;
}

View File

@ -20,7 +20,6 @@ package cn.topiam.employee.application.jwt.pojo;
import java.io.Serial;
import java.io.Serializable;
import cn.topiam.employee.common.enums.app.AuthorizationType;
import cn.topiam.employee.common.enums.app.JwtBindingType;
import cn.topiam.employee.common.enums.app.JwtIdTokenSubjectType;
@ -34,7 +33,7 @@ import jakarta.validation.constraints.NotNull;
/**
* @author TopIAM
* Created by support@topiam.cn on 2023/02/12 22:45
* Created by support@topiam.cn on 2023/02/12 22:45
*/
@Data
@Schema(description = "保存 JWT 应用配置参数")
@ -44,11 +43,10 @@ public class AppJwtSaveConfigParam implements Serializable {
private static final long serialVersionUID = 7257798528680745281L;
/**
* SSO
* URL
*/
@NotNull(message = "SSO范围不能为空")
@Schema(description = "SSO范围")
private AuthorizationType authorizationType;
@Schema(description = "登录发起登录URL")
private String initLoginUrl;
/**
* PCJWT SSO[GET]id_tokenid_token

View File

@ -24,7 +24,7 @@
<parent>
<groupId>cn.topiam</groupId>
<artifactId>eiam-application</artifactId>
<version>1.0.2-SNAPSHOT</version>
<version>1.1.0</version>
<relativePath>../pom.xml</relativePath>
</parent>
<packaging>jar</packaging>

View File

@ -25,7 +25,7 @@ import java.util.Optional;
import com.nimbusds.jose.jwk.RSAKey;
import cn.topiam.employee.application.AbstractCertificateApplicationService;
import cn.topiam.employee.application.AbstractCertApplicationService;
import cn.topiam.employee.application.exception.AppCertNotExistException;
import cn.topiam.employee.application.exception.AppNotExistException;
import cn.topiam.employee.application.oidc.model.OidcProtocolConfig;
@ -40,24 +40,23 @@ import static cn.topiam.employee.support.util.CertUtils.readPublicKey;
* OIDC
*
* @author TopIAM
* Created by support@topiam.cn on 2022/8/23 21:58
* Created by support@topiam.cn on 2022/8/23 21:58
*/
public abstract class AbstractOidcCertificateApplicationService extends
AbstractCertificateApplicationService
implements OidcApplicationService {
public abstract class AbstractOidcApplicationService extends AbstractCertApplicationService
implements OidcApplicationService {
@Override
public void delete(String appId) {
//删除应用
appRepository.deleteById(Long.valueOf(appId));
appRepository.deleteById(appId);
//删除证书
appCertRepository.deleteByAppId(Long.valueOf(appId));
appCertRepository.deleteByAppId(appId);
//删除应用账户
appAccountRepository.deleteAllByAppId(Long.valueOf(appId));
appAccountRepository.deleteAllByAppId(appId);
//删除应用权限策略
appAccessPolicyRepository.deleteAllByAppId(Long.valueOf(appId));
appAccessPolicyRepository.deleteAllByAppId(appId);
//删除OIDC配置
appOidcConfigRepository.deleteByAppId(Long.valueOf(appId));
appOidcConfigRepository.deleteByAppId(appId);
}
/**
@ -86,11 +85,12 @@ public abstract class AbstractOidcCertificateApplicationService extends
RSAKey rsaKey = new RSAKey.Builder(rsaPublicKey)
.privateKey(rsaPrivateKey)
.keyID(appCert.getId().toString())
.keyID(appCert.getId())
.build();
return OidcProtocolConfig.builder()
.appId(appConfig.getAppId().toString())
.appId(appConfig.getAppId())
.appName(appConfig.getAppName())
.clientId(appConfig.getClientId())
.clientSecret(appConfig.getClientSecret())
.appCode(appConfig.getAppCode())
@ -105,12 +105,15 @@ public abstract class AbstractOidcCertificateApplicationService extends
.requireProofKey(appConfig.getRequireProofKey())
.tokenEndpointAuthSigningAlgorithm(appConfig.getTokenEndpointAuthSigningAlgorithm())
.refreshTokenTimeToLive(appConfig.getRefreshTokenTimeToLive())
.authorizationCodeTimeToLive(appConfig.getAuthorizationCodeTimeToLive())
.deviceCodeTimeToLive(appConfig.getDeviceCodeTimeToLive())
.idTokenSignatureAlgorithm(appConfig.getIdTokenSignatureAlgorithm())
.idTokenTimeToLive(appConfig.getIdTokenTimeToLive())
.accessTokenFormat(appConfig.getAccessTokenFormat())
.accessTokenTimeToLive(appConfig.getAccessTokenTimeToLive())
.reuseRefreshToken(appConfig.getReuseRefreshToken())
.jwks(Collections.singletonList(rsaKey))
.configured(appConfig.getConfigured())
.build();
//@formatter:on
@ -134,14 +137,14 @@ public abstract class AbstractOidcCertificateApplicationService extends
*/
protected final AppOidcConfigRepository appOidcConfigRepository;
protected AbstractOidcCertificateApplicationService(AppCertRepository appCertRepository,
AppAccountRepository appAccountRepository,
AppAccessPolicyRepository appAccessPolicyRepository,
AppRepository appRepository,
AppGroupAssociationRepository appGroupAssociationRepository,
AppOidcConfigRepository appOidcConfigRepository) {
super(appCertRepository, appAccountRepository, appAccessPolicyRepository,
appGroupAssociationRepository, appRepository);
protected AbstractOidcApplicationService(AppCertRepository appCertRepository,
AppGroupAssociationRepository appGroupAssociationRepository,
AppAccountRepository appAccountRepository,
AppAccessPolicyRepository appAccessPolicyRepository,
AppRepository appRepository,
AppOidcConfigRepository appOidcConfigRepository) {
super(appCertRepository, appGroupAssociationRepository, appAccountRepository,
appAccessPolicyRepository, appRepository);
this.appCertRepository = appCertRepository;
this.appRepository = appRepository;
this.appOidcConfigRepository = appOidcConfigRepository;

View File

@ -24,7 +24,7 @@ import cn.topiam.employee.application.oidc.model.OidcProtocolConfig;
*
*
* @author TopIAM
* Created by support@topiam.cn on 2022/8/20 23:20
* Created by support@topiam.cn on 2022/8/20 23:20
*/
public interface OidcApplicationService extends ApplicationService {

View File

@ -17,13 +17,15 @@
*/
package cn.topiam.employee.application.oidc.converter;
import java.time.Duration;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Objects;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.text.StringSubstitutor;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import cn.topiam.employee.application.oidc.pojo.AppOidcProtocolEndpoint;
import cn.topiam.employee.application.oidc.pojo.AppOidcStandardConfigGetResult;
@ -31,9 +33,9 @@ import cn.topiam.employee.application.oidc.pojo.AppOidcStandardSaveConfigParam;
import cn.topiam.employee.common.constant.ProtocolConstants;
import cn.topiam.employee.common.entity.app.AppOidcConfigEntity;
import cn.topiam.employee.common.entity.app.po.AppOidcConfigPO;
import cn.topiam.employee.core.help.ServerHelp;
import cn.topiam.employee.core.context.ContextService;
import cn.topiam.employee.support.util.UrlUtils;
import static cn.topiam.employee.common.constant.AppConstants.APP_CODE;
import static cn.topiam.employee.common.constant.ProtocolConstants.APP_CODE;
import static cn.topiam.employee.common.constant.ProtocolConstants.OidcEndpointConstants.OIDC_AUTHORIZE_PATH;
import static cn.topiam.employee.common.constant.ProtocolConstants.OidcEndpointConstants.WELL_KNOWN_OPENID_CONFIGURATION;
@ -69,15 +71,27 @@ public interface AppOidcStandardConfigConverter {
//启用PKCE
result.setRequireProofKey(config.getRequireProofKey());
//访问令牌有效时间
result.setAccessTokenTimeToLive(config.getAccessTokenTimeToLive().toString());
result.setAccessTokenTimeToLive(
String.valueOf(config.getAccessTokenTimeToLive().toMinutes()));
//刷新令牌有效时间
result.setRefreshTokenTimeToLive(config.getRefreshTokenTimeToLive().toString());
result.setRefreshTokenTimeToLive(
String.valueOf(config.getRefreshTokenTimeToLive().toMinutes()));
//ID令牌有效时间
result.setIdTokenTimeToLive(config.getIdTokenTimeToLive().toString());
// id 令牌签名算法
result.setIdTokenTimeToLive(String.valueOf(config.getIdTokenTimeToLive().toMinutes()));
//设备授权码有效期
result
.setDeviceCodeTimeToLive(String.valueOf(config.getDeviceCodeTimeToLive().toMinutes()));
//access_token格式
result.setAccessTokenFormat(config.getAccessTokenFormat());
//授权码有效期
result.setAuthorizationCodeTimeToLive(
String.valueOf(config.getAuthorizationCodeTimeToLive().toMinutes()));
//ID令牌有效时间
result.setReuseRefreshToken(config.getReuseRefreshToken());
//ID令牌有效时间
result.setIdTokenTimeToLive(String.valueOf(config.getIdTokenTimeToLive().toMinutes()));
//ID令牌签名算法
result.setIdTokenSignatureAlgorithm(config.getIdTokenSignatureAlgorithm());
//SSO 发起方
result.setInitLoginType(config.getInitLoginType());
//登录发起地址
result.setInitLoginUrl(config.getInitLoginUrl());
//授权类型
@ -91,16 +105,52 @@ public interface AppOidcStandardConfigConverter {
* @param config {@link AppOidcConfigEntity}
* @return {@link AppOidcConfigEntity}
*/
@Mapping(target = "deleted", ignore = true)
@Mapping(target = "responseTypes", ignore = true)
@Mapping(target = "updateTime", ignore = true)
@Mapping(target = "updateBy", ignore = true)
@Mapping(target = "remark", ignore = true)
@Mapping(target = "id", ignore = true)
@Mapping(target = "createTime", ignore = true)
@Mapping(target = "createBy", ignore = true)
@Mapping(target = "appId", ignore = true)
AppOidcConfigEntity appOidcStandardSaveConfigParamToEntity(AppOidcStandardSaveConfigParam config);
default AppOidcConfigEntity appOidcStandardSaveConfigParamToEntity(AppOidcStandardSaveConfigParam config) {
if (config == null) {
return null;
}
AppOidcConfigEntity entity = new AppOidcConfigEntity();
if (CollectionUtils.isNotEmpty(config.getClientAuthMethods())) {
entity.setClientAuthMethods(new LinkedHashSet<>(config.getClientAuthMethods()));
}
if (CollectionUtils.isNotEmpty(config.getAuthGrantTypes())) {
entity.setAuthGrantTypes(new LinkedHashSet<>(config.getAuthGrantTypes()));
}
if (CollectionUtils.isNotEmpty(config.getRedirectUris())) {
entity.setRedirectUris(new LinkedHashSet<>(config.getRedirectUris()));
}
if (CollectionUtils.isNotEmpty(config.getPostLogoutRedirectUris())) {
entity
.setPostLogoutRedirectUris(new LinkedHashSet<>(config.getPostLogoutRedirectUris()));
}
if (CollectionUtils.isNotEmpty(config.getGrantScopes())) {
entity.setGrantScopes(new LinkedHashSet<>(config.getGrantScopes()));
}
entity.setRequireAuthConsent(config.getRequireAuthConsent());
entity.setRequireProofKey(config.getRequireProofKey());
entity.setTokenEndpointAuthSigningAlgorithm(config.getTokenEndpointAuthSigningAlgorithm());
if (config.getRefreshTokenTimeToLive() != null) {
entity
.setRefreshTokenTimeToLive(Duration.ofMinutes(config.getRefreshTokenTimeToLive()));
}
if (config.getAuthorizationCodeTimeToLive() != null) {
entity.setAuthorizationCodeTimeToLive(
Duration.ofMinutes(config.getAuthorizationCodeTimeToLive()));
}
if (config.getDeviceCodeTimeToLive() != null) {
entity.setDeviceCodeTimeToLive(Duration.ofMinutes(config.getDeviceCodeTimeToLive()));
}
if (config.getIdTokenTimeToLive() != null) {
entity.setIdTokenTimeToLive(Duration.ofMinutes(config.getIdTokenTimeToLive()));
}
if (config.getAccessTokenTimeToLive() != null) {
entity.setAccessTokenTimeToLive(Duration.ofMinutes(config.getAccessTokenTimeToLive()));
}
entity.setIdTokenSignatureAlgorithm(config.getIdTokenSignatureAlgorithm());
entity.setAccessTokenFormat(config.getAccessTokenFormat());
entity.setReuseRefreshToken(config.getReuseRefreshToken());
return entity;
}
/**
*
@ -116,21 +166,21 @@ public interface AppOidcStandardConfigConverter {
variables.put(APP_CODE,appCode);
StringSubstitutor sub = new StringSubstitutor(variables, "{", "}");
//Issuer
domain.setIssuer(sub.replace(ServerHelp.getPortalPublicBaseUrl()+OIDC_AUTHORIZE_PATH));
domain.setIssuer(sub.replace(ContextService.getPortalPublicBaseUrl() + OIDC_AUTHORIZE_PATH));
//发现端点
domain.setDiscoveryEndpoint(UrlUtils.format(ServerHelp.getPortalPublicBaseUrl() + sub.replace(WELL_KNOWN_OPENID_CONFIGURATION)));
domain.setDiscoveryEndpoint(UrlUtils.format(ContextService.getPortalPublicBaseUrl() + sub.replace(WELL_KNOWN_OPENID_CONFIGURATION)));
//认证端点
domain.setAuthorizationEndpoint(UrlUtils.format(ServerHelp.getPortalPublicBaseUrl() + sub.replace(ProtocolConstants.OidcEndpointConstants.AUTHORIZATION_ENDPOINT)));
domain.setAuthorizationEndpoint(UrlUtils.format(ContextService.getPortalPublicBaseUrl() + sub.replace(ProtocolConstants.OidcEndpointConstants.AUTHORIZATION_ENDPOINT)));
//Token端点
domain.setTokenEndpoint(UrlUtils.format(ServerHelp.getPortalPublicBaseUrl() + sub.replace( ProtocolConstants.OidcEndpointConstants.TOKEN_ENDPOINT)));
domain.setTokenEndpoint(UrlUtils.format(ContextService.getPortalPublicBaseUrl() + sub.replace( ProtocolConstants.OidcEndpointConstants.TOKEN_ENDPOINT)));
//Jwks端点
domain.setJwksEndpoint(UrlUtils.format(ServerHelp.getPortalPublicBaseUrl() + sub.replace(ProtocolConstants.OidcEndpointConstants.JWK_SET_ENDPOINT)));
domain.setJwksEndpoint(UrlUtils.format(ContextService.getPortalPublicBaseUrl() + sub.replace(ProtocolConstants.OidcEndpointConstants.JWK_SET_ENDPOINT)));
//撤销端点
domain.setRevokeEndpoint(UrlUtils.format(ServerHelp.getPortalPublicBaseUrl()+ sub.replace(ProtocolConstants.OidcEndpointConstants.TOKEN_REVOCATION_ENDPOINT)));
domain.setRevokeEndpoint(UrlUtils.format(ContextService.getPortalPublicBaseUrl()+ sub.replace(ProtocolConstants.OidcEndpointConstants.TOKEN_REVOCATION_ENDPOINT)));
//UserInfo端点
domain.setUserinfoEndpoint(UrlUtils.format(ServerHelp.getPortalPublicBaseUrl() + sub.replace(ProtocolConstants.OidcEndpointConstants.OIDC_USER_INFO_ENDPOINT)));
domain.setUserinfoEndpoint(UrlUtils.format(ContextService.getPortalPublicBaseUrl() + sub.replace(ProtocolConstants.OidcEndpointConstants.OIDC_USER_INFO_ENDPOINT)));
//登出端点
domain.setEndSessionEndpoint(UrlUtils.format(ServerHelp.getPortalPublicBaseUrl() + sub.replace(ProtocolConstants.OidcEndpointConstants.OIDC_LOGOUT_ENDPOINT)));
domain.setEndSessionEndpoint(UrlUtils.format(ContextService.getPortalPublicBaseUrl() + sub.replace(ProtocolConstants.OidcEndpointConstants.OIDC_LOGOUT_ENDPOINT)));
return domain;
//@formatter:on
}

View File

@ -18,9 +18,12 @@
package cn.topiam.employee.application.oidc.model;
import java.io.Serial;
import java.time.Duration;
import java.util.List;
import java.util.Set;
import org.springframework.util.CollectionUtils;
import com.nimbusds.jose.jwk.JWK;
import cn.topiam.employee.application.AbstractProtocolConfig;
@ -28,18 +31,16 @@ import cn.topiam.employee.application.AbstractProtocolConfig;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.SuperBuilder;
import lombok.extern.jackson.Jacksonized;
/**
* Oidc
*
* @author TopIAM
* Created by support@topiam.cn on 2022/8/28 21:43
* Created by support@topiam.cn on 2022/8/28 21:43
*/
@EqualsAndHashCode(callSuper = true)
@Data
@SuperBuilder
@Jacksonized
public class OidcProtocolConfig extends AbstractProtocolConfig {
@Serial
@ -90,20 +91,30 @@ public class OidcProtocolConfig extends AbstractProtocolConfig {
*/
private String tokenEndpointAuthSigningAlgorithm;
/**
*
*/
private Duration authorizationCodeTimeToLive;
/**
*
*/
private Duration deviceCodeTimeToLive;
/**
* Token
*/
private Integer refreshTokenTimeToLive;
private Duration refreshTokenTimeToLive;
/**
* ID Token
*/
private Integer idTokenTimeToLive;
private Duration idTokenTimeToLive;
/**
* 访 Token
*/
private Integer accessTokenTimeToLive;
private Duration accessTokenTimeToLive;
/**
* Id Token
@ -124,4 +135,33 @@ public class OidcProtocolConfig extends AbstractProtocolConfig {
* jwks
*/
private List<JWK> jwks;
/**
*
*/
private Boolean configured;
public Set<String> getRedirectUris() {
return CollectionUtils.isEmpty(redirectUris) ? Set.of() : redirectUris;
}
public Set<String> getPostLogoutRedirectUris() {
return CollectionUtils.isEmpty(postLogoutRedirectUris) ? Set.of() : postLogoutRedirectUris;
}
public Set<String> getGrantScopes() {
return CollectionUtils.isEmpty(grantScopes) ? Set.of() : grantScopes;
}
public Set<String> getClientAuthMethods() {
return CollectionUtils.isEmpty(clientAuthMethods) ? Set.of() : clientAuthMethods;
}
public Set<String> getResponseTypes() {
return CollectionUtils.isEmpty(responseTypes) ? Set.of() : responseTypes;
}
public List<JWK> getJwks() {
return CollectionUtils.isEmpty(jwks) ? List.of() : jwks;
}
}

View File

@ -22,14 +22,13 @@ import java.io.Serializable;
import lombok.Data;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.Schema;
/**
*
*
* @author TopIAM
* Created by support@topiam.cn on 2022/6/4 23:37
* Created by support@topiam.cn on 2022/6/4 23:37
*/
@Data
@Schema(description = "协议端点")
@ -40,48 +39,48 @@ public class AppOidcProtocolEndpoint implements Serializable {
/**
* oidcIssuer
*/
@Parameter(description = "Issuer")
@Schema(description = "Issuer")
private String issuer;
/**
* discoveryEndpoint
*/
@Parameter(description = "Discovery Endpoint")
@Schema(description = "Discovery Endpoint")
private String discoveryEndpoint;
/**
* UserinfoEndpoint
*/
@Parameter(description = "UserInfo Endpoint")
@Schema(description = "UserInfo Endpoint")
private String userinfoEndpoint;
/**
* jwksEndpoint
*/
@Parameter(description = "Jwks Endpoint")
@Schema(description = "Jwks Endpoint")
private String jwksEndpoint;
/**
* revokeEndpoint
*/
@Parameter(description = "Revoke Endpoint")
@Schema(description = "Revoke Endpoint")
private String revokeEndpoint;
/**
* tokenEndpoint
*/
@Parameter(description = "Token Endpoint")
@Schema(description = "Token Endpoint")
private String tokenEndpoint;
/**
* authorizationEndpoint
*/
@Parameter(description = "Authorization Endpoint")
@Schema(description = "Authorization Endpoint")
private String authorizationEndpoint;
/**
* endSessionEndpoint
*/
@Parameter(description = "End Session Endpoint")
@Schema(description = "End Session Endpoint")
private String endSessionEndpoint;
}

View File

@ -22,18 +22,16 @@ import java.io.Serializable;
import java.util.Set;
import cn.topiam.employee.common.enums.app.AuthorizationType;
import cn.topiam.employee.common.enums.app.InitLoginType;
import lombok.Data;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.Schema;
/**
* OIDC
*
* @author TopIAM
* Created by support@topiam.cn on 2022/5/31 22:46
* Created by support@topiam.cn on 2022/5/31 22:46
*/
@Data
@Schema(description = "OIDC 配置返回响应")
@ -42,113 +40,116 @@ public class AppOidcStandardConfigGetResult implements Serializable {
@Serial
private static final long serialVersionUID = 4177874005424703372L;
/**
* APP ID
*/
@Parameter(description = "appId")
private Long appId;
/**
* SSO
*/
@Parameter(description = "SSO 发起方")
private InitLoginType initLoginType;
/**
* SSO
*/
@Parameter(description = "SSO 登录链接")
@Schema(description = "SSO 登录链接")
private String initLoginUrl;
/**
*
*/
@Parameter(description = "SSO 授权范围")
@Schema(description = "SSO 授权范围")
private AuthorizationType authorizationType;
/**
* authorizationGrantTypes
*/
@Parameter(description = "认证授权类型")
@Schema(description = "认证授权类型")
private Set<String> authGrantTypes;
/**
*
*/
@Parameter(description = "客户端认证方式")
@Schema(description = "客户端认证方式")
private Set<String> clientAuthMethods;
/**
* URI
*/
@Parameter(description = "重定向URI")
@Schema(description = "重定向URI")
private Set<String> redirectUris;
/**
* URI
*/
@Parameter(description = "登出重定向URI")
@Schema(description = "登出重定向URI")
private Set<String> postLogoutRedirectUris;
/**
* scopes
*/
@Parameter(description = "授权范围")
@Schema(description = "授权范围")
private Set<String> grantScopes;
/**
* PKCE
*/
@Parameter(description = "启用PKCE")
@Schema(description = "启用PKCE")
private Boolean requireProofKey;
/**
* Endpoint
*/
@Parameter(description = "令牌 Endpoint 身份验证签名算法")
@Schema(description = "令牌 Endpoint 身份验证签名算法")
private String tokenEndpointAuthSigningAlgorithm;
/**
*
*/
@Parameter(description = "是否需要授权同意")
@Schema(description = "是否需要授权同意")
private Boolean requireAuthConsent;
/**
* 访
*/
@Parameter(description = "访问令牌有效时间")
@Schema(description = "访问令牌有效时间")
private String accessTokenTimeToLive;
/**
*
*/
@Parameter(description = "刷新令牌有效时间")
@Schema(description = "刷新令牌有效时间")
private String refreshTokenTimeToLive;
/**
*
*/
@Schema(description = "授权码 生存时间(分钟)")
private String authorizationCodeTimeToLive;
/**
* CODE
*/
@Schema(description = "设备CODE 生存时间(分钟)")
private String deviceCodeTimeToLive;
/**
* ID token
*/
@Parameter(description = "ID 令牌有效时间")
@Schema(description = "ID 令牌有效时间")
private String idTokenTimeToLive;
/**
* id
*/
@Parameter(description = "Id令牌签名算法")
@Schema(description = "Id令牌签名算法")
private String idTokenSignatureAlgorithm;
/**
*
*/
@Parameter(description = "协议端点域")
@Schema(description = "协议端点域")
private AppOidcProtocolEndpoint protocolEndpoint;
/**
* Access Token
*/
@Parameter(description = "Access Token 格式")
@Schema(description = "Access Token 格式")
private String accessTokenFormat;
/**
*
*/
@Parameter(description = "是否重用刷新令牌")
@Schema(description = "是否重用刷新令牌")
private Boolean reuseRefreshToken;
}

View File

@ -23,9 +23,6 @@ import java.util.List;
import org.hibernate.validator.constraints.URL;
import cn.topiam.employee.common.enums.app.AuthorizationType;
import cn.topiam.employee.common.enums.app.InitLoginType;
import lombok.Data;
import io.swagger.v3.oas.annotations.media.Schema;
@ -34,7 +31,7 @@ import jakarta.validation.constraints.NotNull;
/**
* @author TopIAM
* Created by support@topiam.cn on 2022/7/10 01:45
* Created by support@topiam.cn on 2022/7/10 01:45
*/
@Data
@Schema(description = "保存 OIDC 应用配置参数")
@ -64,23 +61,9 @@ public class AppOidcStandardSaveConfigParam implements Serializable {
private List<@NotBlank(message = "登出重定向URI不能为空") @URL(message = "登出重定向URI格式不正确") String> postLogoutRedirectUris;
/**
* SSO
* URL
*/
@NotNull(message = "SSO范围不能为空")
@Schema(description = "SSO范围")
private AuthorizationType authorizationType;
/**
* SSO
*/
@NotNull(message = "SSO发起方不能为空")
@Schema(description = "SSO发起方")
private InitLoginType initLoginType;
/**
* SSO URL
*/
@Schema(description = "SSO 发起登录URL")
@Schema(description = "登录发起登录URL")
private String initLoginUrl;
/**
@ -105,9 +88,9 @@ public class AppOidcStandardSaveConfigParam implements Serializable {
/**
* Access Token
*/
@NotBlank(message = "Access Token 生存时间不能为空")
@NotNull(message = "Access Token 生存时间不能为空")
@Schema(description = "Access Token 生存时间")
private String accessTokenTimeToLive;
private Long accessTokenTimeToLive;
/**
* Access Token
@ -118,16 +101,29 @@ public class AppOidcStandardSaveConfigParam implements Serializable {
/**
* Refresh Token
*/
@NotBlank(message = "Refresh Token 生存时间不能为空")
@NotNull(message = "Refresh Token 生存时间不能为空")
@Schema(description = "Refresh Token 生存时间")
private String refreshTokenTimeToLive;
private Long refreshTokenTimeToLive;
/**
*
*/
@NotNull(message = "授权码模式授权码生存时间不能为空")
@Schema(description = "授权码模式授权码生存时间")
private Long authorizationCodeTimeToLive;
/**
*
*/
@Schema(description = "设备模式授权码生存时间")
private Long deviceCodeTimeToLive;
/**
* Id Token
*/
@NotBlank(message = "Id Token 生存时间不能为空")
@NotNull(message = "Id Token 生存时间不能为空")
@Schema(description = "Id Token 生存时间")
private String idTokenTimeToLive;
private Long idTokenTimeToLive;
/**
* ID Token

View File

@ -24,7 +24,7 @@
<parent>
<groupId>cn.topiam</groupId>
<artifactId>eiam</artifactId>
<version>1.0.2-SNAPSHOT</version>
<version>1.1.0</version>
<relativePath>../pom.xml</relativePath>
</parent>
<packaging>pom</packaging>

View File

@ -24,7 +24,7 @@
<parent>
<groupId>cn.topiam</groupId>
<artifactId>eiam</artifactId>
<version>1.0.2-SNAPSHOT</version>
<version>1.1.0</version>
<relativePath>../pom.xml</relativePath>
</parent>
<packaging>jar</packaging>

View File

@ -1,74 +0,0 @@
/*
* eiam-audit - Employee Identity and Access Management
* Copyright © 2022-Present Jinan Yuanchuang Network Technology Co., Ltd. (support@topiam.cn)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package cn.topiam.employee.audit.access;
import cn.topiam.employee.support.enums.BaseEnum;
import static cn.topiam.employee.support.constant.EiamConstants.COLON;
/**
*
*
* @author TopIAM
* Created by support@topiam.cn on 2023/4/24 23:45
*/
public interface AuditAccess {
String CODE = "audit";
/**
*
*/
enum Audit implements BaseEnum {
/**
*
*/
audit_list("audit_list", "查看页面");
/**
* CODE
*/
public final static String CODE = AuditAccess.CODE + COLON + "audit";
/**
* CODE
*/
final static String ACTION_CODE_PREFIX = CODE + COLON;
/**
* code
*/
private final String code;
/**
* name
*/
private final String name;
Audit(String code, String name) {
this.code = code;
this.name = name;
}
@Override
public String getCode() {
return ACTION_CODE_PREFIX + this.code;
}
@Override
public String getDesc() {
return this.name;
}
}
}

View File

@ -25,7 +25,7 @@ import cn.topiam.employee.audit.event.type.EventType;
* Audit
*
* @author TopIAM
* Created by support@topiam.cn on 2021/9/28 21:56
* Created by support@topiam.cn on 2021/9/28 21:56
*/
@Target({ ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)

View File

@ -55,7 +55,7 @@ import static cn.topiam.employee.support.constant.EiamConstants.COLON;
*
*
* @author TopIAM
* Created by support@topiam.cn on 2021/9/28 21:20
* Created by support@topiam.cn on 2021/9/28 21:20
*/
@Component
@Aspect

View File

@ -23,7 +23,7 @@ import org.springframework.security.core.Authentication;
* Audit
*
* @author TopIAM
* Created by support@topiam.cn on 2021/9/28 22:45
* Created by support@topiam.cn on 2021/9/28 22:45
*/
public interface AuditExpressionOperations {

View File

@ -28,7 +28,7 @@ import lombok.AllArgsConstructor;
* AuditExpressionRoot
*
* @author TopIAM
* Created by support@topiam.cn on 2021/9/28 22:48
* Created by support@topiam.cn on 2021/9/28 22:48
*/
@AllArgsConstructor
public class AuditExpressionRoot implements AuditExpressionOperations {

View File

@ -17,15 +17,13 @@
*/
package cn.topiam.employee.audit.context;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.*;
import org.springframework.security.core.Authentication;
import org.springframework.util.CollectionUtils;
import com.alibaba.ttl.TransmittableThreadLocal;
import com.google.common.collect.Lists;
import cn.topiam.employee.audit.entity.Target;
@ -33,7 +31,7 @@ import cn.topiam.employee.audit.entity.Target;
* AuditContext
*
* @author TopIAM
* Created by support@topiam.cn on 2021/11/23 22:39
* Created by support@topiam.cn on 2021/11/23 22:39
*/
public class AuditContext {
@ -155,7 +153,7 @@ public class AuditContext {
*/
public static void setTarget(Target... target) {
if (!Objects.isNull(target)) {
TARGET_LIST.set(List.of(target));
TARGET_LIST.set(Lists.newArrayList(target));
}
}
@ -168,6 +166,20 @@ public class AuditContext {
}
}
/**
* Add Target
*/
public static void addTarget(Target target) {
if (!Objects.isNull(target)) {
List<Target> targetList = getTarget();
if (Objects.isNull(targetList)) {
targetList = new ArrayList<>();
}
targetList.add(target);
TARGET_LIST.set(targetList);
}
}
/**
* Remove Content
*/

View File

@ -15,7 +15,7 @@
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package cn.topiam.employee.audit.controller;
package cn.topiam.employee.audit.endpoint;
import java.util.List;
@ -26,11 +26,10 @@ import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import cn.topiam.employee.audit.controller.pojo.AuditListQuery;
import cn.topiam.employee.audit.controller.pojo.AuditListResult;
import cn.topiam.employee.audit.controller.pojo.DictResult;
import cn.topiam.employee.audit.endpoint.pojo.AuditListQuery;
import cn.topiam.employee.audit.endpoint.pojo.AuditListResult;
import cn.topiam.employee.audit.endpoint.pojo.DictResult;
import cn.topiam.employee.audit.service.AuditService;
import cn.topiam.employee.common.constant.AuditConstants;
import cn.topiam.employee.support.repository.page.domain.Page;
import cn.topiam.employee.support.repository.page.domain.PageModel;
import cn.topiam.employee.support.result.ApiRestResult;
@ -40,19 +39,25 @@ import lombok.AllArgsConstructor;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.constraints.NotNull;
import static cn.topiam.employee.support.constant.EiamConstants.V1_API_PATH;
/**
*
*
* @author TopIAM
* Created by support@topiam.cn on 2021/9/23 21:12
* Created by support@topiam.cn on 2021/9/23 21:12
*/
@Validated
@Tag(name = "系统审计")
@RestController
@RequestMapping(value = AuditConstants.AUDIT_PATH, produces = MediaType.APPLICATION_JSON_VALUE)
@RequestMapping(value = AuditEndpoint.AUDIT_PATH, produces = MediaType.APPLICATION_JSON_VALUE)
@AllArgsConstructor
public class AuditController {
public class AuditEndpoint {
/**
* API
*/
public final static String AUDIT_PATH = V1_API_PATH + "/audit";
/**
*

View File

@ -15,7 +15,7 @@
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package cn.topiam.employee.audit.controller.pojo;
package cn.topiam.employee.audit.endpoint.pojo;
import java.io.Serializable;
import java.time.LocalDateTime;
@ -38,7 +38,7 @@ import static cn.topiam.employee.support.constant.EiamConstants.DEFAULT_DATE_TIM
*
*
* @author TopIAM
* Created by support@topiam.cn on 2021/9/23 21:22
* Created by support@topiam.cn on 2021/9/23 21:22
*/
@Data
@Schema(description = "查询审计日志列表入参")
@ -67,7 +67,7 @@ public class AuditListQuery implements Serializable {
/**
*
*/
@Schema(description = "事件状态")
@Parameter(description = "事件状态")
private EventStatus eventStatus;
/**

View File

@ -15,7 +15,7 @@
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package cn.topiam.employee.audit.controller.pojo;
package cn.topiam.employee.audit.endpoint.pojo;
import java.io.Serializable;
import java.time.LocalDateTime;
@ -37,7 +37,7 @@ import static cn.topiam.employee.support.constant.EiamConstants.DEFAULT_DATE_TIM
*
*
* @author TopIAM
* Created by support@topiam.cn on 2021/9/24 22:07
* Created by support@topiam.cn on 2021/9/24 22:07
*/
@Data
@Schema(description = "审计日志列表响应")

View File

@ -15,7 +15,7 @@
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package cn.topiam.employee.audit.controller.pojo;
package cn.topiam.employee.audit.endpoint.pojo;
import java.util.Set;
@ -30,7 +30,7 @@ import io.swagger.v3.oas.annotations.media.Schema;
*
*
* @author TopIAM
* Created by support@topiam.cn on 2021/11/27 22:35
* Created by support@topiam.cn on 2021/11/27 22:35
*/
@Data
@Schema(description = "字典响应")

View File

@ -20,40 +20,40 @@ package cn.topiam.employee.audit.entity;
import java.io.Serial;
import java.io.Serializable;
import cn.topiam.employee.support.security.userdetails.UserType;
import lombok.Builder;
import lombok.Data;
import lombok.NonNull;
/**
* Actor
*
* @author TopIAM
* Created by support@topiam.cn on 2022/11/5 23:30
* Created by support@topiam.cn on 2022/11/5 23:30
*/
@Data
@Builder
public class Actor implements Serializable {
@Serial
private static final long serialVersionUID = -1144169992714000310L;
public static final String ACTOR_ID = "actor.id.keyword";
public static final String ACTOR_TYPE = "actor.type.keyword";
public static final String ACTOR_AUTH_TYPE = "actor.auth_type.keyword";
@Serial
private static final long serialVersionUID = -1144169992714000310L;
/**
* ID
*/
@NonNull
private String id;
private String id;
/**
*
*/
@NonNull
private UserType type;
private cn.topiam.employee.support.security.userdetails.UserType type;
/**
*
*/
private String authType;
private String authType;
}

View File

@ -22,13 +22,13 @@ import java.time.LocalDateTime;
import java.util.List;
import org.hibernate.annotations.JdbcTypeCode;
import org.hibernate.annotations.SQLDelete;
import org.hibernate.annotations.Where;
import org.hibernate.annotations.SoftDelete;
import org.hibernate.type.SqlTypes;
import cn.topiam.employee.audit.enums.EventStatus;
import cn.topiam.employee.audit.event.type.EventType;
import cn.topiam.employee.support.repository.domain.LogicDeleteEntity;
import cn.topiam.employee.support.repository.SoftDeleteConverter;
import cn.topiam.employee.support.repository.base.BaseEntity;
import cn.topiam.employee.support.security.userdetails.UserType;
import lombok.Getter;
@ -40,14 +40,13 @@ import lombok.experimental.Accessors;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.Table;
import static cn.topiam.employee.support.repository.domain.LogicDeleteEntity.SOFT_DELETE_SET;
import static cn.topiam.employee.support.repository.domain.LogicDeleteEntity.SOFT_DELETE_WHERE;
import static cn.topiam.employee.support.repository.base.BaseEntity.IS_DELETED_COLUMN;
/**
*
*
* @author TopIAM
* Created by support@topiam.cn on 2021/8/1 21:41
* Created by support@topiam.cn on 2021/8/1 21:41
*/
@Getter
@Setter
@ -55,10 +54,9 @@ import static cn.topiam.employee.support.repository.domain.LogicDeleteEntity.SOF
@RequiredArgsConstructor
@Accessors(chain = true)
@Entity
@Table(name = "audit")
@SQLDelete(sql = "update audit set " + SOFT_DELETE_SET + " where id_ = ?")
@Where(clause = SOFT_DELETE_WHERE)
public class AuditEntity extends LogicDeleteEntity<Long> {
@Table(name = "eiam_audit")
@SoftDelete(columnName = IS_DELETED_COLUMN, converter = SoftDeleteConverter.class)
public class AuditEntity extends BaseEntity {
@Serial
private static final long serialVersionUID = -3119319193111206582L;
@ -68,7 +66,6 @@ public class AuditEntity extends LogicDeleteEntity<Long> {
public static final String ACTOR_ID_FIELD_NAME = "actorId";
public static final String EVENT_TIME_FIELD_NAME = "eventTime";
/**
* Request Id
*/

View File

@ -21,10 +21,6 @@ import java.io.Serial;
import java.io.Serializable;
import java.time.LocalDateTime;
import org.springframework.data.elasticsearch.annotations.DateFormat;
import org.springframework.data.elasticsearch.annotations.Field;
import org.springframework.data.elasticsearch.annotations.FieldType;
import cn.topiam.employee.audit.enums.EventStatus;
import cn.topiam.employee.audit.event.type.EventType;
@ -35,7 +31,7 @@ import lombok.Data;
* Event
*
* @author TopIAM
* Created by support@topiam.cn on 2022/11/5 23:33
* Created by support@topiam.cn on 2022/11/5 23:33
*/
@Data
@Builder
@ -44,7 +40,7 @@ public class Event implements Serializable {
@Serial
private static final long serialVersionUID = -1144169992714000310L;
public static final String EVENT_TYPE = "event.type";
public static final String EVENT_TYPE = "event.type.keyword";
public static final String EVENT_TIME = "event.time";
@ -53,37 +49,31 @@ public class Event implements Serializable {
/**
*
*/
@Field(type = FieldType.Keyword, name = "type")
private EventType type;
/**
*
*/
@Field(type = FieldType.Text, name = "param")
private String param;
/**
*
*/
@Field(type = FieldType.Text, name = "content")
private String content;
/**
*
*/
@Field(type = FieldType.Text, name = "result")
private String result;
/**
*
*/
@Field(type = FieldType.Date, name = "time", format = DateFormat.date_hour_minute_second_millis)
private LocalDateTime time;
/**
*
*/
@Field(type = FieldType.Keyword, name = "status")
private EventStatus status;
}

View File

@ -20,8 +20,6 @@ package cn.topiam.employee.audit.entity;
import java.io.Serial;
import java.io.Serializable;
import org.springframework.data.elasticsearch.core.geo.GeoPoint;
import cn.topiam.employee.support.geo.GeoLocationProvider;
import lombok.AllArgsConstructor;
@ -33,7 +31,7 @@ import lombok.NoArgsConstructor;
*
*
* @author TopIAM
* Created by support@topiam.cn on 2022/11/5 23:31
* Created by support@topiam.cn on 2022/11/5 23:31
*/
@Data
@Builder

View File

@ -0,0 +1,65 @@
/*
* eiam-audit - Employee Identity and Access Management
* Copyright © 2022-Present Jinan Yuanchuang Network Technology Co., Ltd. (support@topiam.cn)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package cn.topiam.employee.audit.entity;
import java.util.Objects;
import lombok.Getter;
/**
* GeoPoint
*
* @author TopIAM
* Created by support@topiam.cn on 2024/04/17 23:30
*/
@Getter
public class GeoPoint {
private double lat;
private double lon;
private GeoPoint() {
}
public GeoPoint(double latitude, double longitude) {
this.lat = latitude;
this.lon = longitude;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
GeoPoint geoPoint = (GeoPoint) o;
return Double.compare(geoPoint.lat, lat) == 0 && Double.compare(geoPoint.lon, lon) == 0;
}
@Override
public int hashCode() {
return Objects.hash(lat, lon);
}
@Override
public String toString() {
return "GeoPoint{" + "lat=" + lat + ", lon=" + lon + '}';
}
}

View File

@ -22,16 +22,13 @@ import java.io.Serializable;
import cn.topiam.employee.audit.enums.TargetType;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.*;
/**
* Target
*
* @author TopIAM
* Created by support@topiam.cn on 2022/11/5 23:34
* Created by support@topiam.cn on 2022/11/5 23:34
*/
@Data
@Builder
@ -47,20 +44,27 @@ public class Target implements Serializable {
/**
* ID
*/
@NonNull
private String id;
/**
*
*/
@NonNull
private String name;
/**
*
*
*/
@NonNull
private TargetType type;
/**
*
*/
private String typeName;
public String getTypeName() {
return type.getDesc();
}
}

View File

@ -27,7 +27,7 @@ import lombok.NoArgsConstructor;
/**
* UserAgent
* @author TopIAM
* Created by support@topiam.cn on 2022/11/5 23:31
* Created by support@topiam.cn on 2022/11/5 23:31
*/
@Data
@Builder
@ -35,15 +35,17 @@ import lombok.NoArgsConstructor;
@NoArgsConstructor
public class UserAgent implements Serializable {
private String deviceType;
public static final String USER_AGENT_BROWSER = "user_agent.browser.keyword";
private String platform;
private String deviceType;
private String platformVersion;
private String platform;
private String browser;
private String platformVersion;
private String browserType;
private String browser;
private String browserMajorVersion;
private String browserType;
private String browserMajorVersion;
}

View File

@ -27,7 +27,7 @@ import lombok.Getter;
*
*
* @author TopIAM
* Created by support@topiam.cn on 2022/11/6 21:57
* Created by support@topiam.cn on 2022/11/6 21:57
*/
@Getter
public enum EventStatus {

View File

@ -20,6 +20,7 @@ package cn.topiam.employee.audit.enums;
import com.fasterxml.jackson.annotation.JsonValue;
import cn.topiam.employee.audit.event.type.EventType;
import cn.topiam.employee.support.exception.BadParamsException;
import cn.topiam.employee.support.web.converter.EnumConvert;
import lombok.Getter;
@ -28,7 +29,7 @@ import lombok.Getter;
*
*
* @author TopIAM
* Created by support@topiam.cn on 2022/10/27 23:46
* Created by support@topiam.cn on 2022/10/27 23:46
*/
@Getter
public enum TargetType {
@ -126,7 +127,11 @@ public enum TargetType {
/**
*
*/
PORTAL("portal", "门户端");
PORTAL("portal", "门户端"),
/**
*
*/
USER_IDP("user_idp", "用户绑定三方用户");
@JsonValue
private final String code;
@ -151,7 +156,7 @@ public enum TargetType {
return status;
}
}
return null;
throw new BadParamsException("无效的目标类型");
}
}

View File

@ -26,7 +26,7 @@ import jakarta.persistence.Converter;
/**
* @author TopIAM
* Created by support@topiam.cn on 2021/11/10 23:02
* Created by support@topiam.cn on 2021/11/10 23:02
*/
@Converter(autoApply = true)
public class AuditTypeConverter implements AttributeConverter<EventType, String> {

View File

@ -26,7 +26,7 @@ import jakarta.persistence.Converter;
/**
* @author TopIAM
* Created by support@topiam.cn on 2021/11/10 23:02
* Created by support@topiam.cn on 2021/11/10 23:02
*/
@Converter(autoApply = true)
public class EventStatusConverter implements AttributeConverter<EventStatus, String> {

View File

@ -26,7 +26,7 @@ import jakarta.persistence.Converter;
/**
* @author TopIAM
* Created by support@topiam.cn on 2021/11/10 23:02
* Created by support@topiam.cn on 2021/11/10 23:02
*/
@Converter(autoApply = true)
public class TargetTypeConverter implements AttributeConverter<TargetType, String> {

View File

@ -30,7 +30,7 @@ import lombok.Getter;
*
*
* @author TopIAM
* Created by support@topiam.cn on 2021/8/1 21:56
* Created by support@topiam.cn on 2021/8/1 21:56
*/
@Getter
public class AuditEvent extends ApplicationEvent {

View File

@ -35,7 +35,7 @@ import cn.topiam.employee.audit.repository.AuditRepository;
*
*
* @author TopIAM
* Created by support@topiam.cn on 2021/9/12 22:49
* Created by support@topiam.cn on 2021/9/12 22:49
*/
@Component
@Async

View File

@ -24,7 +24,6 @@ import java.util.Objects;
import org.apache.commons.lang3.StringUtils;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.data.elasticsearch.core.geo.GeoPoint;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
@ -36,7 +35,7 @@ import com.google.common.collect.Maps;
import cn.topiam.employee.audit.entity.*;
import cn.topiam.employee.audit.enums.EventStatus;
import cn.topiam.employee.audit.event.type.EventType;
import cn.topiam.employee.support.context.ServletContextHelp;
import cn.topiam.employee.support.context.ServletContextService;
import cn.topiam.employee.support.geo.GeoLocationService;
import cn.topiam.employee.support.security.authentication.WebAuthenticationDetails;
import cn.topiam.employee.support.security.userdetails.UserDetails;
@ -52,7 +51,7 @@ import static cn.topiam.employee.support.util.StringUtils.replaceBlank;
*
*
* @author TopIAM
* Created by support@topiam.cn on 2021/8/1 21:04
* Created by support@topiam.cn on 2021/8/1 21:04
*/
@Component
public class AuditEventPublish {
@ -77,7 +76,7 @@ public class AuditEventPublish {
//封装操作人
Actor actor = getActor();
//Publish AuditEvent
applicationEventPublisher.publishEvent(new AuditEvent(TraceUtils.get(), ServletContextHelp.getSession().getId(), actor, event, userAgent, geoLocationModal, null));
applicationEventPublisher.publishEvent(new AuditEvent(TraceUtils.get(), ServletContextService.getSession().getId(), actor, event, userAgent, geoLocationModal, null));
//@formatter:on
}
@ -108,7 +107,7 @@ public class AuditEventPublish {
//封装操作人
Actor actor = getActor(authentication);
//Publish AuditEvent
applicationEventPublisher.publishEvent(new AuditEvent(TraceUtils.get(), ServletContextHelp.getSession().getId(), actor, event, userAgent, geoLocationModal, targets));
applicationEventPublisher.publishEvent(new AuditEvent(TraceUtils.get(), ServletContextService.getSession().getId(), actor, event, userAgent, geoLocationModal, targets));
//@formatter:on
}
@ -130,7 +129,7 @@ public class AuditEventPublish {
//封装用户代理
UserAgent userAgent = getUserAgent();
//Publish AuditEvent
applicationEventPublisher.publishEvent(new AuditEvent(TraceUtils.get(), ServletContextHelp.getSession().getId(), actor, event, userAgent, geoLocationModal, null));
applicationEventPublisher.publishEvent(new AuditEvent(TraceUtils.get(), ServletContextService.getSession().getId(), actor, event, userAgent, geoLocationModal, null));
//@formatter:on
}
@ -171,7 +170,7 @@ public class AuditEventPublish {
actor = getActor();
}
//Publish AuditEvent
applicationEventPublisher.publishEvent(new AuditEvent(TraceUtils.get(), ServletContextHelp.getSession().getId(), actor, event, userAgent, geoLocationModal, target));
applicationEventPublisher.publishEvent(new AuditEvent(TraceUtils.get(), ServletContextService.getSession().getId(), actor, event, userAgent, geoLocationModal, target));
//@formatter:on
}
@ -197,7 +196,7 @@ public class AuditEventPublish {
//封装操作人
Actor actor = getActor();
//Publish AuditEvent
applicationEventPublisher.publishEvent(new AuditEvent(TraceUtils.get(), ServletContextHelp.getSession().getId(), actor, event, userAgent, geoLocationModal, target));
applicationEventPublisher.publishEvent(new AuditEvent(TraceUtils.get(), ServletContextService.getSession().getId(), actor, event, userAgent, geoLocationModal, target));
//@formatter:on
}
@ -272,7 +271,7 @@ public class AuditEventPublish {
*/
private UserAgent getUserAgent() {
//@formatter:off
HttpServletRequest request = ServletContextHelp.getRequest();
HttpServletRequest request = ServletContextService.getRequest();
cn.topiam.employee.support.web.useragent.UserAgent ua = UserAgentParser.getUserAgent(request);
return UserAgent.builder()
.browser(ua.getBrowser())
@ -292,7 +291,7 @@ public class AuditEventPublish {
*/
private GeoLocation getGeoLocation() {
//@formatter:off
HttpServletRequest request = ServletContextHelp.getRequest();
HttpServletRequest request = ServletContextService.getRequest();
String ip = IpUtils.getIpAddr(request);
cn.topiam.employee.support.geo.GeoLocation geoLocation = geoLocationService.getGeoLocation(ip);
if (Objects.isNull(geoLocation)){

View File

@ -25,7 +25,7 @@ import lombok.EqualsAndHashCode;
*
*
* @author TopIAM
* Created by support@topiam.cn on 2021/9/29 21:07
* Created by support@topiam.cn on 2021/9/29 21:07
*/
@EqualsAndHashCode(callSuper = true)
@Data

View File

@ -25,7 +25,7 @@ import lombok.EqualsAndHashCode;
*
*
* @author TopIAM
* Created by support@topiam.cn on 2021/9/29 21:07
* Created by support@topiam.cn on 2021/9/29 21:07
*/
@EqualsAndHashCode(callSuper = true)
@Data

View File

@ -28,7 +28,7 @@ import lombok.Data;
*
*
* @author TopIAM
* Created by support@topiam.cn on 2021/11/24 23:06
* Created by support@topiam.cn on 2021/11/24 23:06
*/
@Data
@AllArgsConstructor

View File

@ -27,7 +27,7 @@ import static cn.topiam.employee.support.security.userdetails.UserType.ADMIN;
*
*
* @author TopIAM
* Created by support@topiam.cn on 2021/11/24 22:58
* Created by support@topiam.cn on 2021/11/24 22:58
*/
public class AccountEventType {

View File

@ -28,7 +28,7 @@ import static cn.topiam.employee.audit.event.ConsoleResource.APP_RESOURCE;
*
*
* @author TopIAM
* Created by support@topiam.cn on 2021/11/24 23:00
* Created by support@topiam.cn on 2021/11/24 23:00
*/
public class AppEventType {
@ -69,6 +69,18 @@ public class AppEventType {
public static Type APP_ACCESS_POLICY = new Type("eiam:event:app:access_policy",
"添加应用访问授权", APP_RESOURCE, List.of(UserType.ADMIN));
/**
* 访
*/
public static Type ENABLE_APP_ACCESS_POLICY = new Type(
"eiam:event:app:enable_access_policy", "启用应用访问授权", APP_RESOURCE, List.of(UserType.ADMIN));
/**
* 访
*/
public static Type DISABLE_APP_ACCESS_POLICY = new Type(
"eiam:event:app:disable_access_policy", "禁用应用访问授权", APP_RESOURCE, List.of(UserType.ADMIN));
/**
* 访
*/
@ -81,6 +93,12 @@ public class AppEventType {
public static Type ADD_APP_ACCOUNT = new Type("eiam:event:app:add_app_account",
"添加应用账户", APP_RESOURCE, List.of(UserType.ADMIN));
/**
*
*/
public static Type UPDATE_DEFAULT_APP_ACCOUNT = new Type(
"eiam:event:app:update_default_app_account", "更新默认应用账户", APP_RESOURCE,
List.of(UserType.ADMIN));
/**
*
*/

View File

@ -22,13 +22,13 @@ import java.util.List;
import cn.topiam.employee.audit.event.ConsoleResource;
import cn.topiam.employee.audit.event.Type;
import cn.topiam.employee.support.security.userdetails.UserType;
import static cn.topiam.employee.audit.event.ConsoleResource.*;
import static cn.topiam.employee.audit.event.ConsoleResource.IDP_RESOURCE;
/**
*
*
* @author TopIAM
* Created by support@topiam.cn on 2021/11/24 22:59
* Created by support@topiam.cn on 2021/11/24 22:59
*/
public class AuthenticationEventType {

View File

@ -32,7 +32,7 @@ import lombok.Getter;
*
*
* @author TopIAM
* Created by support@topiam.cn on 2021/9/29 21:00
* Created by support@topiam.cn on 2021/9/29 21:00
*/
@Getter
public enum EventType {
@ -304,6 +304,15 @@ public enum EventType {
*
*/
APP_AUTHORIZATION(AppEventType.APP_ACCESS_POLICY),
/**
* 访
*/
ENABLE_APP_ACCESS_POLICY(AppEventType.ENABLE_APP_ACCESS_POLICY),
/**
* 访
*/
DISABLE_APP_ACCESS_POLICY(AppEventType.DISABLE_APP_ACCESS_POLICY),
/**
*
*/
@ -312,6 +321,10 @@ public enum EventType {
*
*/
ADD_APP_ACCOUNT(AppEventType.ADD_APP_ACCOUNT),
/**
*
*/
UPDATE_DEFAULT_APP_ACCOUNT(AppEventType.UPDATE_DEFAULT_APP_ACCOUNT),
/**
*
*/

View File

@ -27,7 +27,7 @@ import static cn.topiam.employee.audit.event.ConsoleResource.SESSION_RESOURCE;
*
*
* @author TopIAM
* Created by support@topiam.cn on 2021/11/24 22:58
* Created by support@topiam.cn on 2021/11/24 22:58
*/
public class MonitorEventType {

View File

@ -22,13 +22,14 @@ import java.util.List;
import cn.topiam.employee.audit.event.ConsoleResource;
import cn.topiam.employee.audit.event.Type;
import cn.topiam.employee.support.security.userdetails.UserType;
import static cn.topiam.employee.audit.event.PortalResource.*;
import static cn.topiam.employee.audit.event.PortalResource.MY_ACCOUNT_RESOURCE;
import static cn.topiam.employee.audit.event.PortalResource.MY_APP_RESOURCE;
/**
*
*
* @author TopIAM
* Created by support@topiam.cn on 2021/11/24 22:58
* Created by support@topiam.cn on 2021/11/24 22:58
*/
public class PortalEventType {
/**

View File

@ -27,7 +27,7 @@ import static cn.topiam.employee.audit.event.ConsoleResource.*;
*
*
* @author TopIAM
* Created by support@topiam.cn on 2021/11/24 22:58
* Created by support@topiam.cn on 2021/11/24 22:58
*/
public class SettingEventType {

View File

@ -19,6 +19,6 @@
*
*
* @author TopIAM
* Created by support@topiam.cn on 2021/9/11 22:10
* Created by support@topiam.cn on 2021/9/11 22:10
*/
package cn.topiam.employee.audit;

View File

@ -28,19 +28,19 @@ import cn.topiam.employee.audit.repository.result.AuthnQuantityResult;
*
*
* @author TopIAM
* Created by support@topiam.cn on 2022/10/2 02:53
* Created by support@topiam.cn on 2022/10/2 02:53
*/
public interface AuditCustomizedRepository {
List<AuditStatisticsResult> authnHotProvider(EventType type, LocalDateTime startTime,
List<AuditStatisticsResult> authnHotProvider(List<EventType> types, LocalDateTime startTime,
LocalDateTime endTime);
List<AuthnQuantityResult> authnQuantity(EventType type, LocalDateTime startTime,
List<AuthnQuantityResult> authnQuantity(List<EventType> types, LocalDateTime startTime,
LocalDateTime endTime, String dateFormat);
List<AuditStatisticsResult> appVisitRank(EventType type, LocalDateTime startTime,
LocalDateTime endTime);
List<AuditStatisticsResult> authnZone(EventType type, LocalDateTime startTime,
List<AuditStatisticsResult> authnZone(List<EventType> types, LocalDateTime startTime,
LocalDateTime endTime);
}

View File

@ -18,48 +18,28 @@
package cn.topiam.employee.audit.repository;
import java.time.LocalDateTime;
import java.util.Optional;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;
import cn.topiam.employee.audit.entity.AuditEntity;
import cn.topiam.employee.support.repository.LogicDeleteRepository;
import cn.topiam.employee.audit.event.type.EventType;
/**
* repository
*
* @author TopIAM
* Created by support@topiam.cn on 2021/9/11 22:32
* Created by support@topiam.cn on 2021/9/11 22:32
*/
@Repository
public interface AuditRepository extends LogicDeleteRepository<AuditEntity, Long>,
public interface AuditRepository extends JpaRepository<AuditEntity, String>,
AuditCustomizedRepository, JpaSpecificationExecutor<AuditEntity> {
/**
*
*
* @param startTime {@link LocalDateTime}
* @param endTime {@link LocalDateTime}
* @param userId {@link Long}
* @return {@link Integer}
*/
@Query(value = "SELECT count(*) FROM `audit` WHERE event_time BETWEEN :startTime AND :endTime AND actor_id = :userId AND event_type = 'eiam:event:login:portal' AND event_status = 'fail'", nativeQuery = true)
Integer countLoginFailByUserId(@Param("startTime") LocalDateTime startTime,
@Param("endTime") LocalDateTime endTime,
@Param("userId") Long userId);
/**
* requestId
*
* @param requestId {@link String}
* @return {@link AuditEntity}
*/
Optional<AuditEntity> findByRequestId(String requestId);
@Query(value = "SELECT COUNT(*) FROM audit WHERE event_type = :type AND event_time BETWEEN :startTime AND :endTime", nativeQuery = true)
Long countByTypeAndTime(@Param("type") String type, @Param("startTime") LocalDateTime startTime,
@Query(value = "SELECT COUNT(*) FROM AuditEntity WHERE eventType = :type AND eventTime BETWEEN :startTime AND :endTime")
Long countByTypeAndTime(@Param("type") EventType type,
@Param("startTime") LocalDateTime startTime,
@Param("endTime") LocalDateTime endTime);
}

View File

@ -19,8 +19,10 @@ package cn.topiam.employee.audit.repository.impl;
import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.stereotype.Repository;
import cn.topiam.employee.audit.event.type.EventType;
@ -35,58 +37,69 @@ import lombok.RequiredArgsConstructor;
/**
*
* @author TopIAM
* Created by support@topiam.cn on 2022/10/2 02:54
* Created by support@topiam.cn on 2022/10/2 02:54
*/
@Repository
@RequiredArgsConstructor
public class AuditCustomizedRepositoryImpl implements AuditCustomizedRepository {
/**
* JdbcTemplate
* NamedParameterJdbcTemplate
*/
private final JdbcTemplate jdbcTemplate;
private final NamedParameterJdbcTemplate namedParameterJdbcTemplate;
@Override
public List<AuditStatisticsResult> authnHotProvider(EventType type, LocalDateTime startTime,
public List<AuditStatisticsResult> authnHotProvider(List<EventType> types,
LocalDateTime startTime,
LocalDateTime endTime) {
String sql = """
SELECT
actor_auth_type AS key_,
COUNT(*) AS count_
FROM
audit
eiam_audit
WHERE
event_type = ?
AND event_time BETWEEN ?
AND ?
event_type IN (:types)
AND event_time BETWEEN :startTime
AND :endTime
GROUP BY
actor_auth_type
ORDER BY count_
""";
return jdbcTemplate.query(sql, new AuditStatisticsResultMapper(), type.getCode(), startTime,
endTime);
MapSqlParameterSource params = new MapSqlParameterSource();
params.addValue("types",
types.stream().map(EventType::getCode).collect(Collectors.toList()));
params.addValue("startTime", startTime);
params.addValue("endTime", endTime);
return namedParameterJdbcTemplate.query(sql, params, new AuditStatisticsResultMapper());
}
@Override
public List<AuthnQuantityResult> authnQuantity(EventType type, LocalDateTime startTime,
public List<AuthnQuantityResult> authnQuantity(List<EventType> types, LocalDateTime startTime,
LocalDateTime endTime, String dateFormat) {
String sql = """
SELECT
DATE_FORMAT( event_time, ? ) AS name_,
DATE_FORMAT( event_time, :dateFormat ) AS name_,
COUNT(*) AS count_,
event_status AS status_
FROM
audit
eiam_audit
WHERE
event_type = ?
AND event_time BETWEEN ?
AND ?
event_type IN (:types)
AND event_time BETWEEN :startTime
AND :endTime
GROUP BY
DATE_FORMAT( event_time, ? ),
DATE_FORMAT( event_time, :dateFormat ),
event_status
ORDER BY name_
""";
return jdbcTemplate.query(sql, new AuthnQuantityResultMapper(), dateFormat, type.getCode(),
startTime, endTime, dateFormat);
MapSqlParameterSource params = new MapSqlParameterSource();
params.addValue("types",
types.stream().map(EventType::getCode).collect(Collectors.toList()));
params.addValue("startTime", startTime);
params.addValue("endTime", endTime);
params.addValue("dateFormat", dateFormat);
return namedParameterJdbcTemplate.query(sql, params, new AuthnQuantityResultMapper());
}
@Override
@ -97,41 +110,49 @@ public class AuditCustomizedRepositoryImpl implements AuditCustomizedRepository
JSON_EXTRACT( target_, '$[0].id' ) AS key_,
COUNT(*) AS count_
FROM
audit
eiam_audit
WHERE
event_type = ?
AND event_time BETWEEN ?
AND ?
event_type = :type
AND event_time BETWEEN :startTime
AND :endTime
GROUP BY
JSON_EXTRACT(
target_,
'$[0].id'
)
ORDER BY count_
""";
return jdbcTemplate.query(sql, new AuditStatisticsResultMapper(), type.getCode(), startTime,
endTime);
MapSqlParameterSource params = new MapSqlParameterSource();
params.addValue("type", type.getCode());
params.addValue("startTime", startTime);
params.addValue("endTime", endTime);
return namedParameterJdbcTemplate.query(sql, params, new AuditStatisticsResultMapper());
}
@Override
public List<AuditStatisticsResult> authnZone(EventType type, LocalDateTime startTime,
public List<AuditStatisticsResult> authnZone(List<EventType> types, LocalDateTime startTime,
LocalDateTime endTime) {
String sql = """
SELECT
JSON_EXTRACT( target_, '$.provinceCode' ) AS key_,
JSON_EXTRACT( geo_location, '$.provinceCode' ) AS key_,
COUNT(*) AS count_
FROM
audit
eiam_audit
WHERE
event_type = ?
AND event_time BETWEEN ?
AND ?
event_type IN (:types)
AND event_time BETWEEN :startTime
AND :endTime
GROUP BY
JSON_EXTRACT(
target_,
geo_location,
'$.provinceCode'
)
""";
return jdbcTemplate.query(sql, new AuditStatisticsResultMapper(), type.getCode(), startTime,
endTime);
MapSqlParameterSource params = new MapSqlParameterSource();
params.addValue("types",
types.stream().map(EventType::getCode).collect(Collectors.toList()));
params.addValue("startTime", startTime);
params.addValue("endTime", endTime);
return namedParameterJdbcTemplate.query(sql, params, new AuditStatisticsResultMapper());
}
}

View File

@ -28,7 +28,7 @@ import cn.topiam.employee.audit.repository.result.AuditStatisticsResult;
/**
* @author TopIAM
* Created by support@topiam.cn on 2023/10/04 22:25
* Created by support@topiam.cn on 2023/10/04 22:25
*/
@SuppressWarnings("DuplicatedCode")
public class AuditStatisticsResultMapper implements RowMapper<AuditStatisticsResult> {

View File

@ -27,7 +27,7 @@ import cn.topiam.employee.audit.repository.result.AuthnQuantityResult;
/**
* @author TopIAM
* Created by support@topiam.cn on 2023/10/04 22:25
* Created by support@topiam.cn on 2023/10/04 22:25
*/
@SuppressWarnings("DuplicatedCode")
public class AuthnQuantityResultMapper implements RowMapper<AuthnQuantityResult> {

View File

@ -19,9 +19,9 @@ package cn.topiam.employee.audit.service;
import java.util.List;
import cn.topiam.employee.audit.controller.pojo.AuditListQuery;
import cn.topiam.employee.audit.controller.pojo.AuditListResult;
import cn.topiam.employee.audit.controller.pojo.DictResult;
import cn.topiam.employee.audit.endpoint.pojo.AuditListQuery;
import cn.topiam.employee.audit.endpoint.pojo.AuditListResult;
import cn.topiam.employee.audit.endpoint.pojo.DictResult;
import cn.topiam.employee.support.repository.page.domain.Page;
import cn.topiam.employee.support.repository.page.domain.PageModel;
@ -29,7 +29,7 @@ import cn.topiam.employee.support.repository.page.domain.PageModel;
* service
*
* @author TopIAM
* Created by support@topiam.cn on 2021/9/10 23:06
* Created by support@topiam.cn on 2021/9/10 23:06
*/
public interface AuditService {
/**

View File

@ -20,37 +20,23 @@ package cn.topiam.employee.audit.service.converter;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import org.mapstruct.Mapper;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import cn.topiam.employee.audit.controller.pojo.AuditListQuery;
import cn.topiam.employee.audit.controller.pojo.AuditListResult;
import cn.topiam.employee.audit.endpoint.pojo.AuditListQuery;
import cn.topiam.employee.audit.endpoint.pojo.AuditListResult;
import cn.topiam.employee.audit.entity.AuditEntity;
import cn.topiam.employee.audit.entity.Target;
import cn.topiam.employee.audit.enums.TargetType;
import cn.topiam.employee.common.entity.account.OrganizationEntity;
import cn.topiam.employee.common.entity.account.UserEntity;
import cn.topiam.employee.common.entity.account.UserGroupEntity;
import cn.topiam.employee.common.entity.app.AppEntity;
import cn.topiam.employee.common.entity.authn.IdentityProviderEntity;
import cn.topiam.employee.common.entity.identitysource.IdentitySourceEntity;
import cn.topiam.employee.common.entity.setting.AdministratorEntity;
import cn.topiam.employee.common.entity.setting.MailTemplateEntity;
import cn.topiam.employee.common.repository.account.OrganizationRepository;
import cn.topiam.employee.common.repository.account.UserGroupRepository;
import cn.topiam.employee.common.repository.account.UserRepository;
import cn.topiam.employee.common.repository.app.AppRepository;
import cn.topiam.employee.common.repository.authentication.IdentityProviderRepository;
import cn.topiam.employee.common.repository.identitysource.IdentitySourceRepository;
import cn.topiam.employee.common.repository.setting.AdministratorRepository;
import cn.topiam.employee.common.repository.setting.MailTemplateRepository;
import cn.topiam.employee.support.context.ApplicationContextHelp;
import cn.topiam.employee.support.context.ApplicationContextService;
import cn.topiam.employee.support.repository.page.domain.Page;
import cn.topiam.employee.support.repository.page.domain.PageModel;
import cn.topiam.employee.support.security.userdetails.UserDetails;
import cn.topiam.employee.support.security.userdetails.UserType;
import cn.topiam.employee.support.security.util.SecurityUtils;
@ -80,7 +66,7 @@ public interface AuditDataConverter {
//总记录数
auditEntityPage.forEach(audit -> {
AuditListResult result = new AuditListResult();
result.setId(audit.getId().toString());
result.setId(audit.getId());
result.setEventStatus(audit.getEventStatus());
result.setEventType(audit.getEventType().getDesc());
result.setEventTime(audit.getEventTime());
@ -93,14 +79,6 @@ public interface AuditDataConverter {
//用户类型
result.setUserType(audit.getActorType().getType());
//操作对象
if (Objects.nonNull(audit.getTargets())) {
for (Target target : audit.getTargets()) {
if (Objects.nonNull(target.getId())) {
target.setName(getTargetName(target.getType(), target.getId()));
}
target.setTypeName(target.getType().getDesc());
}
}
result.setTargets(audit.getTargets());
list.add(result);
});
@ -128,14 +106,14 @@ public interface AuditDataConverter {
return null;
}
if (UserType.USER.equals(actorType)) {
UserRepository repository = ApplicationContextHelp.getBean(UserRepository.class);
UserEntity user = repository.findById(Long.valueOf(actorId)).orElse(new UserEntity());
UserRepository repository = ApplicationContextService.getBean(UserRepository.class);
UserEntity user = repository.findById(actorId).orElse(new UserEntity());
return Objects.toString(user.getFullName(), user.getUsername());
}
if (UserType.ADMIN.equals(actorType)) {
AdministratorRepository repository = ApplicationContextHelp
AdministratorRepository repository = ApplicationContextService
.getBean(AdministratorRepository.class);
AdministratorEntity administrator = repository.findById(Long.valueOf(actorId))
AdministratorEntity administrator = repository.findById(actorId)
.orElse(new AdministratorEntity());
return administrator.getUsername();
}
@ -153,46 +131,35 @@ public interface AuditDataConverter {
return (root, criteriaQuery, criteriaBuilder) -> {
ArrayList<Predicate> predicates = new ArrayList<>();
ArrayList<Order> orders = new ArrayList<>();
UserType userType = SecurityUtils.getCurrentUser().getUserType();
UserDetails currentUser = SecurityUtils.getCurrentUser();
UserType loginUserType = currentUser.getUserType();
// 登录角色 管理员
if (UserType.ADMIN.equals(userType)) {
String actorId = null;
if (UserType.ADMIN.equals(loginUserType)) {
if (StringUtils.hasText(query.getUsername())) {
String actorId = "";
if (UserType.USER.getType().equals(query.getUserType())) {
UserRepository userRepository = ApplicationContextHelp
.getBean(UserRepository.class);
UserEntity user = userRepository.findByUsername(query.getUsername());
if (!Objects.isNull(user)) {
actorId = user.getId().toString();
}
}
if (UserType.ADMIN.getType().equals(query.getUserType())) {
AdministratorRepository administratorRepository = ApplicationContextHelp
.getBean(AdministratorRepository.class);
Optional<AdministratorEntity> optional = administratorRepository
.findByUsername(query.getUsername());
if (optional.isPresent()) {
actorId = optional.get().getId().toString();
}
}
if (StringUtils.hasText(actorId)) {
predicates.add(criteriaBuilder.equal(root.get("actorId"), actorId));
UserRepository userRepository = ApplicationContextService
.getBean(UserRepository.class);
List<UserEntity> userList = userRepository
.findByFullNameLike("%" + query.getUsername() + "%");
// 模糊匹配
if (!CollectionUtils.isEmpty(userList)) {
List<String> userIds = userList.stream().map(UserEntity::getId).toList();
predicates.add(criteriaBuilder.in(root.get("actorId")).value(userIds));
} else {
return null;
}
} else if (UserType.ADMIN.getType().equals(query.getUserType())) {
actorId = currentUser.getId();
}
// 用户类型
if (UserType.USER.getType().equals(query.getUserType())) {
predicates.add(criteriaBuilder.equal(root.get("actorType"), UserType.USER));
}
if (UserType.ADMIN.getType().equals(query.getUserType())) {
predicates.add(criteriaBuilder.equal(root.get("actorType"), UserType.ADMIN));
}
predicates.add(criteriaBuilder.equal(root.get("actorType"), query.getUserType()));
}
// 登录角色 用户
if (UserType.USER.equals(userType)) {
predicates.add(criteriaBuilder.equal(root.get("actorId"),
SecurityUtils.getCurrentUser().getId()));
// 用户类型
predicates.add(criteriaBuilder.equal(root.get("actorType"), UserType.USER));
if (UserType.USER.equals(loginUserType)) {
actorId = currentUser.getId();
}
if (StringUtils.hasText(actorId)) {
predicates.add(criteriaBuilder.equal(root.get("actorId"), currentUser.getId()));
}
// 事件类型
if (!CollectionUtils.isEmpty(query.getEventType())) {
@ -205,8 +172,8 @@ public interface AuditDataConverter {
.add(criteriaBuilder.equal(root.get("eventStatus"), query.getEventStatus()));
}
// 事件时间
if (!Objects.isNull(query.getStartEventTime())
&& !Objects.isNull(query.getEndEventTime())) {
if (Objects.nonNull(query.getStartEventTime())
&& Objects.nonNull(query.getEndEventTime())) {
predicates.add(criteriaBuilder.between(root.get("eventTime"),
query.getStartEventTime(), query.getEndEventTime()));
}
@ -225,91 +192,4 @@ public interface AuditDataConverter {
return criteriaQuery.getRestriction();
};
}
/**
*
*
* @param targetType {@link TargetType}
* @param id {@link String}
* @return {@link String}
*/
@SuppressWarnings("AlibabaMethodTooLong")
default String getTargetName(TargetType targetType, String id) {
//@formatter:off
String name = "";
if (TargetType.USER.equals(targetType) || TargetType.USER_DETAIL.equals(targetType)) {
UserRepository userRepository = ApplicationContextHelp.getBean(UserRepository.class);
Optional<UserEntity> user = userRepository.findByIdContainsDeleted(Long.valueOf(id));
if (user.isPresent()) {
UserEntity entity = user.get();
name = Objects.toString(entity.getFullName(),
entity.getUsername());
}
}
//用户组
if (TargetType.USER_GROUP.equals(targetType)) {
UserGroupRepository userGroupRepository = ApplicationContextHelp.getBean(UserGroupRepository.class);
Optional<UserGroupEntity> userGroup = userGroupRepository.findByIdContainsDeleted(Long.valueOf(id));
if (userGroup.isPresent()) {
name = userGroup.get().getName();
}
}
//身份源
if (TargetType.IDENTITY_SOURCE.equals(targetType)) {
IdentitySourceRepository identitySourceRepository = ApplicationContextHelp.getBean(IdentitySourceRepository.class);
Optional<IdentitySourceEntity> identitySource = identitySourceRepository.findByIdContainsDeleted(Long.valueOf(id));
if (identitySource.isPresent()) {
name = identitySource.get().getName();
}
}
//组织机构
if (TargetType.ORGANIZATION.equals(targetType)) {
OrganizationRepository organizationRepository = ApplicationContextHelp.getBean(OrganizationRepository.class);
Optional<OrganizationEntity> organizationEntity = organizationRepository.findByIdContainsDeleted(id);
if (organizationEntity.isPresent()) {
name = organizationEntity.get().getName();
}
}
//应用
if (TargetType.APPLICATION.equals(targetType)) {
AppRepository appRepository = ApplicationContextHelp.getBean(AppRepository.class);
Optional<AppEntity> appEntity = appRepository.findByIdContainsDeleted(Long.valueOf(id));
if (appEntity.isPresent()) {
name = appEntity.get().getName();
}
}
//应用账户
if (TargetType.APPLICATION_ACCOUNT.equals(targetType)) {
if (org.apache.commons.lang3.StringUtils.isNotBlank(id)) {
name = id;
}
}
//管理员
if (TargetType.ADMINISTRATOR.equals(targetType)) {
AdministratorRepository administratorRepository = ApplicationContextHelp.getBean(AdministratorRepository.class);
Optional<AdministratorEntity> administratorEntity = administratorRepository.findByIdContainsDeleted(Long.valueOf(id));
if (administratorEntity.isPresent()) {
name = administratorEntity.get().getUsername();
}
}
//邮件模版
if (TargetType.MAIL_TEMPLATE.equals(targetType)) {
MailTemplateRepository mailTemplateRepository = ApplicationContextHelp.getBean(MailTemplateRepository.class);
Optional<MailTemplateEntity> mailTemplateEntity = mailTemplateRepository.findByIdContainsDeleted(Long.valueOf(id));
if (mailTemplateEntity.isPresent()) {
name = mailTemplateEntity.get().getSender();
}
}
//身份提供商
if (TargetType.IDENTITY_PROVIDER.equals(targetType)) {
IdentityProviderRepository identityProviderRepository = ApplicationContextHelp.getBean(IdentityProviderRepository.class);
Optional<IdentityProviderEntity> identityProviderEntity = identityProviderRepository.findByIdContainsDeleted(Long.valueOf(id));
if (identityProviderEntity.isPresent()) {
name = identityProviderEntity.get().getName();
}
}
return name;
//@formatter:on
}
}

View File

@ -17,20 +17,18 @@
*/
package cn.topiam.employee.audit.service.impl;
import java.util.Arrays;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import java.util.*;
import java.util.stream.Collectors;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import cn.topiam.employee.audit.controller.pojo.AuditListQuery;
import cn.topiam.employee.audit.controller.pojo.AuditListResult;
import cn.topiam.employee.audit.controller.pojo.DictResult;
import cn.topiam.employee.audit.endpoint.pojo.AuditListQuery;
import cn.topiam.employee.audit.endpoint.pojo.AuditListResult;
import cn.topiam.employee.audit.endpoint.pojo.DictResult;
import cn.topiam.employee.audit.entity.AuditEntity;
import cn.topiam.employee.audit.event.type.EventType;
import cn.topiam.employee.audit.repository.AuditRepository;
@ -49,7 +47,7 @@ import static cn.topiam.employee.support.security.userdetails.UserType.USER;
* service impl
*
* @author TopIAM
* Created by support@topiam.cn on 2021/9/10 23:06
* Created by support@topiam.cn on 2021/9/10 23:06
*/
@Service
@RequiredArgsConstructor
@ -71,9 +69,18 @@ public class AuditServiceImpl implements AuditService {
//查询入参转查询条件
Specification<AuditEntity> specification = auditDataConverter
.auditListRequestConvertToSpecification(query, page);
if (Objects.isNull(specification)) {
return new Page<>();
}
// 排序
List<Sort.Order> orders = new ArrayList<>();
for (PageModel.Sort sort : page.getSorts()) {
orders.add(new Sort.Order((sort.getAsc() ? Sort.Direction.ASC : Sort.Direction.DESC),
sort.getSorter()));
}
//分页条件
PageRequest request = PageRequest.of(page.getCurrent(), page.getPageSize());
PageRequest request = PageRequest.of(page.getCurrent(), page.getPageSize(),
Sort.by(orders));
//查询列表
return auditDataConverter
.entityConvertToAuditListResult(auditRepository.findAll(specification, request), page);

View File

@ -21,10 +21,10 @@
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<parent>
<artifactId>eiam-authentication</artifactId>
<groupId>cn.topiam</groupId>
<version>1.0.2-SNAPSHOT</version>
<version>1.1.0</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -17,7 +17,7 @@
*/
package cn.topiam.employee.authentication.alipay;
import cn.topiam.employee.authentication.common.config.IdentityProviderConfig;
import cn.topiam.employee.authentication.common.client.IdentityProviderConfig;
import lombok.Data;
import lombok.EqualsAndHashCode;
@ -28,11 +28,11 @@ import jakarta.validation.constraints.NotBlank;
*
*
* @author TopIAM
* Created by support@topiam.cn on 2023/8/19 16:09
* Created by support@topiam.cn on 2023/8/19 16:09
*/
@Data
@EqualsAndHashCode(callSuper = true)
public class AlipayIdpOAuth2Config extends IdentityProviderConfig {
public class AlipayIdentityProviderOAuth2Config extends IdentityProviderConfig {
/**
* ID

View File

@ -24,7 +24,7 @@ import com.aliyun.tea.*;
/**
*
* @author TopIAM
* Created by support@topiam.cn on 2023/8/25 22:26
* Created by support@topiam.cn on 2023/8/25 22:26
*/
public class AlipayClient {
@ -42,12 +42,11 @@ public class AlipayClient {
* @throws Exception Exception
*/
public AlipaySystemOauthTokenResponse getOauthToken(String code) throws Exception {
java.util.Map<String, Object> runtime = getRuntime();
Map<String, Object> runtime = getRuntime();
TeaRequest request = null;
long now = System.currentTimeMillis();
int retryTimes = 0;
while (Tea.allowRetry((java.util.Map<String, Object>) runtime.get("retry"), retryTimes,
now)) {
while (Tea.allowRetry((Map<String, Object>) runtime.get("retry"), retryTimes, now)) {
if (retryTimes > 0) {
int backoffTime = Tea.getBackoffTime(runtime.get("backoff"), retryTimes);
if (backoffTime > 0) {
@ -57,7 +56,7 @@ public class AlipayClient {
retryTimes = retryTimes + 1;
try {
//@formatter:off
java.util.Map<String, String> systemParams = TeaConverter.buildMap(
Map<String, String> systemParams = TeaConverter.buildMap(
new TeaPair("method", "alipay.system.oauth.token"),
new TeaPair("app_id", kernel.getConfig("appId")),
new TeaPair("timestamp", kernel.getTimestamp()),
@ -68,13 +67,13 @@ public class AlipayClient {
new TeaPair("app_cert_sn", kernel.getMerchantCertSN()),
new TeaPair("alipay_root_cert_sn", kernel.getAlipayRootCertSN()));
//@formatter:no
java.util.Map<String, Object> bizParams = new java.util.HashMap<>();
java.util.Map<String, String> textParams = TeaConverter.buildMap(
Map<String, Object> bizParams = new java.util.HashMap<>();
Map<String, String> textParams = TeaConverter.buildMap(
new TeaPair("grant_type", "authorization_code"), new TeaPair("code", code));
request = getRequest(systemParams, bizParams, textParams);
TeaResponse response = Tea.doAction(request, runtime);
java.util.Map<String, Object> respMap = kernel.readAsJson(response,
Map<String, Object> respMap = kernel.readAsJson(response,
"alipay.system.oauth.token");
if (kernel.isCertMode()) {
if (kernel.verify(respMap,
@ -122,7 +121,7 @@ public class AlipayClient {
return request;
}
private java.util.Map<String, Object> getRuntime() throws Exception {
private Map<String, Object> getRuntime() throws Exception {
return TeaConverter.buildMap(new TeaPair("ignoreSSL", kernel.getConfig("ignoreSSL")),
new TeaPair("httpProxy", kernel.getConfig("httpProxy")),
new TeaPair("connectTimeout", 15000), new TeaPair("readTimeout", 15000),

View File

@ -17,7 +17,9 @@
*/
package cn.topiam.employee.authentication.alipay.client;
import com.aliyun.tea.*;
import com.aliyun.tea.NameInMap;
import com.aliyun.tea.TeaModel;
import com.aliyun.tea.Validation;
import lombok.Getter;
import lombok.Setter;
@ -25,7 +27,7 @@ import lombok.Setter;
/**
*
* @author TopIAM
* Created by support@topiam.cn on 2023/8/25 22:26
* Created by support@topiam.cn on 2023/8/25 22:26
*/
@Getter
@Setter

View File

@ -0,0 +1,79 @@
/*
* eiam-authentication-alipay - Employee Identity and Access Management
* Copyright © 2022-Present Jinan Yuanchuang Network Technology Co., Ltd. (support@topiam.cn)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package cn.topiam.employee.authentication.alipay.client;
import com.aliyun.tea.NameInMap;
import com.aliyun.tea.TeaModel;
import com.aliyun.tea.Validation;
import lombok.Getter;
import lombok.Setter;
/**
*
* @author TopIAM
* Created by support@topiam.cn on 2023/8/25 22:26
*/
@Getter
@Setter
public class AlipaySystemUserInfoShareResponse extends TeaModel {
@NameInMap("http_body")
@Validation(required = true)
public String httpBody;
@NameInMap("code")
@Validation(required = true)
public String code;
@NameInMap("msg")
@Validation(required = true)
public String msg;
@NameInMap("sub_code")
@Validation(required = true)
public String subCode;
@NameInMap("sub_msg")
@Validation(required = true)
public String subMsg;
@NameInMap("user_id")
@Validation(required = true)
public String userId;
@NameInMap("avatar")
@Validation(required = true)
public String avatar;
@NameInMap("city")
@Validation(required = true)
public Long city;
@NameInMap("nick_name")
@Validation(required = true)
public String nickName;
@NameInMap("province")
@Validation(required = true)
public Long province;
@NameInMap("gender")
@Validation(required = true)
public Long gender;
}

View File

@ -29,8 +29,8 @@ import org.springframework.util.Assert;
import cn.topiam.employee.authentication.alipay.filter.AlipayAuthorizationRequestRedirectFilter;
import cn.topiam.employee.authentication.alipay.filter.AlipayLoginAuthenticationFilter;
import cn.topiam.employee.authentication.common.service.UserIdpService;
import cn.topiam.employee.common.repository.authentication.IdentityProviderRepository;
import cn.topiam.employee.authentication.common.IdentityProviderAuthenticationService;
import cn.topiam.employee.authentication.common.client.RegisteredIdentityProviderClientRepository;
import lombok.NonNull;
import lombok.Setter;
@ -40,36 +40,38 @@ import static cn.topiam.employee.support.security.util.HttpSecurityFilterOrderRe
*
*
* @author TopIAM
* Created by support@topiam.cn on 2023/8/19 15:52
* Created by support@topiam.cn on 2023/8/19 15:52
*/
public class AlipayAuthenticationConfigurer extends
AbstractAuthenticationFilterConfigurer<HttpSecurity, AlipayAuthenticationConfigurer, AlipayLoginAuthenticationFilter> {
@Setter
@NonNull
private String loginProcessingUrl = AlipayLoginAuthenticationFilter.DEFAULT_FILTER_PROCESSES_URI;
private String loginProcessingUrl = AlipayLoginAuthenticationFilter.DEFAULT_FILTER_PROCESSES_URI;
private final IdentityProviderRepository identityProviderRepository;
private final UserIdpService userIdpService;
private final RegisteredIdentityProviderClientRepository registeredIdentityProviderClientRepository;
private final IdentityProviderAuthenticationService identityProviderAuthenticationService;
AlipayAuthenticationConfigurer(IdentityProviderRepository identityProviderRepository,
UserIdpService userIdpService) {
Assert.notNull(identityProviderRepository, "identityProviderRepository must not be null");
Assert.notNull(userIdpService, "userIdpService must not be null");
this.identityProviderRepository = identityProviderRepository;
this.userIdpService = userIdpService;
AlipayAuthenticationConfigurer(RegisteredIdentityProviderClientRepository registeredIdentityProviderClientRepository,
IdentityProviderAuthenticationService identityProviderAuthenticationService) {
Assert.notNull(registeredIdentityProviderClientRepository,
"registeredIdentityProviderClientRepository must not be null");
Assert.notNull(identityProviderAuthenticationService, "userIdpService must not be null");
this.registeredIdentityProviderClientRepository = registeredIdentityProviderClientRepository;
this.identityProviderAuthenticationService = identityProviderAuthenticationService;
}
@Override
public void init(HttpSecurity http) throws Exception {
//支付宝登录认证
this.setAuthenticationFilter(
new AlipayLoginAuthenticationFilter(userIdpService, identityProviderRepository));
this.setAuthenticationFilter(new AlipayLoginAuthenticationFilter(
identityProviderAuthenticationService, registeredIdentityProviderClientRepository));
putFilterBefore(http, this.getAuthenticationFilter(),
OAuth2LoginAuthenticationFilter.class);
//支付宝请求重定向
http.addFilterBefore(
new AlipayAuthorizationRequestRedirectFilter(identityProviderRepository),
new AlipayAuthorizationRequestRedirectFilter(
registeredIdentityProviderClientRepository),
OAuth2AuthorizationRequestRedirectFilter.class);
//登录处理地址
@ -94,8 +96,9 @@ public class AlipayAuthenticationConfigurer extends
AlipayLoginAuthenticationFilter.getRequestMatcher());
}
public static AlipayAuthenticationConfigurer alipayOauth(IdentityProviderRepository identityProviderRepository,
UserIdpService userIdpService) {
return new AlipayAuthenticationConfigurer(identityProviderRepository, userIdpService);
public static AlipayAuthenticationConfigurer alipayOauth(RegisteredIdentityProviderClientRepository registeredIdentityProviderClientRepository,
IdentityProviderAuthenticationService identityProviderAuthenticationService) {
return new AlipayAuthenticationConfigurer(registeredIdentityProviderClientRepository,
identityProviderAuthenticationService);
}
}

View File

@ -21,7 +21,7 @@ package cn.topiam.employee.authentication.alipay.constant;
*
*
* @author TopIAM
* Created by support@topiam.cn on 2023/8/19 15:18
* Created by support@topiam.cn on 2023/8/19 15:18
*/
public class AlipayAuthenticationConstants {

Some files were not shown because too many files have changed in this diff Show More