├── Document ├── 基础研发总图路线图.pptx └── spring-session-db-schema │ ├── schema-h2.sql │ ├── schema-mysql.sql │ └── schema-oracle.sql ├── framework-core └── src │ ├── test │ ├── resources │ │ └── system.properties │ └── java │ │ └── com │ │ └── centit │ │ └── framework │ │ └── test │ │ ├── TestI18n.java │ │ ├── TestRefection.java │ │ └── TestPasswordEncoder.java │ └── main │ └── java │ └── com │ └── centit │ └── framework │ ├── core │ ├── dao │ │ ├── README.md │ │ └── DictionaryMapColumn.java │ ├── controller │ │ ├── WrapUpResponseBody.java │ │ ├── WrapUpContentType.java │ │ ├── DatePropertiesEditor.java │ │ ├── SqlDatePropertiesEditor.java │ │ ├── SqlTimestampPropertiesEditor.java │ │ ├── StringPropertiesEditor.java │ │ ├── SmartDateFormat.java │ │ ├── ObjectAppendProperties.java │ │ └── MvcConfigUtil.java │ └── aop │ │ ├── NoRepeatCommit.java │ │ ├── ResubmitLock.java │ │ └── ResubmitDataAspect.java │ ├── components │ ├── impl │ │ ├── DummyMessageSenderImpl.java │ │ ├── Log4jOperationLogWriterImpl.java │ │ ├── TextOperationLogWriterImpl.java │ │ └── UserUnitMapTranslate.java │ └── README.md │ ├── filter │ ├── RequestThreadLocal.java │ ├── HttpThreadWrapper.java │ ├── RequestThreadLocalFilter.java │ └── AssertUserLoginFilter.java │ ├── operationlog │ ├── README.md │ └── RecordOperationLog.java │ ├── common │ ├── ValidatorUtils.java │ └── HttpContextUtils.java │ └── security │ ├── SM3PasswordEncoderImpl.java │ ├── CentitSecurityMetadata.java │ ├── StandardPasswordEncoderImpl.java │ └── UserDetailsServiceImpl.java ├── .gitignore ├── framework-dubbo-config ├── src │ └── main │ │ ├── resources │ │ └── META-INF │ │ │ └── dubbo │ │ │ └── com.alibaba.dubbo.rpc.Filter │ │ └── java │ │ └── com │ │ └── centit │ │ └── framework │ │ └── dubbo │ │ └── config │ │ └── DubboConfig.java └── pom.xml ├── framework-adapter ├── src │ ├── main │ │ └── java │ │ │ └── com │ │ │ └── centit │ │ │ └── framework │ │ │ ├── common │ │ │ ├── ToResponseData.java │ │ │ ├── ImmutableResponseData.java │ │ │ ├── GlobalConstValue.java │ │ │ ├── ResponseSingleData.java │ │ │ ├── ResponseMapData.java │ │ │ └── OptionItem.java │ │ │ ├── model │ │ │ ├── adapter │ │ │ │ ├── UserUnitFilterCalcContextFactory.java │ │ │ │ ├── README.md │ │ │ │ ├── OperationLogWriter.java │ │ │ │ ├── UserUnitVariableTranslate.java │ │ │ │ ├── MessageSender.java │ │ │ │ └── UserUnitFilterCalcContext.java │ │ │ ├── security │ │ │ │ ├── ThirdPartyCheckUserDetails.java │ │ │ │ ├── SimpleGrantedAuthority.java │ │ │ │ ├── CentitPasswordEncoder.java │ │ │ │ ├── CentitUserDetailsService.java │ │ │ │ └── CentitSecurityConfig.java │ │ │ └── basedata │ │ │ │ ├── FVUserRolesId.java │ │ │ │ ├── WorkGroupParameter.java │ │ │ │ ├── OptMethodUrlMap.java │ │ │ │ ├── FVUserOptListId.java │ │ │ │ ├── RolePowerId.java │ │ │ │ ├── UserRoleId.java │ │ │ │ ├── UnitRoleId.java │ │ │ │ ├── DataDictionaryId.java │ │ │ │ ├── UserSettingId.java │ │ │ │ ├── NoticeMessage.java │ │ │ │ └── FVUserOptList.java │ │ │ ├── core │ │ │ └── dao │ │ │ │ └── DictionaryMap.java │ │ │ └── appclient │ │ │ └── PooledHttpClientFactory.java │ └── test │ │ └── java │ │ └── com │ │ └── centit │ │ └── framework │ │ └── test │ │ ├── TestHttpReceiveJSON.java │ │ └── TestJson.java └── pom.xml ├── framework-config ├── README.md ├── src │ └── main │ │ └── java │ │ └── com │ │ └── centit │ │ └── framework │ │ └── config │ │ ├── SystemSpringMvcConfig.java │ │ ├── SecurityCasCondition.java │ │ ├── SecurityDaoCondition.java │ │ └── BaseSpringMvcConfig.java └── pom.xml ├── framework-session-core ├── src │ └── main │ │ └── java │ │ └── com │ │ └── centit │ │ └── framework │ │ └── session │ │ ├── CentitSessionRepo.java │ │ ├── FrameworkHttpSessionConfiguration.java │ │ └── FrameworkSessionApplicationInitializer.java └── pom.xml ├── framework-security ├── src │ ├── test │ │ └── java │ │ │ └── com │ │ │ └── centit │ │ │ └── framework │ │ │ └── security │ │ │ └── TestUrl.java │ └── main │ │ └── java │ │ └── com │ │ └── centit │ │ └── framework │ │ └── security │ │ ├── AjaxAuthenticationEntryPoint.java │ │ ├── HostIpFilterDecisionManager.java │ │ ├── DaoInvocationSecurityMetadataSource.java │ │ ├── AjaxAuthenticationFailureHandler.java │ │ ├── AjaxAccessDeniedHandlerImpl.java │ │ └── AjaxAuthenticationSuccessHandler.java ├── README.md └── pom.xml ├── .editorconfig ├── framework-core-web ├── src │ └── main │ │ ├── resources │ │ ├── ExtendedSqlMap.xml │ │ └── log4j2.xml │ │ └── java │ │ └── com │ │ └── centit │ │ └── framework │ │ └── system │ │ └── controller │ │ └── EnvironmentController.java └── pom.xml ├── framework-filter ├── src │ ├── main │ │ ├── java │ │ │ └── com │ │ │ │ └── centit │ │ │ │ └── framework │ │ │ │ └── filter │ │ │ │ ├── XFrameOptionsFilter.java │ │ │ │ ├── DisableUrlSessionFilter.java │ │ │ │ ├── GZIPFilter.java │ │ │ │ ├── CacheResponseWrapper.java │ │ │ │ ├── ResponseCorsFilter.java │ │ │ │ └── GZIPResponseWrapper.java │ │ └── resources │ │ │ └── securityconfig │ │ │ └── xss_security_config.xml │ └── test │ │ └── resources │ │ └── xss_security_config.xml └── pom.xml ├── framework-session-redis ├── pom.xml └── src │ └── main │ └── java │ └── com │ └── centit │ └── framework │ └── session │ └── redis │ ├── CentitSessionRedisRepo.java │ └── RedisSessionPersistenceConfig.java ├── centit-persistence-extend ├── pom.xml └── src │ └── main │ └── java │ └── com │ └── centit │ └── framework │ └── core │ └── service │ ├── DataScopePowerManager.java │ └── impl │ ├── CurrentUserContext.java │ └── DataScopePowerManagerImpl.java ├── README.md └── framework-session-jdbc ├── pom.xml └── src └── main └── java └── com └── centit └── framework └── session └── jdbc └── CentitSessionJdbcRepo.java /Document/基础研发总图路线图.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ndxt/centit-framework/HEAD/Document/基础研发总图路线图.pptx -------------------------------------------------------------------------------- /framework-core/src/test/resources/system.properties: -------------------------------------------------------------------------------- 1 | server.ip = http://127.0.0.1 2 | server.path = ${server.ip}/meet 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | target 3 | **/*.iml 4 | **/target 5 | **/node_modules 6 | .mvn 7 | mvn* 8 | .settings 9 | **/~$* 10 | out.* 11 | .flattened-pom.xml 12 | -------------------------------------------------------------------------------- /framework-dubbo-config/src/main/resources/META-INF/dubbo/com.alibaba.dubbo.rpc.Filter: -------------------------------------------------------------------------------- 1 | dubboServiceCallContextFilter=com.centit.framework.dubbo.config.DubboCallContextFilter -------------------------------------------------------------------------------- /framework-adapter/src/main/java/com/centit/framework/common/ToResponseData.java: -------------------------------------------------------------------------------- 1 | package com.centit.framework.common; 2 | 3 | public interface ToResponseData { 4 | ResponseData toResponseData(); 5 | } 6 | -------------------------------------------------------------------------------- /framework-adapter/src/main/java/com/centit/framework/model/adapter/UserUnitFilterCalcContextFactory.java: -------------------------------------------------------------------------------- 1 | package com.centit.framework.model.adapter; 2 | 3 | /** 4 | * 用于构建计算权限引擎的上下文环境 5 | * 6 | */ 7 | public interface UserUnitFilterCalcContextFactory { 8 | UserUnitFilterCalcContext createCalcContext(String topUnit); 9 | } 10 | -------------------------------------------------------------------------------- /framework-core/src/main/java/com/centit/framework/core/dao/README.md: -------------------------------------------------------------------------------- 1 | # 数据字典映射工具 2 | 3 | 数据字典的作用参见[数据字典](https://ndxt.github.io/system_design/concept_design.html#%E6%95%B0%E6%8D%AE%E5%AD%97%E5%85%B8)。 4 | 5 | ## 定义 6 | 7 | 在po的字段上用 DictionaryMap 注解添加映射关系。其中: 8 | 1. value 标识数据字典的catalog值。 9 | 2. fieldName 为将字典中的值映射到新的属性上。 10 | 11 | ## 实现 12 | 13 | DictionaryMapUtils 实现对DictionaryMap映射关系的处理。他只用于将po转化为JSON。 -------------------------------------------------------------------------------- /framework-config/README.md: -------------------------------------------------------------------------------- 1 | # 通用配置类 2 | 3 | ## BaseSpringMvcConfig 4 | 5 | 通用的mvc配置类,配置资源、jsp页面、FastJson序列化方式等等。 6 | 7 | ## *Condition 8 | 9 | 配置类条件加载器。 10 | 11 | ## *SessionPersistenceConfig 12 | 13 | 使用spring session做session持久化的配置。 14 | 15 | ## SpringSecurity*Config 16 | 17 | Spring Security相关配置,包括登录,权限过滤等等。 18 | 19 | ## SystemSpringMvcConfig 20 | 21 | 系统服务接口配置信息。 22 | 23 | ## WebConfig 24 | 25 | web通用配置包括监听和过滤器配置。 -------------------------------------------------------------------------------- /framework-session-core/src/main/java/com/centit/framework/session/CentitSessionRepo.java: -------------------------------------------------------------------------------- 1 | package com.centit.framework.session; 2 | 3 | import org.springframework.session.Session; 4 | 5 | public interface CentitSessionRepo { 6 | void kickSessionByName(String loginName, String escapeSessionId); 7 | 8 | void kickSessionByName(String loginName); 9 | 10 | void kickSessionByPrincipal(String principalName); 11 | 12 | Session findById(String id); 13 | 14 | } 15 | -------------------------------------------------------------------------------- /framework-core/src/main/java/com/centit/framework/core/controller/WrapUpResponseBody.java: -------------------------------------------------------------------------------- 1 | package com.centit.framework.core.controller; 2 | 3 | import java.lang.annotation.*; 4 | 5 | @Target({ElementType.TYPE, ElementType.METHOD}) 6 | @Retention(RetentionPolicy.RUNTIME) 7 | @Documented 8 | public @interface WrapUpResponseBody { 9 | /** 10 | * 用来指定 封装类别 11 | * @return String contentType 12 | */ 13 | WrapUpContentType contentType() default WrapUpContentType.DATA; 14 | } 15 | -------------------------------------------------------------------------------- /Document/spring-session-db-schema/schema-h2.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE SPRING_SESSION ( 2 | TOKEN_NO CHAR(48) NOT NULL, 3 | CREATION_TIME BIGINT NOT NULL, 4 | LAST_ACCESS_TIME BIGINT NOT NULL, 5 | MAX_INACTIVE_INTERVAL INT NOT NULL, 6 | USER_CODE VARCHAR(50) NOT NULL, 7 | USER_DETAILS LONGVARBINARY NOT NULL, 8 | CONSTRAINT SPRING_SESSION_PK PRIMARY KEY (TOKEN_NO) 9 | ); 10 | 11 | CREATE INDEX SPRING_SESSION_IX1 ON SPRING_SESSION (LAST_ACCESS_TIME); 12 | CREATE INDEX SPRING_SESSION_IX2 ON SPRING_SESSION (USER_CODE); 13 | -------------------------------------------------------------------------------- /Document/spring-session-db-schema/schema-mysql.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE SPRING_SESSION ( 2 | TOKEN_NO CHAR(48) NOT NULL, 3 | CREATION_TIME BIGINT NOT NULL, 4 | LAST_ACCESS_TIME BIGINT NOT NULL, 5 | MAX_INACTIVE_INTERVAL INT NOT NULL, 6 | USER_CODE VARCHAR(50) NOT NULL, 7 | USER_DETAILS BLOB NOT NULL, 8 | CONSTRAINT SPRING_SESSION_PK PRIMARY KEY (TOKEN_NO) 9 | ) ENGINE=InnoDB; 10 | 11 | CREATE INDEX SPRING_SESSION_IX1 ON SPRING_SESSION (LAST_ACCESS_TIME); 12 | CREATE INDEX SPRING_SESSION_IX2 ON SPRING_SESSION (USER_CODE); 13 | -------------------------------------------------------------------------------- /Document/spring-session-db-schema/schema-oracle.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE SPRING_SESSION ( 2 | TOKEN_NO CHAR(48) NOT NULL, 3 | CREATION_TIME NUMBER(19,0) NOT NULL, 4 | LAST_ACCESS_TIME NUMBER(19,0) NOT NULL, 5 | MAX_INACTIVE_INTERVAL NUMBER(10,0) NOT NULL, 6 | USER_CODE VARCHAR2(50 CHAR), 7 | USER_DETAILS BLOB NOT NULL, 8 | CONSTRAINT SPRING_SESSION_PK PRIMARY KEY (TOKEN_NO) 9 | ); 10 | 11 | CREATE INDEX SPRING_SESSION_IX1 ON SPRING_SESSION (LAST_ACCESS_TIME); 12 | CREATE INDEX SPRING_SESSION_IX2 ON SPRING_SESSION (USER_CODE); 13 | -------------------------------------------------------------------------------- /framework-core/src/main/java/com/centit/framework/core/aop/NoRepeatCommit.java: -------------------------------------------------------------------------------- 1 | package com.centit.framework.core.aop; 2 | 3 | import java.lang.annotation.*; 4 | 5 | /** 6 | * @desc 定义一个不重复提交的注解 7 | */ 8 | //@Target({ElementType.PARAMETER, ElementType.METHOD}) 9 | @Target(ElementType.METHOD) 10 | @Retention(RetentionPolicy.RUNTIME) 11 | @Documented 12 | public @interface NoRepeatCommit { 13 | /** 14 | * 延时时间 在延时多久后可以再次提交 15 | * 16 | * @return Time unit is one second 17 | */ 18 | int delaySeconds() default 20; 19 | } 20 | -------------------------------------------------------------------------------- /framework-config/src/main/java/com/centit/framework/config/SystemSpringMvcConfig.java: -------------------------------------------------------------------------------- 1 | package com.centit.framework.config; 2 | 3 | import org.springframework.context.annotation.ComponentScan; 4 | 5 | /** 6 | * Created by zou_wy on 2017/3/29. 7 | */ 8 | @ComponentScan(basePackages = {"com.centit.framework.**.controller"}, 9 | includeFilters = {@ComponentScan.Filter(value= org.springframework.stereotype.Controller.class)}, 10 | useDefaultFilters = false) 11 | public class SystemSpringMvcConfig extends BaseSpringMvcConfig { 12 | 13 | } 14 | -------------------------------------------------------------------------------- /framework-core/src/main/java/com/centit/framework/core/controller/WrapUpContentType.java: -------------------------------------------------------------------------------- 1 | package com.centit.framework.core.controller; 2 | 3 | /** 4 | * 包装器内容类别 5 | */ 6 | public enum WrapUpContentType { 7 | DATA, // json data,默认属性,返回json格式的数据 8 | RAW, // 返回函数返回值的元素数据,如果不是String类型,转换为String类型,非标量类型转换为json, 等价于 @RespondBody 9 | JAVASCRIPT, // 返回脚本 10 | IMAGE, // 返回图片流 11 | XML, //将对象转换为xml返回 12 | HTML, // 返回html文本 13 | FILE, // 返回文件流 14 | MAP_DICT, // 将对象中的 DictionaryMap 注解 映射为 对应的字段添加到json 15 | BASE64 // 对data部分进行 base64 编码 16 | } 17 | -------------------------------------------------------------------------------- /framework-security/src/test/java/com/centit/framework/security/TestUrl.java: -------------------------------------------------------------------------------- 1 | package com.centit.framework.security; 2 | 3 | public class TestUrl { 4 | public static void main(String[] args) { 5 | System.out.println(CentitSecurityMetadata.parseUrlToApi("/dde/run/D12341234?w34")); 6 | System.out.println(CentitSecurityMetadata.parseUrlToApi("/dde/run/draft/D12341234?w34")); 7 | System.out.println(CentitSecurityMetadata.parseUrlToApi("/dde/run/D12341234")); 8 | System.out.println(CentitSecurityMetadata.parseUrlToApi("/dde/run/draft/D1234123f")); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | root = true 3 | [*.html] 4 | indent_style = space 5 | indent_size = 2 6 | end_of_line = lf 7 | charset = utf-8 8 | trim_trailing_whitespace = true 9 | insert_final_newline = true 10 | [*.js] 11 | indent_style = space 12 | indent_size = 2 13 | end_of_line = lf 14 | charset = utf-8 15 | trim_trailing_whitespace = true 16 | insert_final_newline = true 17 | [*.java] 18 | indent_style = space 19 | indent_size = 4 20 | end_of_line = lf 21 | charset = utf-8 22 | trim_trailing_whitespace = true 23 | insert_final_newline = true 24 | [*.md] 25 | trim_trailing_whitespace = false 26 | -------------------------------------------------------------------------------- /framework-adapter/src/main/java/com/centit/framework/model/security/ThirdPartyCheckUserDetails.java: -------------------------------------------------------------------------------- 1 | package com.centit.framework.model.security; 2 | 3 | import com.alibaba.fastjson2.JSONObject; 4 | import com.centit.framework.model.adapter.PlatformEnvironment; 5 | 6 | /** 7 | * 用户和第三方验证对接 8 | */ 9 | public interface ThirdPartyCheckUserDetails { 10 | /** 11 | * 验证成功返回用户对象,失败返回null,或者抛ObjectException 12 | * @param platformEnvironment 环境 13 | * @param token 验证参数 14 | * @return 用户对象 15 | */ 16 | CentitUserDetails check(PlatformEnvironment platformEnvironment, JSONObject token); 17 | } 18 | -------------------------------------------------------------------------------- /framework-config/src/main/java/com/centit/framework/config/SecurityCasCondition.java: -------------------------------------------------------------------------------- 1 | package com.centit.framework.config; 2 | 3 | import com.centit.support.algorithm.StringRegularOpt; 4 | import org.springframework.context.annotation.Condition; 5 | import org.springframework.context.annotation.ConditionContext; 6 | import org.springframework.core.type.AnnotatedTypeMetadata; 7 | 8 | /** 9 | * Created by zou_wy on 2017/4/18. 10 | */ 11 | public class SecurityCasCondition implements Condition { 12 | @Override 13 | public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { 14 | return StringRegularOpt.isTrue(context.getEnvironment().getProperty("login.cas.enable")); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /framework-config/src/main/java/com/centit/framework/config/SecurityDaoCondition.java: -------------------------------------------------------------------------------- 1 | package com.centit.framework.config; 2 | 3 | import com.centit.support.algorithm.StringRegularOpt; 4 | import org.springframework.context.annotation.Condition; 5 | import org.springframework.context.annotation.ConditionContext; 6 | import org.springframework.core.type.AnnotatedTypeMetadata; 7 | 8 | /** 9 | * Created by zou_wy on 2017/4/18. 10 | */ 11 | public class SecurityDaoCondition implements Condition { 12 | 13 | @Override 14 | public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { 15 | return StringRegularOpt.isTrue(context.getEnvironment().getProperty("login.dao.enable")); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /framework-adapter/src/main/java/com/centit/framework/model/adapter/README.md: -------------------------------------------------------------------------------- 1 | # 框架基础服务接口 2 | 3 | 框架基础服务通过接口和实现分离的方式,将开发的使用和事项分离,开发可以面向接口编程。 4 | 5 | adapter 包的目的就是将接口抽象出来,业务或者其他服务可以针对这些接口编写自己的实现然后通过配置文件注入到系统。 6 | 7 | ## 消息通知接口 8 | 9 | 1. MessageSender实现了消息发送 10 | 2. NotificationCenter 通知中心接口,它根据用户设定的接受消息的方式向用户发送通知。 11 | 12 | ## 操作日志接口 13 | 14 | 1. OperationLog 定义了日志的记录内容。 15 | 2. OperationLogWriter 定义日志写入接口。 16 | 17 | 日志的具体写入操作参见[日志写入操作](https://github.com/ndxt/centit-framework/tree/master/framework-core/src/main/java/com/centit/framework/operationlog)。 18 | 19 | ## 接口的实现 20 | 21 | [代码components/impl](https://github.com/ndxt/centit-framework/tree/master/framework-core/src/main/java/com/centit/framework/components/impl)中提供了接口多种默认实现。 -------------------------------------------------------------------------------- /framework-core/src/main/java/com/centit/framework/core/controller/DatePropertiesEditor.java: -------------------------------------------------------------------------------- 1 | package com.centit.framework.core.controller; 2 | 3 | import com.centit.support.algorithm.DatetimeOpt; 4 | import org.apache.commons.lang3.StringUtils; 5 | import org.springframework.beans.propertyeditors.PropertiesEditor; 6 | 7 | import java.util.Date; 8 | 9 | public class DatePropertiesEditor extends PropertiesEditor { 10 | 11 | @Override 12 | public void setAsText(String text) throws IllegalArgumentException { 13 | if (StringUtils.isBlank(text)) { 14 | super.setValue(null); 15 | } else { 16 | Date value = DatetimeOpt.smartPraseDate(text); 17 | setValue(value); 18 | } 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /framework-core/src/main/java/com/centit/framework/components/impl/DummyMessageSenderImpl.java: -------------------------------------------------------------------------------- 1 | package com.centit.framework.components.impl; 2 | 3 | import com.centit.framework.common.ResponseData; 4 | import com.centit.framework.model.adapter.MessageSender; 5 | import com.centit.framework.model.basedata.NoticeMessage; 6 | 7 | /** 8 | * Created by codefan on 17-7-24. 9 | */ 10 | public class DummyMessageSenderImpl implements MessageSender{ 11 | private DummyMessageSenderImpl(){ 12 | 13 | } 14 | public final static DummyMessageSenderImpl instance = new DummyMessageSenderImpl(); 15 | 16 | @Override 17 | public ResponseData sendMessage(String sender, String receiver, NoticeMessage message) { 18 | return ResponseData.successResponse; 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /framework-core/src/main/java/com/centit/framework/core/controller/SqlDatePropertiesEditor.java: -------------------------------------------------------------------------------- 1 | package com.centit.framework.core.controller; 2 | 3 | import com.centit.support.algorithm.DatetimeOpt; 4 | import org.apache.commons.lang3.StringUtils; 5 | import org.springframework.beans.propertyeditors.PropertiesEditor; 6 | 7 | import java.sql.Date; 8 | 9 | public class SqlDatePropertiesEditor extends PropertiesEditor { 10 | 11 | @Override 12 | public void setAsText(String text) throws IllegalArgumentException { 13 | if (StringUtils.isBlank(text)) { 14 | super.setValue(null); 15 | } else { 16 | Date value = DatetimeOpt.convertToSqlDate( 17 | DatetimeOpt.smartPraseDate(text)); 18 | setValue(value); 19 | } 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /framework-core-web/src/main/resources/ExtendedSqlMap.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | ]> 7 | 8 | 9 | 18 | 19 | -------------------------------------------------------------------------------- /framework-adapter/src/main/java/com/centit/framework/model/adapter/OperationLogWriter.java: -------------------------------------------------------------------------------- 1 | package com.centit.framework.model.adapter; 2 | 3 | import com.centit.framework.model.basedata.OperationLog; 4 | 5 | import java.util.List; 6 | import java.util.Map; 7 | 8 | /** 9 | * 10 | * 操作日志持久化接口,可以单独写入一个日志,和批量写入一个数组 11 | * 12 | * @author codefan 13 | * /@create 2015年10月14日 14 | * /@version 15 | */ 16 | //默认不支持日志的查询操作 17 | public interface OperationLogWriter { 18 | 19 | void save(OperationLog optLog); 20 | 21 | void save(List optLogs); 22 | 23 | default List 24 | listOptLog(String optId, Map filterMap, int startPos, int maxRows){ 25 | return null; 26 | } 27 | 28 | default int 29 | countOptLog(String optId, Map filter){ 30 | return 0; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /framework-session-core/src/main/java/com/centit/framework/session/FrameworkHttpSessionConfiguration.java: -------------------------------------------------------------------------------- 1 | package com.centit.framework.session; 2 | 3 | import org.springframework.beans.factory.annotation.Value; 4 | import org.springframework.context.annotation.Bean; 5 | import org.springframework.context.annotation.Configuration; 6 | 7 | @Configuration 8 | public class FrameworkHttpSessionConfiguration { 9 | 10 | @Value("${session.strategy.cookie.first:false}") 11 | private boolean cookieFist; 12 | @Value("${session.strategy.cookie.path:/}") 13 | private String cookiePath; 14 | @Value("${session.strategy.addAccessToken:true}") 15 | private boolean addAccessToken; 16 | 17 | @Bean 18 | public SmartHttpSessionResolver httpSessionIdResolver(){ 19 | return new SmartHttpSessionResolver(cookieFist, cookiePath, addAccessToken); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /framework-session-core/src/main/java/com/centit/framework/session/FrameworkSessionApplicationInitializer.java: -------------------------------------------------------------------------------- 1 | package com.centit.framework.session; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | import org.springframework.session.web.context.AbstractHttpSessionApplicationInitializer; 6 | 7 | import javax.servlet.ServletContext; 8 | 9 | public class FrameworkSessionApplicationInitializer extends AbstractHttpSessionApplicationInitializer { 10 | Logger logger = LoggerFactory.getLogger(FrameworkSessionApplicationInitializer.class); 11 | 12 | @Override 13 | protected void beforeSessionRepositoryFilter(ServletContext servletContext) { 14 | logger.debug("初始化spring session 过滤器"); 15 | } 16 | 17 | @Override 18 | protected void afterSessionRepositoryFilter(ServletContext servletContext) { 19 | logger.debug("spring session 过滤器启动完成"); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /framework-core/src/main/java/com/centit/framework/core/controller/SqlTimestampPropertiesEditor.java: -------------------------------------------------------------------------------- 1 | package com.centit.framework.core.controller; 2 | 3 | import com.centit.support.algorithm.DatetimeOpt; 4 | import org.apache.commons.lang3.StringUtils; 5 | import org.springframework.beans.propertyeditors.PropertiesEditor; 6 | 7 | import java.sql.Timestamp; 8 | import java.util.Date; 9 | 10 | public class SqlTimestampPropertiesEditor extends PropertiesEditor { 11 | 12 | @Override 13 | public void setAsText(String text) throws IllegalArgumentException { 14 | if (StringUtils.isBlank(text)) { 15 | super.setValue(null); 16 | } else { 17 | Date dt = DatetimeOpt.smartPraseDate(text); 18 | if(dt!=null){ 19 | Timestamp value = new Timestamp(dt.getTime() ); 20 | setValue(value); 21 | }else 22 | setValue(null); 23 | } 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /framework-core/src/main/java/com/centit/framework/filter/RequestThreadLocal.java: -------------------------------------------------------------------------------- 1 | package com.centit.framework.filter; 2 | 3 | import javax.servlet.http.HttpServletRequest; 4 | 5 | /** 6 | * 将HttpServletRequest请求与本地线程绑定,方便在非Controller层获取HttpServletRequest实例 7 | * 8 | * @author sx 9 | * 2014-10-14 10 | */ 11 | public abstract class RequestThreadLocal { 12 | private static ThreadLocal threadLocal = new ThreadLocal<>(); 13 | 14 | public static void setHttpThreadWrapper(HttpThreadWrapper wrapper) { 15 | threadLocal.set(wrapper); 16 | } 17 | 18 | public static HttpThreadWrapper getHttpThreadWrapper() { 19 | return threadLocal.get(); 20 | } 21 | 22 | public static HttpServletRequest getLocalThreadWrapperRequest(){ 23 | HttpThreadWrapper localThread = threadLocal.get(); 24 | if(localThread != null) { 25 | return localThread.getRequest(); 26 | } 27 | return null; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /framework-core/src/test/java/com/centit/framework/test/TestI18n.java: -------------------------------------------------------------------------------- 1 | package com.centit.framework.test; 2 | import java.util.Locale; 3 | import java.util.ResourceBundle; 4 | 5 | public class TestI18n { 6 | 7 | private static void printMessage(String msg, Object... args){ 8 | System.out.println(msg); 9 | if(args!=null){ 10 | for(Object obj : args){ 11 | System.out.println(obj); 12 | } 13 | } 14 | } 15 | 16 | public static void main(String[] args) { 17 | Object obj = new Object[]{"begin", "end"}; 18 | printMessage("hello", (Object[])obj); 19 | ResourceBundle zhMessages = ResourceBundle.getBundle("i18n/messages", Locale.SIMPLIFIED_CHINESE); 20 | System.out.println(zhMessages.getString("greeting")); 21 | ResourceBundle enMessages = ResourceBundle.getBundle("i18n/messages", Locale.US); 22 | System.out.println(enMessages.getString("greeting")); 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /framework-adapter/src/main/java/com/centit/framework/model/adapter/UserUnitVariableTranslate.java: -------------------------------------------------------------------------------- 1 | package com.centit.framework.model.adapter; 2 | 3 | import com.centit.support.compiler.VariableTranslate; 4 | 5 | import java.util.Set; 6 | 7 | public interface UserUnitVariableTranslate extends VariableTranslate { 8 | 9 | 10 | /** 11 | * 返回权限表达式中的自定义变量对应的用户组 12 | * 13 | * @param varName 自定义变量 14 | * @return Set 权限表达式中的自定义变量对应的用户组 15 | */ 16 | Set getUsersVariable(String varName); 17 | 18 | /** 19 | * 返回机构表达式中的自定义变量对应的机构组 20 | * 21 | * @param varName 自定义变量 22 | * @return Set 返回机构表达式中的自定义变量对应的机构组 23 | */ 24 | Set getUnitsVariable(String varName); 25 | 26 | /*变量名--变量值的转变 保持历史版本兼容 27 | *变量 是用 ${变量名} 28 | *如果这个变量不存在,返回空字符串 "''" 29 | * @param varName 自定义变量 30 | * @return Object 31 | */ 32 | /*default Object getGeneralVariable(String varName){ 33 | return getVarValue(varName); 34 | }*/ 35 | 36 | } 37 | -------------------------------------------------------------------------------- /framework-core/src/main/java/com/centit/framework/filter/HttpThreadWrapper.java: -------------------------------------------------------------------------------- 1 | package com.centit.framework.filter; 2 | 3 | import javax.servlet.http.HttpServletRequest; 4 | import javax.servlet.http.HttpServletResponse; 5 | import java.io.Serializable; 6 | 7 | /** 8 | * 在ThreadLocal中封装请求响应 9 | * 10 | * @author sx 11 | * 2014-10-20 12 | */ 13 | public class HttpThreadWrapper implements Serializable { 14 | /** 15 | * 16 | */ 17 | private static final long serialVersionUID = 3434170518095254917L; 18 | 19 | private HttpServletRequest request; 20 | 21 | private HttpServletResponse response; 22 | 23 | public HttpThreadWrapper(HttpServletRequest request, HttpServletResponse response) { 24 | super(); 25 | this.request = request; 26 | this.response = response; 27 | } 28 | 29 | public HttpServletRequest getRequest() { 30 | return request; 31 | } 32 | 33 | public HttpServletResponse getResponse() { 34 | return response; 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /framework-adapter/src/test/java/com/centit/framework/test/TestHttpReceiveJSON.java: -------------------------------------------------------------------------------- 1 | package com.centit.framework.test; 2 | 3 | import com.centit.framework.appclient.HttpReceiveJSON; 4 | import com.centit.support.json.JSONOpt; 5 | 6 | public class TestHttpReceiveJSON { 7 | public static void main(String[] args) { 8 | JSONOpt.fastjsonGlobalConfig(); 9 | String obj = "{code:200,message:\"Hello World!\", callback:\"recall\", data: 200}"; 10 | HttpReceiveJSON receiveJSON = HttpReceiveJSON.valueOfJson("500"); 11 | System.out.println(receiveJSON.toResponseData().toJSONString()); 12 | receiveJSON = HttpReceiveJSON.dataOfJson("Hello World!"); 13 | System.out.println(receiveJSON.toResponseData().toJSONString()); 14 | receiveJSON = HttpReceiveJSON.valueOfJson(obj); 15 | System.out.println(receiveJSON.toResponseData().toJSONString()); 16 | receiveJSON = HttpReceiveJSON.dataOfJson(obj); 17 | System.out.println(receiveJSON.toResponseData().toJSONString()); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /framework-adapter/src/main/java/com/centit/framework/model/basedata/FVUserRolesId.java: -------------------------------------------------------------------------------- 1 | package com.centit.framework.model.basedata; 2 | 3 | import javax.persistence.Column; 4 | import javax.persistence.Embeddable; 5 | import java.io.Serializable; 6 | 7 | @Embeddable 8 | public class FVUserRolesId implements Serializable { 9 | /** 10 | * 11 | */ 12 | private static final long serialVersionUID = -7725372179862779056L; 13 | 14 | /** 15 | * 用户代码 16 | */ 17 | @Column(name = "USER_CODE") 18 | private String userCode; 19 | 20 | /** 21 | * 角色代码 22 | */ 23 | @Column(name = "ROLE_CODE") 24 | private String roleCode; // 25 | 26 | public String getUserCode() { 27 | return userCode; 28 | } 29 | 30 | public void setUserCode(String userCode) { 31 | this.userCode = userCode; 32 | } 33 | 34 | public String getRoleCode() { 35 | return roleCode; 36 | } 37 | 38 | public void setRoleCode(String roleCode) { 39 | this.roleCode = roleCode; 40 | } 41 | 42 | 43 | } 44 | -------------------------------------------------------------------------------- /framework-filter/src/main/java/com/centit/framework/filter/XFrameOptionsFilter.java: -------------------------------------------------------------------------------- 1 | package com.centit.framework.filter; 2 | 3 | 4 | import javax.servlet.*; 5 | import javax.servlet.http.HttpServletResponse; 6 | import java.io.IOException; 7 | 8 | public class XFrameOptionsFilter implements Filter { 9 | 10 | 11 | @Override 12 | public void init(FilterConfig filterConfig) throws ServletException { 13 | 14 | } 15 | 16 | 17 | @Override 18 | public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { 19 | if (response instanceof HttpServletResponse) { 20 | //必须 21 | //HttpServletRequest httpRequest = (HttpServletRequest) request; 22 | HttpServletResponse httpRponse = (HttpServletResponse) response; 23 | //实际设置 24 | httpRponse.setHeader("x-frame-options", "SAMEORIGIN"); 25 | } 26 | //调用下一个过滤器(这是过滤器工作原理,不用动) 27 | chain.doFilter(request, response); 28 | 29 | } 30 | 31 | 32 | @Override 33 | public void destroy() { 34 | 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /framework-core/src/main/java/com/centit/framework/components/impl/Log4jOperationLogWriterImpl.java: -------------------------------------------------------------------------------- 1 | package com.centit.framework.components.impl; 2 | 3 | import com.centit.framework.model.adapter.OperationLogWriter; 4 | import com.centit.framework.model.basedata.OperationLog; 5 | import org.slf4j.Logger; 6 | import org.slf4j.LoggerFactory; 7 | 8 | import java.util.List; 9 | 10 | /** 11 | * 配置日志级别为log 12 | * <category name="com.centit.framework.components.impl.Log4jOperationLogWriterImpl"> 13 | * <priority value="info"/> 14 | * <appender-ref ref="appender-info"/> 15 | * </category> 16 | */ 17 | @SuppressWarnings("unused") 18 | public class Log4jOperationLogWriterImpl implements OperationLogWriter{ 19 | 20 | protected Logger logger = LoggerFactory.getLogger(Log4jOperationLogWriterImpl.class); 21 | 22 | @Override 23 | public void save(OperationLog optLog) { 24 | logger.info(optLog.toString()); 25 | } 26 | 27 | @Override 28 | public void save(List optLogs) { 29 | for(OperationLog optLog : optLogs) 30 | logger.info(optLog.toString()); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /framework-adapter/src/main/java/com/centit/framework/core/dao/DictionaryMap.java: -------------------------------------------------------------------------------- 1 | package com.centit.framework.core.dao; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | /** 9 | * 方法 HibernateOptUtils.listObjectsAsJson 配合这个查询工作 10 | * @author codefan 11 | * 2015年12月16日 12 | */ 13 | @Target({ElementType.FIELD, ElementType.METHOD}) 14 | @Retention(RetentionPolicy.RUNTIME) 15 | public @interface DictionaryMap { 16 | /** 17 | * (Must be assigned) The catalog code of the dictionary . 18 | * Defaults to the default catalog code. 19 | * 对应的数据字典的目录代码。 20 | * @return String value 21 | */ 22 | String [] value() default {}; 23 | 24 | /** 25 | * (Must be assigned) The name of the Field Name. 26 | * Defaults to the field name. 27 | * 数字字典值对应的字段名 28 | * @return String fieldName 29 | */ 30 | String [] fieldName() default {}; 31 | 32 | /** 33 | * 是否作为表达式解释,可能有多个字典数据 34 | * @return isExpress 35 | */ 36 | boolean isExpression() default false; 37 | } 38 | -------------------------------------------------------------------------------- /framework-core/src/main/java/com/centit/framework/filter/RequestThreadLocalFilter.java: -------------------------------------------------------------------------------- 1 | package com.centit.framework.filter; 2 | 3 | import javax.servlet.*; 4 | import javax.servlet.http.HttpServletRequest; 5 | import javax.servlet.http.HttpServletResponse; 6 | import java.io.IOException; 7 | 8 | /** 9 | * 将HttpServletRequest请求与本地线程绑定,方便在非Controller层获取HttpServletRequest实例 10 | * 11 | * @author sx 12 | * 2014-10-14 13 | */ 14 | public class RequestThreadLocalFilter implements Filter { 15 | 16 | @Override 17 | public void init(FilterConfig filterConfig) throws ServletException { 18 | 19 | } 20 | 21 | @Override 22 | public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, 23 | ServletException { 24 | if(request!=null && response!=null) { 25 | RequestThreadLocal.setHttpThreadWrapper( 26 | new HttpThreadWrapper((HttpServletRequest) request, (HttpServletResponse) response)); 27 | if(chain!=null) { 28 | chain.doFilter(request, response); 29 | } 30 | } 31 | } 32 | 33 | @Override 34 | public void destroy() { 35 | 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /framework-session-redis/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | framework-parent 7 | com.centit.framework 8 | ${revision} 9 | 10 | 4.0.0 11 | 12 | framework-session-redis 13 | 14 | 15 | 16 | com.centit.framework 17 | framework-session-core 18 | ${project.version} 19 | 20 | 21 | 22 | org.springframework.session 23 | spring-session-data-redis 24 | 25 | 26 | 27 | io.lettuce 28 | lettuce-core 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /centit-persistence-extend/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | framework-parent 7 | com.centit.framework 8 | ${revision} 9 | 10 | 4.0.0 11 | 12 | centit-persistence-extend 13 | com.centit.framework:centit-persistence-extend 14 | jar 15 | 数据范围权限管理、数据分页查询返回值等等 16 | 17 | 18 | 19 | com.centit.support 20 | centit-database 21 | ${project.version} 22 | 23 | 24 | 25 | com.centit.framework 26 | framework-core 27 | ${project.version} 28 | provided 29 | true 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /framework-filter/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | framework-parent 7 | com.centit.framework 8 | ${revision} 9 | 10 | 4.0.0 11 | 12 | framework-filter 13 | com.centit.framework:framework-filter 14 | jar 15 | 框架过滤器配置类 16 | 17 | 18 | 19 | com.centit.framework 20 | framework-core 21 | ${project.version} 22 | provided 23 | 24 | 25 | 26 | org.dom4j 27 | dom4j 28 | 29 | 30 | 31 | javax.servlet 32 | javax.servlet-api 33 | provided 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /framework-core/src/test/java/com/centit/framework/test/TestRefection.java: -------------------------------------------------------------------------------- 1 | package com.centit.framework.test; 2 | 3 | import com.centit.framework.components.impl.NotificationCenterImpl; 4 | import org.springframework.core.ParameterNameDiscoverer; 5 | import org.springframework.core.StandardReflectionParameterNameDiscoverer; 6 | 7 | import java.lang.reflect.Method; 8 | import java.lang.reflect.Parameter; 9 | 10 | /** 11 | * Created by codefan on 17-6-29. 12 | */ 13 | public class TestRefection { 14 | public static void main(String[] args) { 15 | //System.out.println(CodeRepositoryUtil.getSysConfigValue("server.path")); 16 | ParameterNameDiscoverer pd = new StandardReflectionParameterNameDiscoverer(); 17 | Method[] mths = NotificationCenterImpl.class.getMethods(); 18 | for (Method mth : mths) { 19 | System.out.println(mth.getName()); 20 | String[] names = pd.getParameterNames(mth); 21 | if(names!=null) { 22 | for (String name : names) { 23 | System.out.print("\t" + name); 24 | } 25 | System.out.println(); 26 | } 27 | 28 | Parameter[] params = mth.getParameters(); 29 | for(Parameter param : params){ 30 | System.out.print("\t" + param.getName()); 31 | } 32 | System.out.println(); 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /framework-security/README.md: -------------------------------------------------------------------------------- 1 | # 框架安全机制 2 | 3 | 框架采用[Spring security](https://docs.spring.io/spring-security/site/docs/current/guides/html5/)安全框架,实行身份验证和权限过滤。 4 | 5 | ## 身份验证 6 | 7 | 框架提供两种方式的身份验证:本地认证和基于cas的单点登录认证。 8 | 9 | ### 本地认证 10 | 11 | spring security 提供了多中认证方式,我们一般采用用户名和密码的方式认证。spring 框架中有两种密码认证方式: 12 | 1. org.springframework.security.crypto.password.PasswordEncoder 13 | 14 | Spring推荐的验证方式BCryptPasswordEncoder就是实现了这个接口,其加密盐是随机的并编码在密码中。我们框架中默认的加密方式StandardPasswordEncoderImpl也是采用的这个加密算法。 15 | 16 | 2. org.springframework.security.authentication.encoding.PasswordEncoder 17 | 18 | 这个加密方式是可以自定义加密盐的,CentitPasswordEncoderImpl就实现了这个接口,加密算法和BCryptPasswordEncoder一样,只是添加了自定义盐,我认为这个更好,这样不同的人的密码是不通用的。 19 | 20 | 本地验证也通过SpringSecurityDaoConfig类来配置。 21 | 22 | ### 单点登录 23 | 24 | centit-cas在[apereo cas](https://www.apereo.org/projects/cas)的基础上开发了一套验证界面和验证方式的插件。可以无缝的和框架对接。 25 | 26 | 通过SpringSecurityCasConfig类来配置。 27 | 28 | ## 权限过滤 29 | 30 | 框架的功能权限模型参见[权限体系](https://ndxt.github.io/system_design/concept_design.html#%E6%9D%83%E9%99%90%E4%BD%93%E7%B3%BB)。 31 | 32 | 33 | 功能权限通过[Spring security](https://docs.spring.io/spring-security/site/docs/current/guides/html5/)的过滤器实现,过滤器将请求url映射到optCode,通过角色信息查找用于这个optCode所有角色,然后对比当前用户是否具有其中的一个,如果有就通过,否则提示401。 34 | 35 | 1. DaoFilterSecurityInterceptor 负责过滤器的执行,在执行获取用户的session。 36 | 2. DaoInvocationSecurityMetadataSource 复制将url映射到业务操作,并查找对应的角色集合。 37 | 3. DaoAccessDecisionManager 判断用户是否有权限访问资源。 -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 框架基础平台 2 | 3 | 框架基于前后端分离的理念开发,采用Spring作为后端开发框架,EasyUI、Vue作为前段框架。详情参见[框架技术路线](https://ndxt.github.io/system_design/technical_design.html)。 4 | 5 | ## 框架各模块介绍 6 | 7 | 1. framework-adapter 将框提供的架基础服务抽象为接口,便于业务开发特定的实现,同时定义前后端数据交换格式。参见[framework-adapter/common](./framework-adapter/src/main/java/com/centit/framework/common)。 8 | 2. framework-core 框架的核心组件,包括工具类,用户、机构、权限等模型的数据抽象。平台运行依赖的数据接口(PlatformEnvironment)抽象等等。 9 | 3. framework-security 框架基于spring security实现安全框架,这个类将spring security与平台数据模型整合。 10 | 4. framework-filter 一组通用的过滤器,业务系统可以选择使用。 11 | 5. framework-config 框架的配置类。进一步了解参见[启动与配置空间](https://ndxt.github.io/system_design/product_design.html#%E5%90%AF%E5%8A%A8%E4%B8%8E%E9%85%8D%E7%BD%AE%E7%A9%BA%E9%97%B4)。 12 | 6. framework-core-web 框架提供的基础服务,如:登录、数据字典服务等等。 13 | 7. framework-system-static 框架平台接口PlatformEnvironment一个基于json数据的静态(不能修改)实现。 14 | 8. framework-system-static-jdbc 框架平台接口PlatformEnvironment一个基于jdbc数据的静态实现。 15 | 9. framework-system-static-config 框架静态bean配置类。 16 | 10. framework-web-demo 一个使用框架的示例。 17 | 18 | ## 快速入门 19 | 20 | framework-web-demo模块是使用框架的最简示例。基于框架开发的项目可以直接复制demo中代码到自己的项目中。这个demo代码包括一下内容: 21 | 22 | 1. pom.xml 框架依赖的包。 23 | 2. 配置内在config包中。由于框架采用的spring 4.x 所以框架web项目没有web.xml配置信息,全部采用配置类的方式配置。 24 | 3. resources中的 system.properties 配置信息。 25 | 4. webapp中的jsp页面。 26 | 27 | webapp这部分其实不是必须的,根据框架前后端分离设计原则也是不需要的,只是为了快速启动而设置的跳转页面。同样在pom.xml中的framework-base-view-easyui依赖包也是不需要的,这个包是前段代码,应该解压出来放在静态服务器上比如:nginx。 -------------------------------------------------------------------------------- /framework-core-web/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | framework-parent 7 | com.centit.framework 8 | ${revision} 9 | 10 | 4.0.0 11 | 12 | framework-core-web 13 | com.centit.framework:framework-core-web 14 | jar 15 | 用户验证接口,缓存接口 16 | 17 | 18 | 19 | com.centit.framework 20 | framework-core 21 | ${project.version} 22 | 23 | 24 | 25 | io.swagger 26 | swagger-annotations 27 | provided 28 | 29 | 30 | 31 | javax.servlet 32 | javax.servlet-api 33 | provided 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /framework-adapter/src/main/java/com/centit/framework/common/ImmutableResponseData.java: -------------------------------------------------------------------------------- 1 | package com.centit.framework.common; 2 | 3 | public class ImmutableResponseData implements ResponseData{ 4 | 5 | private static final long serialVersionUID = 1L; 6 | /** 7 | * 返回代码,0 表示正确,其他的为错误代码 8 | */ 9 | private int code; 10 | 11 | /** 12 | * 返回消息提示 ,code为0时是提示,其他为 错误提示 13 | */ 14 | private String message; 15 | 16 | /** 17 | * 返回的详细数据, 可能是需要回显的参数,也可能是验证的错误提示 18 | */ 19 | protected Object data; 20 | 21 | public ImmutableResponseData() { 22 | this.code = RESULT_OK; 23 | this.message = "OK"; 24 | } 25 | 26 | public ImmutableResponseData(int nCode, String message) { 27 | this.code = nCode; 28 | this.message = message; 29 | } 30 | 31 | public ImmutableResponseData(int nCode, String message, Object data) { 32 | this.code = nCode; 33 | this.message = message; 34 | this.data = data; 35 | } 36 | 37 | @Override 38 | public int getCode() { 39 | return this.code; 40 | } 41 | 42 | @Override 43 | public String getMessage() { 44 | return this.message; 45 | } 46 | 47 | @Override 48 | public Object getData() { 49 | return this.data; 50 | } 51 | 52 | @Override 53 | public String toString(){ 54 | return toJSONString(); 55 | } 56 | 57 | } 58 | -------------------------------------------------------------------------------- /framework-adapter/src/main/java/com/centit/framework/appclient/PooledHttpClientFactory.java: -------------------------------------------------------------------------------- 1 | package com.centit.framework.appclient; 2 | 3 | import com.centit.support.network.HttpExecutor; 4 | import org.apache.commons.pool2.PooledObject; 5 | import org.apache.commons.pool2.PooledObjectFactory; 6 | import org.apache.commons.pool2.impl.DefaultPooledObject; 7 | import org.apache.http.impl.client.CloseableHttpClient; 8 | 9 | public class PooledHttpClientFactory implements PooledObjectFactory{ 10 | 11 | @Override 12 | public PooledObject makeObject() throws Exception { 13 | CloseableHttpClient httpClient = HttpExecutor.createKeepSessionHttpClient(); 14 | return new DefaultPooledObject<>(httpClient); 15 | } 16 | 17 | @Override 18 | public void destroyObject(PooledObject p) throws Exception { 19 | p.getObject().close(); 20 | } 21 | 22 | @Override 23 | public boolean validateObject(PooledObject p) { 24 | // TODO Auto-generated method stub 25 | return true; 26 | } 27 | 28 | @Override 29 | public void activateObject(PooledObject p) throws Exception { 30 | // TODO Auto-generated method stub 31 | } 32 | 33 | @Override 34 | public void passivateObject(PooledObject p) throws Exception { 35 | // TODO Auto-generated method stub 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /framework-adapter/src/main/java/com/centit/framework/model/security/SimpleGrantedAuthority.java: -------------------------------------------------------------------------------- 1 | package com.centit.framework.model.security; 2 | 3 | import org.springframework.security.core.GrantedAuthority; 4 | import org.springframework.security.core.SpringSecurityCoreVersion; 5 | import org.springframework.util.Assert; 6 | 7 | 8 | public final class SimpleGrantedAuthority implements GrantedAuthority { 9 | 10 | private static final long serialVersionUID = SpringSecurityCoreVersion.SERIAL_VERSION_UID; 11 | 12 | private final String role; 13 | 14 | public SimpleGrantedAuthority() { 15 | role=""; 16 | } 17 | public SimpleGrantedAuthority(String role) { 18 | Assert.hasText(role, "A granted authority textual representation is required"); 19 | this.role = role; 20 | } 21 | 22 | @Override 23 | public String getAuthority() { 24 | return role; 25 | } 26 | 27 | @Override 28 | public boolean equals(Object obj) { 29 | if (this == obj) { 30 | return true; 31 | } 32 | 33 | if (obj instanceof SimpleGrantedAuthority) { 34 | return role.equals(((SimpleGrantedAuthority)obj).role); 35 | } 36 | 37 | return false; 38 | } 39 | 40 | @Override 41 | public int hashCode() { 42 | return this.role.hashCode(); 43 | } 44 | 45 | @Override 46 | public String toString() { 47 | return this.role; 48 | } 49 | } 50 | 51 | -------------------------------------------------------------------------------- /framework-core/src/main/java/com/centit/framework/operationlog/README.md: -------------------------------------------------------------------------------- 1 | # 日志写入服务 2 | 3 | 框架提供两种方式记录操作日志。 4 | 5 | ## 注解方式 RecordOperationLog 6 | 7 | 通过在controller类的方法上添加 RecordOperationLog 注解记录日志。 8 | 1. 注解中的 content 是一个日志内容模板。模板中可以用{}嵌入方法的参数或者参数的属性。第一个参数为arg0,第二个为org1以此类推。 9 | 2. timing 表示是否记录方法的执行时间。 10 | 3. appendRequest 表示是否要把request中的参数记录到日志中。 11 | 12 | ## 直接调用 OperationLogCenter 13 | 14 | 这个工具类可以直接调用日志记录接口写入用户自定义的日志信息。参见[日志写入接口](https://github.com/ndxt/centit-framework/tree/master/framework-adapter/src/main/java/com/centit/framework/model/adapter)。 15 | 16 | ## 日志记录接口注入 17 | 18 | ```java 19 | /** 20 | * Created by codefan on 17-7-6. 21 | * 需要在配置类中创建这个 Bean 才能是日志生效 22 | */ 23 | public class InstantiationServiceBeanPostProcessor implements ApplicationListener 24 | { 25 | 26 | @Autowired 27 | private OperationLogWriter optLogManager; 28 | 29 | @Override 30 | public void onApplicationEvent(ContextRefreshedEvent event){ 31 | if(optLogManager!=null) { 32 | OperationLogCenter.registerOperationLogWriter(optLogManager); 33 | } 34 | //...... 35 | } 36 | 37 | } 38 | 39 | ``` 40 | 41 | ## 其他注意事项 42 | 43 | 1. 操作日志记录只负责日志的写入操作,不负责日志的查询和统计工作。 44 | 2. 框架提供了两个默认的实现方式 TextOperationLogWriterImpl 和 Log4jOperationLogWriterImpl 。 45 | 3. [centit-framework-system](https://github.com/ndxt/centit-framework-system)中实现了用关系数据库记录操作日志的工作,并实现日志的统计和查询。但需注意虽然日志写入操作和业务的数据库读写操作不在一个事务中,但是当日志量很大的情况下还是不建议使用这种方式记录日志。 46 | 47 | -------------------------------------------------------------------------------- /framework-filter/src/main/java/com/centit/framework/filter/DisableUrlSessionFilter.java: -------------------------------------------------------------------------------- 1 | package com.centit.framework.filter; 2 | 3 | import javax.servlet.*; 4 | import javax.servlet.http.HttpServletRequest; 5 | import javax.servlet.http.HttpServletResponse; 6 | import javax.servlet.http.HttpServletResponseWrapper; 7 | import javax.servlet.http.HttpSession; 8 | import java.io.IOException; 9 | 10 | public class DisableUrlSessionFilter implements Filter { 11 | public void doFilter(ServletRequest request, ServletResponse response, 12 | FilterChain chain) throws IOException, ServletException { 13 | if (!(request instanceof HttpServletRequest)) { 14 | chain.doFilter(request, response); 15 | return; 16 | } 17 | 18 | HttpServletRequest httpRequest = (HttpServletRequest) request; 19 | HttpServletResponse httpResponse = (HttpServletResponse) response; 20 | 21 | if (httpRequest.isRequestedSessionIdFromURL()) { 22 | HttpSession session = httpRequest.getSession(); 23 | if (session != null) 24 | session.invalidate(); 25 | } 26 | 27 | HttpServletResponseWrapper wrappedResponse = new 28 | HttpServletResponseWrapper( httpResponse); 29 | chain.doFilter(request, wrappedResponse); 30 | } 31 | 32 | public void init(FilterConfig config) throws ServletException { 33 | } 34 | 35 | public void destroy() { 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /framework-core/src/main/java/com/centit/framework/core/controller/StringPropertiesEditor.java: -------------------------------------------------------------------------------- 1 | package com.centit.framework.core.controller; 2 | 3 | import org.springframework.beans.propertyeditors.PropertiesEditor; 4 | import org.springframework.util.StringUtils; 5 | import org.springframework.web.util.HtmlUtils; 6 | /** 7 | * 调用htmlEscape 转换属性中的 <>" ;' 等等html 标签 防止XSS攻击 8 | * @author codefan 9 | * 10 | */ 11 | public class StringPropertiesEditor extends PropertiesEditor { 12 | 13 | @Override 14 | public void setAsText(String text) throws IllegalArgumentException { 15 | if(trimWhile) { 16 | String noSpaceText = StringUtils.trimWhitespace(text); 17 | setValue(StringUtils.hasText(noSpaceText) ? 18 | HtmlUtils.htmlEscape(noSpaceText) : noSpaceText); 19 | }else 20 | setValue(StringUtils.hasText(text) ? HtmlUtils.htmlEscape(text) : text); 21 | } 22 | 23 | @Override 24 | public String getAsText() { 25 | Object obj = getValue(); 26 | if(obj==null) 27 | return null; 28 | return obj.toString(); 29 | } 30 | 31 | private boolean trimWhile; 32 | 33 | public void setTrimWhile(boolean trimWhile) { 34 | this.trimWhile = trimWhile; 35 | } 36 | 37 | public StringPropertiesEditor(boolean trimWhile) { 38 | this.trimWhile = trimWhile; 39 | } 40 | 41 | public StringPropertiesEditor() { 42 | this.trimWhile = false; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /centit-persistence-extend/src/main/java/com/centit/framework/core/service/DataScopePowerManager.java: -------------------------------------------------------------------------------- 1 | package com.centit.framework.core.service; 2 | 3 | import com.centit.framework.core.dao.DataPowerFilter; 4 | import com.centit.framework.model.basedata.UserInfo; 5 | import com.centit.framework.model.security.CentitUserDetails; 6 | 7 | import java.util.List; 8 | 9 | /** 10 | * 将项目Service层需要用到的通用服务放在这个,供其他业务服务调用。 11 | * 使用方法:用下面的注解 12 | * (name = "generalService") 13 | * protected GeneralService generalService; 14 | * @author codefan 15 | */ 16 | public interface DataScopePowerManager { 17 | 18 | /** 19 | * 获得用户摸个功能方法的数据范围权限,返回null或者size==0表示拥有所有权限 20 | * @param topUnit 用户租户代码 21 | * @param sUserCode sUserCode 22 | * @param sOptid sOptid 23 | * @param sOptMethod sOptMethod 24 | * @return 用户摸个功能方法的数据范围权限 25 | */ 26 | List listUserDataFiltersByOptIdAndMethod 27 | (String topUnit, String sUserCode, String sOptid, String sOptMethod); 28 | 29 | /** 30 | * 创建用户数据范围过滤器,和上面的方法结合使用 31 | * @param userInfo JSONObject 用户信息 32 | * @param topUnit 用户租户代码 33 | * @param currentUnit 用户当前机构 34 | * @return DataPowerFilter 35 | */ 36 | DataPowerFilter createUserDataPowerFilter(UserInfo userInfo, String topUnit, String currentUnit); 37 | 38 | /** 39 | * 创建用户数据范围过滤器,和上面的方法结合使用 40 | * @param userDetails CentitUserDetails 41 | * @return DataPowerFilter 42 | */ 43 | DataPowerFilter createUserDataPowerFilter(CentitUserDetails userDetails); 44 | } 45 | -------------------------------------------------------------------------------- /framework-adapter/src/main/java/com/centit/framework/common/GlobalConstValue.java: -------------------------------------------------------------------------------- 1 | package com.centit.framework.common; 2 | 3 | public abstract class GlobalConstValue { 4 | //'all'代表返回所有租户的内容,这是topunit这个属性作为租户可以有其他的解释 5 | public static final String NO_TENANT_TOP_UNIT = "all"; 6 | //用户没有登录获取不到租户 7 | public static final String UNKNOW_TENANT_TOP_UNIT = "none"; 8 | //系统管理员、系统维护相关业务的租户为 system;称为系统租户代码 9 | public static final String SYSTEM_TENANT_TOP_UNIT = "system"; 10 | //全局应用归属租户 11 | public static final String GLOBAL_TENANT_TOP_UNIT = "global"; 12 | 13 | //用户类型数据字典 14 | public static final String DATA_CATALOG_UESR_TYPE = "UserType"; 15 | //在多租户系统中用户类型数据字典为 租户代码+这个后缀 16 | public static final String DATA_CATALOG_UESR_TYPE_SUFFIX = "-UT"; 17 | //机构类型数据字典 18 | public static final String DATA_CATALOG_UNIT_TYPE = "UnitType"; 19 | //在多租户系统中机构类型数据字典为 租户代码+这个后缀 20 | public static final String DATA_CATALOG_UNIT_TYPE_SUFFIX = "-DT"; 21 | 22 | //用户职务数据字典 23 | public static final String DATA_CATALOG_RANK = "RankType"; 24 | //在多租户系统中用户职务数据字典为 租户代码+这个后缀 25 | public static final String DATA_CATALOG_RANK_SUFFIX = "-RT"; 26 | //用户岗位数据字典 27 | public static final String DATA_CATALOG_STATION = "StationType"; 28 | //在多租户系统中用户岗位数据字典为 租户代码+这个后缀 29 | public static final String DATA_CATALOG_STATION_SUFFIX = "-ST"; 30 | //用户职级字典 31 | public static final String DATA_CATALOG_POSTRANK = "PostRank"; 32 | //在多租户系统中用户职级字典为 租户代码+这个后缀 33 | public static final String DATA_CATALOG_POSTRANK_SUFFIX = "-PR"; 34 | } 35 | -------------------------------------------------------------------------------- /framework-security/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | framework-parent 7 | com.centit.framework 8 | ${revision} 9 | 10 | 4.0.0 11 | 12 | framework-security 13 | com.centit.framework:framework-security 14 | jar 15 | 框架安全配置类 16 | 17 | 18 | 19 | com.centit.framework 20 | framework-core 21 | ${project.version} 22 | 23 | 24 | 25 | 26 | org.springframework.security 27 | spring-security-config 28 | 29 | 30 | 31 | org.springframework.security 32 | spring-security-taglibs 33 | 34 | 35 | 36 | javax.servlet 37 | javax.servlet-api 38 | provided 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /framework-session-core/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | framework-parent 7 | com.centit.framework 8 | ${revision} 9 | 10 | 4.0.0 11 | 12 | framework-session-core 13 | com.centit.framework:framework-session-core 14 | jar 15 | 框架的Session管理包 16 | 17 | 18 | com.centit.support 19 | centit-database 20 | ${project.version} 21 | 22 | 23 | 24 | org.springframework.session 25 | spring-session-core 26 | 27 | 28 | 29 | com.centit.framework 30 | framework-core 31 | ${project.version} 32 | 33 | 34 | 35 | javax.servlet 36 | javax.servlet-api 37 | provided 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /framework-session-jdbc/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | framework-parent 7 | com.centit.framework 8 | ${revision} 9 | 10 | 4.0.0 11 | 12 | framework-session-jdbc 13 | 14 | 15 | 16 | com.centit.framework 17 | framework-session-core 18 | ${project.version} 19 | 20 | 21 | 22 | org.springframework.session 23 | spring-session-jdbc 24 | 25 | 26 | 27 | com.mysql 28 | mysql-connector-j 29 | compile 30 | 31 | 32 | 33 | 34 | com.oracle 35 | ojdbc6 36 | provided 37 | 38 | 39 | 40 | com.h2database 41 | h2 42 | provided 43 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /framework-core-web/src/main/resources/log4j2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | D:/Projects/RunData/webim_home/logs 6 | mylog 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 16 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 1 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /framework-core/src/main/java/com/centit/framework/operationlog/RecordOperationLog.java: -------------------------------------------------------------------------------- 1 | package com.centit.framework.operationlog; 2 | 3 | import com.centit.framework.model.basedata.OperationLog; 4 | 5 | import java.lang.annotation.ElementType; 6 | import java.lang.annotation.Retention; 7 | import java.lang.annotation.RetentionPolicy; 8 | import java.lang.annotation.Target; 9 | 10 | @Target(ElementType.METHOD) 11 | @Retention(RetentionPolicy.RUNTIME) 12 | public @interface RecordOperationLog { 13 | /** 14 | * 15 | * @return 记录操作内容表达式,理论上这个不能为空 16 | */ 17 | String content() default ""; 18 | 19 | /** 20 | * 21 | * @return 日志等级 22 | */ 23 | String level() default OperationLog.LEVEL_INFO; 24 | 25 | /** 26 | * 27 | * @return 业务编码 28 | */ 29 | String operation() default ""; 30 | 31 | /** 32 | * 33 | * @return 操作方法 34 | */ 35 | String method() default ""; 36 | /** 37 | * 38 | * @return 操作对象主键 表达式 39 | */ 40 | String tag() default ""; 41 | 42 | /** 43 | * 优先级高于 appendRequest 44 | * @return 更改后对象 45 | */ 46 | String newValue() default ""; 47 | /** 48 | * 优先级高于 returnValueAsOld 49 | * @return 更改前对象 50 | */ 51 | String oldValue() default ""; 52 | 53 | /** 54 | * 是否记录操作时间 55 | * @return boolean 56 | */ 57 | boolean timing() default false; 58 | 59 | /** 60 | * 是否将HttpRequest中的参数放入newValue中, 61 | * 一般查询都需要将这个 参数设置为true 62 | * @return boolean 63 | */ 64 | boolean appendRequest() default false; 65 | 66 | /** 67 | * 将方法的返回值放到 old 字段 68 | * @return boolean 69 | */ 70 | boolean returnValueAsOld() default false; 71 | } 72 | -------------------------------------------------------------------------------- /framework-core/src/main/java/com/centit/framework/filter/AssertUserLoginFilter.java: -------------------------------------------------------------------------------- 1 | package com.centit.framework.filter; 2 | 3 | import com.centit.framework.common.JsonResultUtils; 4 | import com.centit.framework.common.ResponseData; 5 | import com.centit.framework.common.WebOptUtils; 6 | import com.centit.framework.model.basedata.UserInfo; 7 | 8 | import javax.servlet.*; 9 | import javax.servlet.http.HttpServletRequest; 10 | import javax.servlet.http.HttpServletResponse; 11 | import java.io.IOException; 12 | 13 | public class AssertUserLoginFilter implements Filter { 14 | 15 | @Override 16 | public void init(FilterConfig filterConfig) throws ServletException { 17 | 18 | } 19 | 20 | @Override 21 | public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, 22 | ServletException { 23 | if(request!=null && response!=null) { 24 | if(request instanceof HttpServletRequest) { 25 | HttpServletRequest httpRequest = (HttpServletRequest)request; 26 | String requestUrl = httpRequest.getRequestURI(); 27 | if(!requestUrl.contains("no-auth")) { 28 | UserInfo userInfo = WebOptUtils.getCurrentUserInfo(httpRequest); 29 | if (userInfo == null) { 30 | JsonResultUtils.writeHttpErrorMessage(ResponseData.ERROR_UNAUTHORIZED, 31 | ResponseData.ERROR_NOT_LOGIN_MSG, (HttpServletResponse) response); 32 | return; 33 | } 34 | } 35 | } 36 | if(chain!=null) { 37 | chain.doFilter(request, response); 38 | } 39 | } 40 | } 41 | 42 | @Override 43 | public void destroy() { 44 | 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /framework-adapter/src/main/java/com/centit/framework/model/basedata/WorkGroupParameter.java: -------------------------------------------------------------------------------- 1 | package com.centit.framework.model.basedata; 2 | 3 | import io.swagger.annotations.ApiModelProperty; 4 | 5 | import javax.persistence.Column; 6 | import javax.persistence.Embeddable; 7 | import javax.validation.constraints.NotBlank; 8 | 9 | /** 10 | * create by scaffold 2020-08-18 13:38:15 11 | * 12 | * @author codefan@sina.com 13 | *

14 | * 项目组成员 15 | */ 16 | @Embeddable 17 | public class WorkGroupParameter implements java.io.Serializable { 18 | private static final long serialVersionUID = 1L; 19 | 20 | @ApiModelProperty(value = "组id") 21 | @Column(name = "group_id") 22 | @NotBlank 23 | private String groupId; 24 | 25 | @ApiModelProperty(value = "用户代码") 26 | @NotBlank 27 | @Column(name = "user_code") 28 | private String userCode; 29 | 30 | @ApiModelProperty(value = "角色代码") 31 | @NotBlank 32 | @Column(name = "role_code") 33 | private String roleCode; 34 | 35 | public WorkGroupParameter() { 36 | } 37 | 38 | public WorkGroupParameter(String groupId, String userCode, String roleCode) { 39 | this.groupId = groupId; 40 | this.userCode = userCode; 41 | this.roleCode = roleCode; 42 | } 43 | 44 | public String getGroupId() { 45 | return groupId; 46 | } 47 | 48 | public void setGroupId(String groupId) { 49 | this.groupId = groupId; 50 | } 51 | 52 | public String getUserCode() { 53 | return userCode; 54 | } 55 | 56 | public void setUserCode(String userCode) { 57 | this.userCode = userCode; 58 | } 59 | 60 | public String getRoleCode() { 61 | return roleCode; 62 | } 63 | 64 | public void setRoleCode(String roleCode) { 65 | this.roleCode = roleCode; 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /framework-core/src/main/java/com/centit/framework/core/controller/SmartDateFormat.java: -------------------------------------------------------------------------------- 1 | package com.centit.framework.core.controller; 2 | 3 | import com.centit.support.algorithm.DatetimeOpt; 4 | import org.apache.commons.lang3.StringUtils; 5 | import org.slf4j.Logger; 6 | import org.slf4j.LoggerFactory; 7 | 8 | import java.text.DateFormatSymbols; 9 | import java.text.ParsePosition; 10 | import java.text.SimpleDateFormat; 11 | import java.util.Date; 12 | import java.util.Locale; 13 | 14 | public class SmartDateFormat extends SimpleDateFormat{ 15 | 16 | private static final long serialVersionUID = 1L; 17 | private static Logger logger = LoggerFactory.getLogger(SmartDateFormat.class); 18 | public SmartDateFormat() { 19 | super(); 20 | } 21 | 22 | public SmartDateFormat(String pattern) 23 | { 24 | super(pattern); 25 | } 26 | 27 | 28 | public SmartDateFormat(String pattern, Locale locale) 29 | { 30 | super(pattern,locale); 31 | } 32 | 33 | public SmartDateFormat(String pattern, DateFormatSymbols formatSymbols) 34 | { 35 | super(pattern,formatSymbols); 36 | } 37 | 38 | @Override 39 | public Date parse(String source, ParsePosition pos){ 40 | if (StringUtils.isBlank(source)) { 41 | return null; 42 | } 43 | 44 | int start = pos.getIndex(); 45 | int errorIndex = pos.getErrorIndex(); 46 | Date parseDate = null; 47 | try{ 48 | parseDate = super.parse(source, pos); 49 | }catch(RuntimeException e){ 50 | logger.error(e.getMessage(),e); 51 | parseDate = null; 52 | } 53 | if(parseDate!=null) 54 | return parseDate; 55 | 56 | pos.setErrorIndex(errorIndex); 57 | 58 | int nlen = source.length(); 59 | pos.setIndex(start + nlen); 60 | return DatetimeOpt.smartPraseDate(source); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /framework-core/src/main/java/com/centit/framework/components/impl/TextOperationLogWriterImpl.java: -------------------------------------------------------------------------------- 1 | package com.centit.framework.components.impl; 2 | 3 | import com.centit.framework.components.OperationLogCenter; 4 | import com.centit.framework.model.adapter.OperationLogWriter; 5 | import com.centit.framework.model.basedata.OperationLog; 6 | import com.centit.support.algorithm.DatetimeOpt; 7 | import com.centit.support.file.TxtLogFile; 8 | 9 | import java.util.List; 10 | 11 | public class TextOperationLogWriterImpl implements OperationLogWriter{ 12 | 13 | //@PostConstruct 14 | public void init(){ 15 | OperationLogCenter.initOperationLogWriter(this); 16 | //OperationLogCenter.registerOperationLogWriter(this); 17 | } 18 | 19 | private String optLogHomePath; 20 | 21 | public void setOptLogHomePath(String optLogPath){ 22 | if(optLogPath.endsWith("/") || optLogPath.endsWith("\\")){ 23 | this.optLogHomePath = optLogPath.substring(0,optLogPath.length()-1); 24 | }else { 25 | this.optLogHomePath = optLogPath; 26 | } 27 | } 28 | 29 | public String getCurrentLogPath(){ 30 | return optLogHomePath+"/D" 31 | +DatetimeOpt.convertDateToString( 32 | DatetimeOpt.currentUtilDate(),"yyyyMMdd")+".log"; 33 | } 34 | 35 | @Override 36 | public void save(OperationLog optLog) { 37 | TxtLogFile.writeLog(getCurrentLogPath(), optLog.toString(), 38 | true,true); 39 | } 40 | 41 | @Override 42 | public void save(List optLogs) { 43 | String logFilePath = getCurrentLogPath(); 44 | TxtLogFile logger = new TxtLogFile(); 45 | logger.openLogFile(logFilePath); 46 | for(OperationLog optLog : optLogs) { 47 | logger.writeLog(optLog.toString(), 48 | true, true); 49 | } 50 | logger.closeLogFile(); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /framework-adapter/src/main/java/com/centit/framework/model/basedata/OptMethodUrlMap.java: -------------------------------------------------------------------------------- 1 | package com.centit.framework.model.basedata; 2 | 3 | import org.hibernate.validator.constraints.Length; 4 | 5 | import javax.persistence.Column; 6 | import javax.persistence.Entity; 7 | import javax.persistence.Id; 8 | import javax.persistence.Table; 9 | 10 | @Entity 11 | @Table(name = "F_V_OPTDEF_URL_MAP") 12 | public class OptMethodUrlMap implements java.io.Serializable { 13 | 14 | private static final long serialVersionUID = 396021378825483579L; 15 | 16 | @Id 17 | @Column(name = "OPT_CODE") 18 | //@GeneratedValue(generator = "assignedGenerator") 19 | private String optCode;// 操作代码 20 | 21 | @Column(name = "OPT_DEF_URL") 22 | @Length(max = 50) 23 | private String optDefUrl; // 操作名称 24 | 25 | @Column(name = "OPT_REQ") 26 | @Length(max = 6) 27 | private String optReq; 28 | 29 | 30 | public OptMethodUrlMap() { 31 | } 32 | 33 | /** 34 | * minimal constructor 35 | * @param optcode String 36 | */ 37 | public OptMethodUrlMap(String optcode) { 38 | this.optCode = optcode; 39 | } 40 | 41 | 42 | 43 | public OptMethodUrlMap(String optcode, String optdefurl, String optmethod) { 44 | this.optCode = optcode; 45 | this.optDefUrl = optdefurl; 46 | this.optReq = optmethod; 47 | } 48 | 49 | public String getOptCode() { 50 | return optCode; 51 | } 52 | 53 | public void setOptCode(String optCode) { 54 | this.optCode = optCode; 55 | } 56 | 57 | public String getOptDefUrl() { 58 | return optDefUrl; 59 | } 60 | 61 | public void setOptDefUrl(String optDefUrl) { 62 | this.optDefUrl = optDefUrl; 63 | } 64 | 65 | public String getOptReq() { 66 | return optReq; 67 | } 68 | 69 | public void setOptReq(String optReq) { 70 | this.optReq = optReq; 71 | } 72 | 73 | 74 | } 75 | -------------------------------------------------------------------------------- /framework-adapter/src/main/java/com/centit/framework/model/security/CentitPasswordEncoder.java: -------------------------------------------------------------------------------- 1 | package com.centit.framework.model.security; 2 | 3 | 4 | import org.apache.commons.lang3.StringUtils; 5 | 6 | /** 7 | * Created by codefan on 17-1-20. 8 | */ 9 | @SuppressWarnings("deprecation") 10 | public interface CentitPasswordEncoder { 11 | 12 | /** 13 | * 14 | * @param password 密码 15 | * @param minLength 最小长度 16 | * @return 返回值 < 0 不符合要求, 1~4 之间为密码强度 17 | */ 18 | static int checkPasswordStrength(String password, int minLength){ 19 | if(StringUtils.isBlank(password)){ 20 | return -1; 21 | } 22 | int passwrodLen = password.length(); 23 | int mathLength = passwrodLen>=minLength? 1 : -1; 24 | int hasDigit = 0, hasLowLetter = 0, hasUpLetter = 0, hasOtherLetter = 0; 25 | for(int i=0; i='0' && c<='9'){ 28 | hasDigit = 1; 29 | } else if(c>='a' && c<='z'){ 30 | hasLowLetter = 1; 31 | } else if(c>='A' && c<='Z'){ 32 | hasUpLetter = 1; 33 | } else { 34 | hasOtherLetter = 1; 35 | } 36 | } 37 | return mathLength * (hasDigit + hasLowLetter + hasUpLetter + hasOtherLetter); 38 | } 39 | 40 | static int checkPasswordStrength(String password){ 41 | return checkPasswordStrength(password, 8); 42 | } 43 | 44 | String encodePassword(String rawPass, Object salt); 45 | /** 46 | * 在 encodePassword 前疊加 预处理 47 | * @param rawPass 明文原始密码 48 | * @param salt 盐 49 | * @return 密文 50 | */ 51 | String createPassword(String rawPass, Object salt); 52 | 53 | boolean isPasswordValid(String encodedPassword, String rawPass, Object salt); 54 | 55 | default boolean isCorrectPasswordFormat(String password){ 56 | return true; 57 | } 58 | 59 | } 60 | -------------------------------------------------------------------------------- /framework-session-jdbc/src/main/java/com/centit/framework/session/jdbc/CentitSessionJdbcRepo.java: -------------------------------------------------------------------------------- 1 | package com.centit.framework.session.jdbc; 2 | 3 | import com.centit.framework.session.CentitSessionRepo; 4 | import org.apache.commons.lang3.StringUtils; 5 | import org.springframework.session.FindByIndexNameSessionRepository; 6 | import org.springframework.session.Session; 7 | 8 | import java.util.Map; 9 | 10 | public class CentitSessionJdbcRepo implements CentitSessionRepo { 11 | 12 | private FindByIndexNameSessionRepository sessionRepository; 13 | 14 | public CentitSessionJdbcRepo(FindByIndexNameSessionRepository sessionRepository){ 15 | this.sessionRepository = sessionRepository; 16 | } 17 | 18 | @Override 19 | public void kickSessionByName(String loginName, String escapeSessionId) { 20 | Map mapSession = this.sessionRepository.findByPrincipalName(loginName); 21 | if(mapSession!=null) { 22 | for (Map.Entry ent : mapSession.entrySet()) { 23 | if(!StringUtils.equals(escapeSessionId, ent.getValue().getId())) { 24 | this.sessionRepository.deleteById(ent.getValue().getId()); 25 | } 26 | } 27 | } 28 | } 29 | 30 | @Override 31 | public void kickSessionByName(String loginName) { 32 | Map mapSession = this.sessionRepository.findByPrincipalName(loginName); 33 | if(mapSession!=null) { 34 | for (Map.Entry ent : mapSession.entrySet()) { 35 | this.sessionRepository.deleteById(ent.getValue().getId()); 36 | } 37 | } 38 | } 39 | 40 | @Override 41 | public void kickSessionByPrincipal(String principalName) { 42 | kickSessionByName(principalName); 43 | } 44 | 45 | @Override 46 | public Session findById(String id) { 47 | return this.sessionRepository.findById(id); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /framework-session-redis/src/main/java/com/centit/framework/session/redis/CentitSessionRedisRepo.java: -------------------------------------------------------------------------------- 1 | package com.centit.framework.session.redis; 2 | 3 | import com.centit.framework.session.CentitSessionRepo; 4 | import org.apache.commons.lang3.StringUtils; 5 | import org.springframework.session.Session; 6 | import org.springframework.session.data.redis.RedisIndexedSessionRepository; 7 | 8 | import java.util.Map; 9 | 10 | public class CentitSessionRedisRepo implements CentitSessionRepo { 11 | 12 | private RedisIndexedSessionRepository sessionRepository; 13 | public CentitSessionRedisRepo(RedisIndexedSessionRepository sessionRepository){ 14 | this.sessionRepository = sessionRepository; 15 | } 16 | 17 | @Override 18 | public void kickSessionByName(String loginName, String escapeSessionId) { 19 | Map mapSession = this.sessionRepository.findByPrincipalName(loginName); 20 | if(mapSession!=null) { 21 | for (Map.Entry ent : mapSession.entrySet()) { 22 | if(!StringUtils.equals(escapeSessionId, ent.getValue().getId())) { 23 | this.sessionRepository.deleteById(ent.getValue().getId()); 24 | } 25 | } 26 | } 27 | } 28 | 29 | @Override 30 | public void kickSessionByName(String loginName) { 31 | Map mapSession = this.sessionRepository.findByPrincipalName(loginName); 32 | if(mapSession!=null) { 33 | for (Map.Entry ent : mapSession.entrySet()) { 34 | this.sessionRepository.deleteById(ent.getValue().getId()); 35 | } 36 | } 37 | } 38 | 39 | @Override 40 | public void kickSessionByPrincipal(String principalName) { 41 | kickSessionByName(principalName); 42 | } 43 | 44 | @Override 45 | public Session findById(String id) { 46 | return this.sessionRepository.findById(id); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /framework-core/src/main/java/com/centit/framework/core/controller/ObjectAppendProperties.java: -------------------------------------------------------------------------------- 1 | package com.centit.framework.core.controller; 2 | 3 | import com.centit.framework.common.ResponseData; 4 | import com.centit.framework.common.ToResponseData; 5 | import com.centit.support.algorithm.CollectionsOpt; 6 | import io.swagger.annotations.ApiModel; 7 | import io.swagger.annotations.ApiModelProperty; 8 | 9 | import java.util.Map; 10 | 11 | /** 12 | * 功能,在返回结果对象中添加额外的属性,比如数据字典映射值等等 13 | * @param 模板对象,可以是任何类型 14 | */ 15 | @ApiModel(description = "在返回结果对象中添加额外的属性,比如数据字典映射值等等") 16 | public class ObjectAppendProperties implements ToResponseData { 17 | 18 | @ApiModelProperty(value = "结果对象") 19 | private T object; 20 | @ApiModelProperty(value = "额外属性") 21 | private Map extendProperties; 22 | 23 | /** 24 | * 在返回结果对象中添加额外的属性,比如数据字典映射值等等 25 | * @param obj 对象 26 | * @param extendProperties 额外属性 27 | */ 28 | public ObjectAppendProperties(T obj, Map extendProperties){ 29 | this.object = obj; 30 | this.extendProperties = extendProperties; 31 | } 32 | 33 | /** 34 | * 在返回结果对象中添加额外的属性,比如数据字典映射值等等 35 | * @param obj 对象 36 | * @param extendProperties 额外属性 37 | * @param 对象类型 38 | * @return ToResponseData 用于 WarpUpResponseBody 的处理 39 | */ 40 | public static ObjectAppendProperties 41 | create(D obj, Map extendProperties){ 42 | return new ObjectAppendProperties(obj, extendProperties); 43 | } 44 | 45 | @Override 46 | public ResponseData toResponseData(){ 47 | if(object==null){ 48 | return ResponseData.makeResponseData(extendProperties); 49 | } 50 | Map objectMap = CollectionsOpt.objectToMap(object); 51 | if(extendProperties!=null && extendProperties.size()>0) { 52 | objectMap.putAll(extendProperties); 53 | } 54 | return ResponseData.makeResponseData(objectMap); 55 | } 56 | 57 | } 58 | -------------------------------------------------------------------------------- /framework-adapter/src/main/java/com/centit/framework/common/ResponseSingleData.java: -------------------------------------------------------------------------------- 1 | package com.centit.framework.common; 2 | 3 | /** 4 | * 响应 http 请求 返回的单个数据 5 | */ 6 | public class ResponseSingleData implements ResponseData{ 7 | 8 | private static final long serialVersionUID = 1L; 9 | /** 10 | * 返回代码,0 表示正确,其他的为错误代码 11 | */ 12 | private int code; 13 | 14 | /** 15 | * 返回消息提示 ,code为0时是提示,其他为 错误提示 16 | */ 17 | private String message; 18 | 19 | /** 20 | * 返回的详细数据, 可能是需要回显的参数,也可能是验证的错误提示 21 | */ 22 | protected Object data; 23 | 24 | public ResponseSingleData() { 25 | this.code = RESULT_OK; 26 | this.message = "OK"; 27 | } 28 | 29 | public ResponseSingleData(int nCode) { 30 | this.code = nCode; 31 | this.message = nCode==RESULT_OK ? "OK" : "ERROR"; 32 | } 33 | 34 | public ResponseSingleData(String message) { 35 | this.code = RESULT_OK; 36 | this.message = message; 37 | } 38 | 39 | public ResponseSingleData(int nCode, String message) { 40 | this.code = nCode; 41 | this.message = message; 42 | } 43 | 44 | public static ResponseSingleData makeResponseData(Object objValue){ 45 | ResponseSingleData resData = new ResponseSingleData(); 46 | resData.setData(objValue); 47 | return resData; 48 | } 49 | 50 | public int getCode() { 51 | return code; 52 | } 53 | 54 | public void setCode(int resCode) { 55 | this.code = resCode; 56 | } 57 | 58 | public String getMessage() { 59 | return message; 60 | } 61 | 62 | public void setMessage(String resMessage) { 63 | this.message = resMessage; 64 | } 65 | 66 | public Object getData() { 67 | return data; 68 | } 69 | 70 | public Object setData(Object objValue) { 71 | Object oldObj = this.data; 72 | this.data = objValue; 73 | return oldObj; 74 | } 75 | 76 | @Override 77 | public String toString(){ 78 | return toJSONString(); 79 | } 80 | 81 | } 82 | -------------------------------------------------------------------------------- /framework-adapter/src/main/java/com/centit/framework/model/security/CentitUserDetailsService.java: -------------------------------------------------------------------------------- 1 | package com.centit.framework.model.security; 2 | 3 | import org.springframework.security.core.GrantedAuthority; 4 | import org.springframework.security.core.userdetails.UserDetailsService; 5 | import org.springframework.security.core.userdetails.UsernameNotFoundException; 6 | 7 | import java.util.Collection; 8 | 9 | public interface CentitUserDetailsService 10 | extends UserDetailsService 11 | /*AuthenticationUserDetailsService*/{ 12 | /** 13 | * 获取用户 权限,角色名数组 14 | * @param loginname loginname 15 | * @return 用户 权限,角色名数组 16 | * @throws UsernameNotFoundException UsernameNotFoundException 17 | */ 18 | Collection loadUserAuthorities(String loginname) throws UsernameNotFoundException; 19 | 20 | /** 21 | * 获取用户信息 by loginname,用户的登录名 22 | * @param loginname loginname 23 | * @return 用户信息 24 | */ 25 | CentitUserDetails loadDetailsByLoginName(String loginname); 26 | 27 | /** 28 | * 获取用户信息 by userCode,用户的主键 29 | * @param userCode userCode 30 | * @return 用户信息 31 | */ 32 | CentitUserDetails loadDetailsByUserCode(String userCode); 33 | 34 | /** 35 | * 获取用户信息 by RegEmail,用户的主键 36 | * @param regEmail regEmail 37 | * @return 用户信息 38 | */ 39 | CentitUserDetails loadDetailsByRegEmail(String regEmail); 40 | 41 | /** 42 | * 获取用户信息 by RegCellPhone,用户的主键 43 | * @param regCellPhone regCellPhone 44 | * @return 用户信息 45 | */ 46 | CentitUserDetails loadDetailsByRegCellPhone(String regCellPhone); 47 | /** 48 | * 设置用户参数 (用户登录时 回写表单中的附加信息,比如用户选择的站点、语言等等信息) 49 | * @param userCode userCode 50 | * @param paramCode paramCode 51 | * @param paramValue paramValue 52 | * @param paramClass paramClass 53 | * @param paramName paramName 54 | */ 55 | void saveUserSetting(String userCode, String paramCode,String paramValue, 56 | String paramClass, String paramName); 57 | 58 | } 59 | -------------------------------------------------------------------------------- /framework-security/src/main/java/com/centit/framework/security/AjaxAuthenticationEntryPoint.java: -------------------------------------------------------------------------------- 1 | package com.centit.framework.security; 2 | 3 | import com.centit.framework.common.JsonResultUtils; 4 | import com.centit.framework.common.ResponseData; 5 | import com.centit.framework.common.ResponseSingleData; 6 | import com.centit.framework.common.WebOptUtils; 7 | import org.springframework.http.HttpStatus; 8 | import org.springframework.security.core.AuthenticationException; 9 | import org.springframework.security.web.AuthenticationEntryPoint; 10 | import org.springframework.security.web.authentication.HttpStatusEntryPoint; 11 | import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint; 12 | 13 | import javax.servlet.ServletException; 14 | import javax.servlet.http.HttpServletRequest; 15 | import javax.servlet.http.HttpServletResponse; 16 | import java.io.IOException; 17 | 18 | public class AjaxAuthenticationEntryPoint implements AuthenticationEntryPoint { 19 | private AuthenticationEntryPoint browse; 20 | private AuthenticationEntryPoint api; 21 | 22 | public AjaxAuthenticationEntryPoint(String loginFormUrl) { 23 | this.browse = new LoginUrlAuthenticationEntryPoint(loginFormUrl); 24 | this.api = new HttpStatusEntryPoint(HttpStatus.UNAUTHORIZED); 25 | } 26 | 27 | @Override 28 | public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) 29 | throws IOException, ServletException { 30 | if(WebOptUtils.isAjax(request)){ 31 | if(WebOptUtils.exceptionNotAsHttpError) { 32 | ResponseSingleData responseData = 33 | new ResponseSingleData(ResponseData.ERROR_UNAUTHORIZED, 34 | "未登录!"); 35 | JsonResultUtils.writeResponseDataAsJson(responseData, response); 36 | } else { 37 | api.commence(request, response, authException); 38 | } 39 | }else { 40 | browse.commence(request, response, authException); 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /framework-filter/src/main/java/com/centit/framework/filter/GZIPFilter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2003 Jayson Falkner (jayson@jspinsider.com) 3 | * This code is from "Servlets and JavaServer pages; the J2EE Web Tier", 4 | * http://www.jspbook.com. You may freely use the code both commercially 5 | * and non-commercially. If you like the code, please pick up a copy of 6 | * the book and help support the authors, development of more free code, 7 | * and the JSP/Servlet/J2EE community. 8 | */ 9 | package com.centit.framework.filter; 10 | 11 | import javax.servlet.*; 12 | import javax.servlet.http.HttpServletRequest; 13 | import javax.servlet.http.HttpServletResponse; 14 | import java.io.IOException; 15 | 16 | /** 17 | * 网站常使用GZIP压缩算法对网页内容进行压缩,然后传给浏览器,以减小数据传输量,提高响应速度。浏览器接收到GZIP压缩数据后会自动解压并正确显示。 18 | * GZIP加速常用于解决网速慢的瓶颈。 19 | * 20 | * 压缩Filter中需要先判断客户浏览器时候支持GZip自动解压,如果支持,则进行GZIP压缩,否则不压缩。判断的依据是浏览器提供的Header信息 21 | * 22 | * 23 | * @author hx 24 | * 2015-8-4 25 | */ 26 | public class GZIPFilter implements Filter { 27 | 28 | public void doFilter(ServletRequest req, ServletResponse res, 29 | FilterChain chain) throws IOException, ServletException { 30 | if (req instanceof HttpServletRequest) { 31 | HttpServletRequest request = (HttpServletRequest) req; 32 | HttpServletResponse response = (HttpServletResponse) res; 33 | //支持的编码方式 34 | String ae = request.getHeader("accept-encoding"); 35 | //如果客户浏览器支持GZIP格式,则使用GZIP压缩数据 36 | if (ae != null && ae.indexOf("gzip") != -1) { 37 | // System.out.println("GZIP supported, compressing."); 38 | GZIPResponseWrapper wrappedResponse = new GZIPResponseWrapper( 39 | response); 40 | chain.doFilter(req, wrappedResponse);//doFilter,使用自定义的response 41 | wrappedResponse.finishResponse();//输出压缩数据 42 | return; 43 | } 44 | chain.doFilter(req, res);//否则不压缩 45 | } 46 | } 47 | 48 | public void init(FilterConfig filterConfig) { 49 | // noop 50 | } 51 | 52 | public void destroy() { 53 | // noop 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /framework-adapter/src/main/java/com/centit/framework/common/ResponseMapData.java: -------------------------------------------------------------------------------- 1 | package com.centit.framework.common; 2 | 3 | import java.util.LinkedHashMap; 4 | import java.util.Map; 5 | 6 | /** 7 | * 响应 http 请求 返回的数据,可以用Map返回多个数据 8 | */ 9 | @SuppressWarnings("unused") 10 | public class ResponseMapData extends ResponseSingleData { 11 | 12 | private static final long serialVersionUID = 1L; 13 | 14 | public ResponseMapData() { 15 | super(); 16 | } 17 | 18 | public ResponseMapData(int nCode) { 19 | super(nCode); 20 | } 21 | 22 | public ResponseMapData(String message) { 23 | super(message); 24 | } 25 | 26 | public ResponseMapData(int nCode, String message) { 27 | super(nCode, message); 28 | } 29 | 30 | public static ResponseMapData makeResponseData(Map resMapData){ 31 | ResponseMapData resData = new ResponseMapData(); 32 | resData.setData(resMapData); 33 | return resData; 34 | } 35 | 36 | public Map getData() { 37 | return (Map) data; 38 | } 39 | 40 | @Deprecated 41 | public Object setData(Object objValue) { 42 | if(! (objValue instanceof Map)){ 43 | throw new RuntimeException("参数必须式 Map 类型"); 44 | } 45 | Object oldObj = this.data; 46 | this.data = objValue; 47 | return oldObj; 48 | } 49 | 50 | public Map setData(Map objValue) { 51 | Object oldObj = data; 52 | this.data = objValue; 53 | return (Map)oldObj; 54 | } 55 | 56 | public void addResponseData(String sKey, Object objValue) { 57 | if(data == null ){ 58 | data = new LinkedHashMap<>(); 59 | } 60 | ((Map) data).put(sKey, objValue); 61 | } 62 | 63 | public Object getResponseData(String sKey) { 64 | if( this.data == null){ 65 | return null; 66 | } 67 | return ((Map) data).get(sKey); 68 | } 69 | 70 | @Override 71 | public String toString(){ 72 | return toJSONString(); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /framework-core/src/main/java/com/centit/framework/components/impl/UserUnitMapTranslate.java: -------------------------------------------------------------------------------- 1 | package com.centit.framework.components.impl; 2 | 3 | import com.centit.framework.model.adapter.UserUnitVariableTranslate; 4 | import com.centit.support.algorithm.ReflectionOpt; 5 | import com.centit.support.network.HtmlFormUtils; 6 | 7 | import java.util.HashSet; 8 | import java.util.Map; 9 | import java.util.Set; 10 | 11 | public class UserUnitMapTranslate implements UserUnitVariableTranslate { 12 | 13 | private Map varMap; 14 | //public 15 | public UserUnitMapTranslate(){ 16 | varMap = null; 17 | } 18 | 19 | public UserUnitMapTranslate(Map varMap) { 20 | this.varMap = varMap; 21 | } 22 | 23 | /** 24 | * 返回权限表达式中的自定义变量对应的用户组 25 | * 26 | * @param varName 自定义变量 27 | * @return 权限表达式中的自定义变量对应的用户组 28 | */ 29 | public Set getUsersVariable(String varName){ 30 | if(varMap==null) 31 | return null; 32 | 33 | Object res = ReflectionOpt.attainExpressionValue(varMap, varName); 34 | String [] us = HtmlFormUtils.getParameterStringArray(res); 35 | if(us==null) 36 | return null; 37 | Set uSet = new HashSet<>(); 38 | for (String s : us){ 39 | uSet.add(s); 40 | } 41 | return uSet; 42 | } 43 | 44 | /** 45 | * 返回机构表达式中的自定义变量对应的机构组 46 | * 47 | * @param varName 自定义变量 48 | * @return 机构表达式中的自定义变量对应的机构组 49 | */ 50 | public Set getUnitsVariable(String varName){ 51 | return getUsersVariable(varName); 52 | } 53 | 54 | /** 55 | * 变量名--变量值的转变 56 | * 变量 是用 ${变量名} 57 | * 如果这个变量不存在,返回空字符串 "''" 58 | * 59 | * @param varName varName 60 | * @return 变量值的转变 61 | */ 62 | @Override 63 | public Object getVarValue(String varName) { 64 | if(varMap==null) 65 | return null; 66 | return ReflectionOpt.attainExpressionValue(varMap, varName); 67 | //return StringBaseOpt.objectToString(res); 68 | } 69 | 70 | public Map getVarMap() { 71 | return varMap; 72 | } 73 | 74 | public void setVarMap(Map varMap) { 75 | this.varMap = varMap; 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /framework-core/src/main/java/com/centit/framework/core/aop/ResubmitLock.java: -------------------------------------------------------------------------------- 1 | package com.centit.framework.core.aop; 2 | 3 | import org.apache.commons.codec.digest.DigestUtils; 4 | 5 | import java.util.Objects; 6 | import java.util.concurrent.ConcurrentHashMap; 7 | import java.util.concurrent.ScheduledThreadPoolExecutor; 8 | import java.util.concurrent.ThreadPoolExecutor; 9 | import java.util.concurrent.TimeUnit; 10 | 11 | /** 12 | * 重复提交锁 13 | */ 14 | public final class ResubmitLock { 15 | 16 | 17 | private static final ConcurrentHashMap LOCK_CACHE = new ConcurrentHashMap<>(200); 18 | private static final ScheduledThreadPoolExecutor EXECUTOR = new ScheduledThreadPoolExecutor(5, new ThreadPoolExecutor.DiscardPolicy()); 19 | 20 | 21 | // private static final Cache CACHES = CacheBuilder.newBuilder() 22 | // 最大缓存 100 个 23 | // .maximumSize(1000) 24 | // 设置写缓存后 5 秒钟过期 25 | // .expireAfterWrite(5, TimeUnit.SECONDS) 26 | // .build(); 27 | 28 | 29 | private ResubmitLock() { 30 | } 31 | 32 | /** 33 | * 静态内部类 单例模式 34 | * 35 | * @return 36 | */ 37 | private static class SingletonInstance { 38 | private static final ResubmitLock INSTANCE = new ResubmitLock(); 39 | } 40 | 41 | public static ResubmitLock getInstance() { 42 | return SingletonInstance.INSTANCE; 43 | } 44 | 45 | 46 | public static String handleKey(String param) { 47 | return DigestUtils.md5Hex(param == null ? "" : param); 48 | } 49 | 50 | /** 51 | * 加锁 putIfAbsent 是原子操作保证线程安全 52 | * 53 | * @param key 对应的key 54 | * @param value 55 | * @return 56 | */ 57 | public boolean lock(final String key, Object value) { 58 | return Objects.isNull(LOCK_CACHE.putIfAbsent(key, value)); 59 | } 60 | 61 | /** 62 | * 延时释放锁 用以控制短时间内的重复提交 63 | * 64 | * @param lock 是否需要解锁 65 | * @param key 对应的key 66 | * @param delaySeconds 延时时间 67 | */ 68 | public void unLock(final boolean lock, final String key, final int delaySeconds) { 69 | if (lock) { 70 | EXECUTOR.schedule(() -> { 71 | LOCK_CACHE.remove(key); 72 | }, delaySeconds, TimeUnit.SECONDS); 73 | } 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /framework-adapter/src/main/java/com/centit/framework/model/security/CentitSecurityConfig.java: -------------------------------------------------------------------------------- 1 | package com.centit.framework.model.security; 2 | 3 | import org.springframework.security.access.ConfigAttribute; 4 | import org.springframework.security.access.SecurityConfig; 5 | import org.springframework.util.Assert; 6 | import org.springframework.util.StringUtils; 7 | 8 | import java.io.Serializable; 9 | import java.util.ArrayList; 10 | import java.util.List; 11 | 12 | public class CentitSecurityConfig implements ConfigAttribute, Serializable { 13 | private final String attrib; 14 | 15 | // ~ Constructors 16 | // =================================================================================================== 17 | public CentitSecurityConfig(){ 18 | attrib=""; 19 | } 20 | public CentitSecurityConfig(String config) { 21 | this.attrib = config; 22 | } 23 | 24 | // ~ Methods 25 | // ======================================================================================================== 26 | 27 | @Override 28 | public boolean equals(Object obj) { 29 | if (obj instanceof ConfigAttribute) { 30 | ConfigAttribute attr = (ConfigAttribute) obj; 31 | 32 | return this.attrib.equals(attr.getAttribute()); 33 | } 34 | 35 | return false; 36 | } 37 | 38 | @Override 39 | public String getAttribute() { 40 | return this.attrib; 41 | } 42 | 43 | @Override 44 | public int hashCode() { 45 | return this.attrib.hashCode(); 46 | } 47 | 48 | @Override 49 | public String toString() { 50 | return this.attrib; 51 | } 52 | 53 | public static List createListFromCommaDelimitedString(String access) { 54 | return createList(StringUtils.commaDelimitedListToStringArray(access)); 55 | } 56 | 57 | public static List createList(String... attributeNames) { 58 | Assert.notNull(attributeNames, "You must supply an array of attribute names"); 59 | List attributes = new ArrayList<>( 60 | attributeNames.length); 61 | 62 | for (String attribute : attributeNames) { 63 | attributes.add(new SecurityConfig(attribute.trim())); 64 | } 65 | 66 | return attributes; 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /framework-security/src/main/java/com/centit/framework/security/HostIpFilterDecisionManager.java: -------------------------------------------------------------------------------- 1 | package com.centit.framework.security; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | import org.springframework.security.access.AccessDecisionManager; 6 | import org.springframework.security.access.AccessDeniedException; 7 | import org.springframework.security.access.ConfigAttribute; 8 | import org.springframework.security.authentication.InsufficientAuthenticationException; 9 | import org.springframework.security.core.Authentication; 10 | import org.springframework.security.web.FilterInvocation; 11 | 12 | import javax.servlet.http.HttpServletRequest; 13 | import java.util.Collection; 14 | 15 | /** 16 | * 17 | * 这个过滤器仅对请求的IP进行过滤,对符合条件的IP的所有请求放行 18 | * 19 | * @author codefan 20 | * 2015年11月30日 21 | */ 22 | //@Component("hostIpFilterDecisionManagerBean") 23 | public class HostIpFilterDecisionManager implements AccessDecisionManager { 24 | protected static final Logger logger = LoggerFactory.getLogger(HostIpFilterDecisionManager.class); 25 | 26 | // In this method, need to compare authentication with configAttributes. 27 | // 1, A object is a URL, a filter was find permission configuration by this 28 | // URL, and pass to here. 29 | // 2, Check authentication has attribute in permission configuration 30 | // (configAttributes) 31 | // 3, If not match corresponding authentication, throw a 32 | // AccessDeniedException. 33 | @Override 34 | public void decide(Authentication authentication, Object object, Collection configAttributes) 35 | throws AccessDeniedException, InsufficientAuthenticationException { 36 | 37 | if(configAttributes!=null && configAttributes.size()>0) 38 | return; 39 | 40 | //没有权限,组织提示信息。 41 | FilterInvocation fi = (FilterInvocation) object; 42 | HttpServletRequest request = fi.getHttpRequest(); 43 | String urlIp = request.getRemoteHost(); 44 | logger.error(urlIp+" 是不允许访问这个服务的。"); 45 | throw new AccessDeniedException(urlIp+" 是不允许访问这个服务的。"); 46 | } 47 | 48 | public boolean supports(ConfigAttribute arg0) { 49 | return true; 50 | } 51 | 52 | public boolean supports(Class arg0) { 53 | return true; 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /framework-core/src/main/java/com/centit/framework/common/ValidatorUtils.java: -------------------------------------------------------------------------------- 1 | package com.centit.framework.common; 2 | 3 | import com.centit.support.common.ObjectException; 4 | import org.apache.commons.lang3.StringUtils; 5 | 6 | import javax.validation.ConstraintViolation; 7 | import javax.validation.Validation; 8 | import javax.validation.Validator; 9 | import javax.validation.ValidatorFactory; 10 | import java.util.HashMap; 11 | import java.util.Map; 12 | import java.util.Set; 13 | /** 14 | * 常用验证工具,适用于控制器及业务层中判断主键或关键对象且需要中断执行流程 15 | */ 16 | public class ValidatorUtils { 17 | 18 | private static Validator validator = null; 19 | 20 | private static synchronized Validator getDefaultValidator(){ 21 | if(validator==null){ 22 | ValidatorFactory factory = Validation.buildDefaultValidatorFactory(); 23 | validator = factory.getValidator(); 24 | } 25 | return validator; 26 | } 27 | /** 28 | * 判断空对象 29 | * 30 | * @param object 任意对象 31 | * @param errorText 返回错误信息 32 | */ 33 | public static void validatorNullObject(Object object, String errorText) { 34 | if (null == object) { 35 | throw new ObjectException(ObjectException.NULL_EXCEPTION,errorText); 36 | } 37 | } 38 | 39 | /** 40 | * 判断空白字符串 41 | * 42 | * @param str 字符串 43 | * @param errorText 返回错误信息 44 | */ 45 | public static void validatorBlank(String str, String errorText) { 46 | if (StringUtils.isBlank(str)) { 47 | throw new ObjectException(ObjectException.BLANK_EXCEPTION,errorText); 48 | } 49 | } 50 | 51 | /** 52 | * 调用Hibernate注解进行验证 53 | * @param 持久对象 54 | * @param po 持久对象 55 | * @return Map 错误信息 56 | */ 57 | public static Map validatorEntityPo(Po po) { 58 | Validator validator = getDefaultValidator(); 59 | 60 | Set> constraintViolations = validator.validate(po); 61 | Map errMsg = new HashMap<>(); 62 | for(ConstraintViolation constraintViolation : constraintViolations) { 63 | errMsg.put(String.valueOf(constraintViolation.getPropertyPath()), 64 | constraintViolation.getMessage()); 65 | } 66 | return errMsg; 67 | } 68 | 69 | } 70 | -------------------------------------------------------------------------------- /framework-security/src/main/java/com/centit/framework/security/DaoInvocationSecurityMetadataSource.java: -------------------------------------------------------------------------------- 1 | package com.centit.framework.security; 2 | 3 | import org.springframework.security.access.ConfigAttribute; 4 | import org.springframework.security.web.FilterInvocation; 5 | import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource; 6 | 7 | import javax.servlet.http.HttpServletRequest; 8 | import java.util.Collection; 9 | 10 | //@Component("centitSecurityMetadataSource") 11 | public class DaoInvocationSecurityMetadataSource 12 | implements FilterInvocationSecurityMetadataSource { 13 | //private static final Logger logger = LoggerFactory.getLogger(DaoInvocationSecurityMetadataSource.class); 14 | //private static boolean logDebug = logger.isDebugEnabled(); 15 | @Override 16 | public boolean supports(Class clazz) { 17 | if (FilterInvocation.class.isAssignableFrom(clazz)) { 18 | return true; 19 | } 20 | return false; 21 | } 22 | 23 | @Override 24 | public Collection getAllConfigAttributes() { 25 | return null; 26 | } 27 | 28 | @Override 29 | // According to a URL, Find out permission configuration of this URL. 30 | public Collection getAttributes(Object object) throws IllegalArgumentException { 31 | // guess object is a URL. 32 | if ((object == null) || !this.supports(object.getClass())) { 33 | throw new IllegalArgumentException("对不起,目标对象不是类型"); 34 | } 35 | FilterInvocation fi = (FilterInvocation) object; 36 | HttpServletRequest request = fi.getHttpRequest(); 37 | String requestUrl = fi.getRequestUrl(); 38 | /* if (logDebug) { 39 | logger.debug("通过权限过滤器 请求url = " + requestUrl + " 请求类型 = " + request.getMethod()); 40 | }*/ 41 | return CentitSecurityMetadata.matchUrlToRole(requestUrl, request); 42 | /* Collection needRoles = CentitSecurityMetadata.matchUrlToRole(requestUrl,request); 43 | if(needRoles==null && requestUrl.contains("/mainframe/logincas")){ 44 | needRoles = new ArrayList<>(1); 45 | needRoles.add(new SecurityConfig(CentitSecurityMetadata.ROLE_PREFIX + SecurityContextUtils.PUBLIC_ROLE_CODE)); 46 | } 47 | return needRoles;*/ 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /framework-adapter/src/main/java/com/centit/framework/common/OptionItem.java: -------------------------------------------------------------------------------- 1 | package com.centit.framework.common; 2 | 3 | import com.centit.support.algorithm.StringBaseOpt; 4 | import org.apache.commons.lang3.StringUtils; 5 | 6 | import java.io.Serializable; 7 | 8 | public class OptionItem implements Serializable { 9 | private static final long serialVersionUID = 1L; 10 | 11 | private String name; 12 | 13 | private Serializable value; 14 | private Serializable group; 15 | 16 | public OptionItem(){ 17 | 18 | } 19 | public OptionItem(String name){ 20 | this.name = name; 21 | this.value = name; 22 | } 23 | 24 | public OptionItem(String name,Serializable value){ 25 | this.name = name; 26 | this.value = value; 27 | } 28 | 29 | public OptionItem(String name,Serializable value,Serializable group){ 30 | this.name = name; 31 | this.value = value; 32 | this.group = group; 33 | } 34 | 35 | public String getName() { 36 | return name; 37 | } 38 | 39 | public void setName(String name) { 40 | this.name = name; 41 | } 42 | 43 | public Serializable getValue() { 44 | return value; 45 | } 46 | 47 | public void setValue(Serializable value) { 48 | this.value = value; 49 | } 50 | 51 | public Serializable getGroup() { 52 | return group; 53 | } 54 | 55 | public void setGroup(Serializable group) { 56 | this.group = group; 57 | } 58 | 59 | @Override 60 | public int hashCode() { 61 | if(name==null) 62 | return 0; 63 | return name.hashCode(); 64 | } 65 | 66 | @Override 67 | public boolean equals(Object obj) { 68 | if(this==obj || value==obj) 69 | return true; 70 | if(obj==null) 71 | return false; 72 | 73 | if(obj instanceof String){ 74 | return StringUtils.equals(StringBaseOpt.objectToString(value), 75 | (String)obj); 76 | } 77 | 78 | if(obj instanceof OptionItem){ 79 | return StringUtils.equals(StringBaseOpt.objectToString(value), 80 | StringBaseOpt.objectToString(((OptionItem)obj).getValue())); 81 | } 82 | 83 | return StringUtils.equals(StringBaseOpt.objectToString(value), 84 | StringBaseOpt.objectToString(obj)); 85 | } 86 | 87 | 88 | } 89 | -------------------------------------------------------------------------------- /framework-adapter/src/main/java/com/centit/framework/model/adapter/MessageSender.java: -------------------------------------------------------------------------------- 1 | package com.centit.framework.model.adapter; 2 | 3 | import com.centit.framework.common.ResponseData; 4 | import com.centit.framework.model.basedata.NoticeMessage; 5 | import com.centit.support.common.DoubleAspect; 6 | 7 | import java.util.Collection; 8 | import java.util.HashMap; 9 | import java.util.Map; 10 | 11 | /** 12 | * 系统消息发送接口 13 | * 系统的内置的两个发送消息的实现,可以通过以下代码引入 14 | Resource(name = "innerMessageManager") 15 | NotNull 16 | private MessageSender innerMessageSender; 17 | 18 | Resource(name = "emailMessageSender") 19 | NotNull 20 | private MessageSender emailMessageSender; 21 | 注意:去掉@后的空格 22 | * @author codefan 23 | */ 24 | public interface MessageSender { 25 | 26 | /** 27 | * 发送内部系统消息 28 | * 29 | * @param sender 发送人内部用户编码 30 | * @param receiver 接收人内部用户编码 31 | * @param message 消息主体 32 | * @return "OK" 表示成功,其他的为错误信息 33 | */ 34 | ResponseData sendMessage(String sender, String receiver, NoticeMessage message); 35 | 36 | /** 37 | * 批量发送内部系统消息 38 | * 39 | * @param sender 发送人内部用户编码 40 | * @param receivers 接收人内部用户编码 41 | * @param message 消息主体 42 | * @return "OK" 表示成功,其他的为错误信息 43 | */ 44 | default ResponseData sendMessage(String sender, Collection receivers, NoticeMessage message){ 45 | int error = 0; int success = 0; 46 | Map result = new HashMap<>(); 47 | for (String receiver : receivers){ 48 | ResponseData response = sendMessage(sender, receiver, message); 49 | if(response.getCode() !=0){ 50 | error ++; 51 | result.put(receiver, response.getMessage()); 52 | } else { 53 | success ++; 54 | } 55 | } 56 | String msgStr = "一共发送" + (error+success) + "条消息,成功"+success+"条,失败"+error+"条。"; 57 | int resCode = error == 0? 0:(success==0?2:3); 58 | return ResponseData.makeErrorMessageWithData(result, resCode, msgStr); 59 | } 60 | 61 | /** 62 | * 广播信息 63 | * @param sender 发送人内部用户编码 64 | * @param message 消息主体 65 | * @param userInline DoubleAspec.ON 在线用户 OFF 离线用户 BOTH 所有用户 66 | * @return 默认没有实现 67 | */ 68 | default ResponseData broadcastMessage(String sender, NoticeMessage message, DoubleAspect userInline){ 69 | return ResponseData.errorResponse; 70 | } 71 | 72 | } 73 | -------------------------------------------------------------------------------- /framework-filter/src/main/java/com/centit/framework/filter/CacheResponseWrapper.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2003 Jayson Falkner (jayson@jspinsider.com) 3 | * This code is from "Servlets and JavaServer pages; the J2EE Web Tier", 4 | * http://www.jspbook.com. You may freely use the code both commercially 5 | * and non-commercially. If you like the code, please pick up a copy of 6 | * the book and help support the authors, development of more free code, 7 | * and the JSP/Servlet/J2EE community. 8 | */ 9 | package com.centit.framework.filter; 10 | 11 | import javax.servlet.ServletOutputStream; 12 | import javax.servlet.http.HttpServletResponse; 13 | import javax.servlet.http.HttpServletResponseWrapper; 14 | import java.io.IOException; 15 | import java.io.OutputStream; 16 | import java.io.OutputStreamWriter; 17 | import java.io.PrintWriter; 18 | 19 | public class CacheResponseWrapper 20 | extends HttpServletResponseWrapper { 21 | protected HttpServletResponse origResponse = null; 22 | protected ServletOutputStream stream = null; 23 | protected PrintWriter writer = null; 24 | protected OutputStream cache = null; 25 | 26 | public CacheResponseWrapper(HttpServletResponse response, 27 | OutputStream cache) { 28 | super(response); 29 | origResponse = response; 30 | this.cache = cache; 31 | } 32 | 33 | public ServletOutputStream createOutputStream() 34 | throws IOException { 35 | return (new CacheResponseStream(origResponse, cache)); 36 | } 37 | 38 | public void flushBuffer() throws IOException { 39 | stream.flush(); 40 | } 41 | 42 | public ServletOutputStream getOutputStream() 43 | throws IOException { 44 | if (writer != null) { 45 | throw new IllegalStateException( 46 | "getWriter() has already been called!"); 47 | } 48 | 49 | if (stream == null) 50 | stream = createOutputStream(); 51 | return (stream); 52 | } 53 | 54 | public PrintWriter getWriter() throws IOException { 55 | if (writer != null) { 56 | return (writer); 57 | } 58 | 59 | if (stream != null) { 60 | throw new IllegalStateException( 61 | "getOutputStream() has already been called!"); 62 | } 63 | 64 | stream = createOutputStream(); 65 | writer = new PrintWriter(new OutputStreamWriter(stream, "UTF-8")); 66 | return (writer); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /framework-filter/src/test/resources/xss_security_config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | true 5 | 6 | true 7 | 8 | true 9 | 10 | true 11 | 12 | true 13 | 14 | true 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | .*.*]]> 43 | 44 | 45 | 46 | 47 | 48 | .*[[.&[^a]]|[|a|\n|\r\n|\r|\u0085|\u2028|\u2029]]*]]> 49 | 50 | -------------------------------------------------------------------------------- /framework-core/src/test/java/com/centit/framework/test/TestPasswordEncoder.java: -------------------------------------------------------------------------------- 1 | package com.centit.framework.test; 2 | 3 | import com.centit.framework.security.StandardPasswordEncoderImpl; 4 | import org.junit.Test; 5 | 6 | /** 7 | * Created by codefan on 17-6-29. 8 | */ 9 | public class TestPasswordEncoder { 10 | @Test 11 | public void testCentitCrypt() { 12 | //093ce7e6c0476c39ce4a46ce53dbcc98b53c30c6baf92e98 13 | System.out.println(new StandardPasswordEncoderImpl().encodePassword("000000", "salt")); 14 | //System.out.println(CentitCrypt.cryptPassword2("000000", "salt", 11)); 15 | } 16 | 17 | public void testPE() { 18 | StandardPasswordEncoderImpl pe = new StandardPasswordEncoderImpl(); 19 | String password = pe.encodePassword("000000",null); 20 | System.out.println(password); 21 | 22 | password = pe.encodePassword("000000",null); 23 | System.out.println(password); 24 | password = pe.encodePassword("000000",null); 25 | System.out.println(password); 26 | password = pe.encodePassword("000000",null); 27 | System.out.println(password); 28 | password = pe.encodePassword("000000",null); 29 | System.out.println(password); 30 | password = pe.encodePassword("000000",null); 31 | System.out.println(password); 32 | 33 | System.out.println( 34 | pe.matches("000000","$2a$11$xLOqxWXU6laDFfbiHP/vmOCEHGXzawFJ5ZSRARTvA1ipUwS5m9lPS")); 35 | System.out.println( 36 | pe.matches("000000","$2a$11$DbyFNhHeCES5CKoMuM5sXepY7GM35sZkUSqQbjYJnFTzJ2GDIYGLK")); 37 | System.out.println( 38 | pe.matches("000000","$2a$11$u8YDC0UY.kfnpBanUOQaRO01bxFgOkvK.82QhMCaGJSsakrf3On9G")); 39 | System.out.println( 40 | pe.matches("000000","$2a$11$BXXUjbJqkhqcu4CvBRljhOwws/85qgGUqKrvZPsVnKCsrsemaKmEG")); 41 | System.out.println( 42 | pe.matches("000000","$2a$11$1vXImmiBQaiMss9UeHp8JeCKKwnqu5A0TfezczPomAtW6YeLylUKy")); 43 | System.out.println( 44 | pe.matches("000000","$2a$11$BM5bvHpT56ekl/i/Qw7v1u70a4hdJh9xCrn7.8bg.yF1vQRSFSLO.")); 45 | } 46 | } 47 | /* 48 | $2a$11$xLOqxWXU6laDFfbiHP/vmOCEHGXzawFJ5ZSRARTvA1ipUwS5m9lPS 49 | $2a$11$DbyFNhHeCES5CKoMuM5sXepY7GM35sZkUSqQbjYJnFTzJ2GDIYGLK 50 | $2a$11$u8YDC0UY.kfnpBanUOQaRO01bxFgOkvK.82QhMCaGJSsakrf3On9G 51 | $2a$11$BXXUjbJqkhqcu4CvBRljhOwws/85qgGUqKrvZPsVnKCsrsemaKmEG 52 | $2a$11$1vXImmiBQaiMss9UeHp8JeCKKwnqu5A0TfezczPomAtW6YeLylUKy 53 | $2a$11$BM5bvHpT56ekl/i/Qw7v1u70a4hdJh9xCrn7.8bg.yF1vQRSFSLO. 54 | */ 55 | -------------------------------------------------------------------------------- /framework-filter/src/main/resources/securityconfig/xss_security_config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | true 5 | 6 | true 7 | 8 | true 9 | 10 | true 11 | 12 | true 13 | 14 | true 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | .*.*]]> 43 | 44 | 45 | 46 | 47 | 48 | .*[[.&[^a]]|[|a|\n|\r\n|\r|\u0085|\u2028|\u2029]]*]]> 49 | 50 | -------------------------------------------------------------------------------- /framework-adapter/src/test/java/com/centit/framework/test/TestJson.java: -------------------------------------------------------------------------------- 1 | package com.centit.framework.test; 2 | 3 | import com.centit.framework.appclient.HttpReceiveJSON; 4 | import com.centit.framework.model.security.CentitPasswordEncoder; 5 | 6 | import java.util.List; 7 | 8 | /** 9 | * Created by codefan on 17-8-4. 10 | */ 11 | public class TestJson { 12 | public static void main(String[] args) { 13 | /*ResponseMapData resData = new ResponseMapData(); 14 | resData.addResponseData("hello","world"); 15 | resData.addResponseData("hello2","world"); 16 | System.out.println(resData.toJSONString()); 17 | System.out.println(JSON.toJSONString(true)); 18 | */ 19 | System.out.println(CentitPasswordEncoder.checkPasswordStrength("zs@SN123",8)); 20 | String jsonStr = "{\"code\":0,\"message\":\"ok\"," + 21 | "\"data\":{\"hello\":\"Say Hello to\", \"world\":\" json world!\"," + 22 | "\"int\":1024, \"bool\":false, \"intArr\":[1,2,3,4]}}"; 23 | HttpReceiveJSON json = HttpReceiveJSON.valueOfJson(jsonStr); 24 | System.out.println(json.getDataAsString()); 25 | System.out.println(json.getDataAsString("hello")+ json.getDataAsString("world")); 26 | System.out.println(json.getDataAsObject("int", Integer.class)); 27 | System.out.println(json.getDataAsObject("bool", Boolean.class)); 28 | System.out.println(json.getDataAsArray("intArr", Integer.class)); 29 | System.out.println(json.getOriginalJSON()); 30 | 31 | json = HttpReceiveJSON.valueOfJson( "[1,2,3,4,5]"); 32 | //Integer ints = json.getDataAsObject(Integer.class); 33 | List intList = json.getDataAsArray(Integer.class); 34 | for(Integer i:intList){ 35 | System.out.println(i); 36 | } 37 | json = HttpReceiveJSON.valueOfJson("102"); 38 | System.out.println(json.getDataAsObject(Integer.class)); 39 | 40 | json = HttpReceiveJSON.valueOfJson("true"); 41 | Boolean bo = json.getDataAsObject(Boolean.class); 42 | System.out.println(bo); 43 | 44 | jsonStr = "{\"c\":0,\"m\":\"ok\"," + 45 | "\"d\":[1,'hello',3,4,5]}"; 46 | json = HttpReceiveJSON.valueOfJson(jsonStr); 47 | System.out.println(json.getDataAsString()); 48 | System.out.println(json.getMessage()); 49 | 50 | System.out.println(json.getDataAsString("d")); 51 | 52 | List strList = json.getDataAsArray("d", String.class); 53 | for(String s:strList){ 54 | System.out.println(s); 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /framework-adapter/src/main/java/com/centit/framework/model/basedata/FVUserOptListId.java: -------------------------------------------------------------------------------- 1 | package com.centit.framework.model.basedata; 2 | 3 | import javax.persistence.Column; 4 | import javax.persistence.Embeddable; 5 | 6 | /** 7 | * FVUseroptlistId entity. 8 | * 9 | * @author MyEclipse Persistence Tools 10 | */ 11 | //用户业务操作 view的主键 12 | @Embeddable 13 | public class FVUserOptListId implements java.io.Serializable { 14 | 15 | // Fields 16 | private static final long serialVersionUID = 1L; 17 | @Column(name = "USER_CODE") 18 | private String userCode; //用户代码 19 | 20 | @Column(name = "OPT_CODE") 21 | private String optcode; //业务代码 22 | 23 | // Constructors 24 | 25 | /** 26 | * default constructor 27 | */ 28 | public FVUserOptListId() { 29 | } 30 | 31 | /** 32 | * minimal constructor 33 | * @param userCode String 34 | * @param optcode String 35 | */ 36 | public FVUserOptListId(String userCode, String optcode) { 37 | this.userCode = userCode; 38 | this.optcode = optcode; 39 | 40 | } 41 | 42 | 43 | // Property accessors 44 | 45 | public String getUserCode() { 46 | return this.userCode; 47 | } 48 | 49 | public void setUserCode(String userCode) { 50 | this.userCode = userCode; 51 | } 52 | 53 | public String getOptcode() { 54 | return this.optcode; 55 | } 56 | 57 | public void setOptcode(String optcode) { 58 | this.optcode = optcode; 59 | } 60 | 61 | public boolean equals(Object other) { 62 | if ((this == other)) 63 | return true; 64 | if ((other == null)) 65 | return false; 66 | if (!(other instanceof FVUserOptListId)) 67 | return false; 68 | FVUserOptListId castOther = (FVUserOptListId) other; 69 | 70 | return ((this.getUserCode() == castOther.getUserCode()) || (this 71 | .getUserCode() != null 72 | && castOther.getUserCode() != null && this.getUserCode() 73 | .equals(castOther.getUserCode()))) 74 | && ((this.getOptcode() == castOther.getOptcode()) || (this 75 | .getOptcode() != null 76 | && castOther.getOptcode() != null && this.getOptcode() 77 | .equals(castOther.getOptcode()))); 78 | } 79 | 80 | public int hashCode() { 81 | int result = 17; 82 | 83 | result = 37 * result 84 | + (getUserCode() == null ? 0 : this.getUserCode().hashCode()); 85 | result = 37 * result 86 | + (getOptcode() == null ? 0 : this.getOptcode().hashCode()); 87 | return result; 88 | } 89 | 90 | } 91 | -------------------------------------------------------------------------------- /framework-core/src/main/java/com/centit/framework/security/SM3PasswordEncoderImpl.java: -------------------------------------------------------------------------------- 1 | package com.centit.framework.security; 2 | 3 | import com.centit.framework.model.security.CentitPasswordEncoder; 4 | import com.centit.support.security.SM3Util; 5 | import org.apache.commons.codec.binary.Base64; 6 | import org.apache.commons.codec.binary.StringUtils; 7 | import org.springframework.security.crypto.password.PasswordEncoder; 8 | 9 | import java.util.function.Function; 10 | 11 | /** 12 | * Created by codefan on 17-1-20. 13 | * 采用Spring 推荐的 BCryptPasswordEncoder 加密方式 14 | */ 15 | public class SM3PasswordEncoderImpl 16 | implements CentitPasswordEncoder, PasswordEncoder { 17 | 18 | private Function passwordPreteat; 19 | 20 | public SM3PasswordEncoderImpl(){ 21 | passwordPreteat = null; 22 | } 23 | 24 | @Override 25 | public String encodePassword(String rawPass, Object salt) { 26 | return new String(Base64.encodeBase64URLSafe( 27 | SM3Util.hash(rawPass.getBytes()))); 28 | } 29 | 30 | @Override 31 | public String createPassword(String rawPass, Object salt){ 32 | return encodePassword( 33 | passwordPreteat != null ? passwordPreteat.apply(rawPass) : rawPass, 34 | salt); 35 | } 36 | 37 | @Override 38 | public boolean isPasswordValid(String encodedPassword, String rawPass, Object salt) { 39 | return StringUtils.equals( 40 | encodedPassword, encodePassword(rawPass, salt)); 41 | } 42 | 43 | /** 44 | * Encode the raw password. Generally, a good encoding algorithm applies a SHA-1 or 45 | * greater hash combined with an 8-byte or greater randomly generated salt. 46 | * 47 | * @param rawPassword 明文密码 48 | */ 49 | @Override 50 | public String encode(CharSequence rawPassword) { 51 | return encodePassword(String.valueOf(rawPassword), null); 52 | } 53 | 54 | /** 55 | * Verify the encoded password obtained from storage matches the submitted raw 56 | * password after it too is encoded. Returns true if the passwords match, false if 57 | * they do not. The stored password itself is never decoded. 58 | * 59 | * @param rawPassword 明文密码 the raw password to encode and match 60 | * @param encodedPassword the encoded password from storage to compare with 61 | * @return true if the raw password, after encoding, matches the encoded password from 62 | * storage ; 这个接口不支持 salt 63 | */ 64 | @Override 65 | public boolean matches(CharSequence rawPassword, String encodedPassword) { 66 | return isPasswordValid(String.valueOf(encodedPassword), 67 | String.valueOf(rawPassword), null); 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /framework-adapter/src/main/java/com/centit/framework/model/basedata/RolePowerId.java: -------------------------------------------------------------------------------- 1 | package com.centit.framework.model.basedata; 2 | 3 | import org.hibernate.validator.constraints.NotBlank; 4 | 5 | import javax.persistence.Column; 6 | import javax.persistence.Embeddable; 7 | 8 | /** 9 | * FRolepowerId entity. 10 | * 11 | * @author MyEclipse Persistence Tools 12 | */ 13 | @Embeddable 14 | public class RolePowerId implements java.io.Serializable { 15 | 16 | // Fields 17 | 18 | private static final long serialVersionUID = 1L; 19 | @Column(name = "ROLE_CODE") 20 | @NotBlank 21 | private String roleCode; //角色代码 22 | 23 | @Column(name = "OPT_CODE") 24 | @NotBlank 25 | private String optCode; //操作代码 26 | 27 | // Constructors 28 | 29 | /** 30 | * default constructor 31 | */ 32 | public RolePowerId() { 33 | } 34 | 35 | /** 36 | * full constructor 37 | * @param rolecode String 38 | * @param optcode String 39 | */ 40 | public RolePowerId(String rolecode, String optcode) { 41 | this.roleCode = rolecode; 42 | this.optCode = optcode; 43 | } 44 | 45 | // Property accessors 46 | 47 | public String getRoleCode() { 48 | return this.roleCode; 49 | } 50 | 51 | public void setRoleCode(String rolecode) { 52 | this.roleCode = rolecode; 53 | } 54 | 55 | public String getOptCode() { 56 | return this.optCode; 57 | } 58 | 59 | public void setOptCode(String optcode) { 60 | this.optCode = optcode; 61 | } 62 | 63 | public boolean equals(Object other) { 64 | if ((this == other)) 65 | return true; 66 | if ((other == null)) 67 | return false; 68 | if (!(other instanceof RolePowerId)) 69 | return false; 70 | RolePowerId castOther = (RolePowerId) other; 71 | 72 | return ((this.getRoleCode() == castOther.getRoleCode()) || (this 73 | .getRoleCode() != null 74 | && castOther.getRoleCode() != null && this.getRoleCode() 75 | .equals(castOther.getRoleCode()))) 76 | && ((this.getOptCode() == castOther.getOptCode()) || (this 77 | .getOptCode() != null 78 | && castOther.getOptCode() != null && this.getOptCode() 79 | .equals(castOther.getOptCode()))); 80 | } 81 | 82 | public int hashCode() { 83 | int result = 17; 84 | 85 | result = 37 * result 86 | + (getRoleCode() == null ? 0 : this.getRoleCode().hashCode()); 87 | result = 37 * result 88 | + (getOptCode() == null ? 0 : this.getOptCode().hashCode()); 89 | return result; 90 | } 91 | 92 | } 93 | -------------------------------------------------------------------------------- /framework-adapter/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | framework-parent 7 | com.centit.framework 8 | ${revision} 9 | 10 | 4.0.0 11 | framework-adapter 12 | com.centit.framework:framework-adapter 13 | jar 14 | 一组框架层的接口,用来对框架的底层服务进行替换 15 | 16 | 17 | 18 | com.centit.support 19 | centit-utils 20 | ${project.version} 21 | 22 | 23 | 24 | org.hibernate.validator 25 | hibernate-validator 26 | 27 | 28 | 29 | org.springframework.security 30 | spring-security-web 31 | 32 | 33 | 34 | javax.persistence 35 | javax.persistence-api 36 | provided 37 | true 38 | 39 | 40 | 41 | org.apache.commons 42 | commons-pool2 43 | 44 | 45 | 46 | org.springframework.security 47 | spring-security-core 48 | true 49 | 50 | 51 | 52 | 53 | javax.servlet 54 | javax.servlet-api 55 | 56 | 57 | 58 | io.swagger 59 | swagger-annotations 60 | 61 | 62 | 63 | org.projectlombok 64 | lombok 65 | 66 | 67 | 68 | com.centit.support 69 | centit-database 70 | ${project.version} 71 | 72 | 73 | 74 | 75 | 76 | -------------------------------------------------------------------------------- /framework-filter/src/main/java/com/centit/framework/filter/ResponseCorsFilter.java: -------------------------------------------------------------------------------- 1 | package com.centit.framework.filter; 2 | 3 | import javax.servlet.*; 4 | import javax.servlet.http.HttpServletRequest; 5 | import javax.servlet.http.HttpServletResponse; 6 | import java.io.IOException; 7 | 8 | /** 9 | * 允许跨站脚本访问过滤器 10 | * spring mvc 4.2 以上版本可以通过添加 @CrossOrigin 来更优雅的实现跨站访问 11 | * for-example : @CrossOrigin(origins = "*",allowCredentials="true",maxAge=86400) 12 | * @author codefan 13 | * 14 | */ 15 | public class ResponseCorsFilter implements Filter { 16 | @Override 17 | public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { 18 | 19 | HttpServletRequest request = (HttpServletRequest) servletRequest; 20 | if (servletResponse instanceof HttpServletResponse) { 21 | HttpServletResponse alteredResponse = (HttpServletResponse) servletResponse; 22 | if((request.getMethod().equals("OPTION") || request.getMethod().equals("OPTIONS")) && 23 | request.getServletPath().equals("/login")) { 24 | //System.out.println("request path match"); 25 | alteredResponse.setStatus(HttpServletResponse.SC_OK); 26 | addHeadersFor200Response(alteredResponse); 27 | return; 28 | } 29 | addHeadersFor200Response(alteredResponse); 30 | } 31 | 32 | filterChain.doFilter(servletRequest, servletResponse); 33 | } 34 | 35 | private void addHeadersFor200Response(HttpServletResponse response) { 36 | response.addHeader("Access-Control-Allow-Origin", "*"); 37 | response.addHeader("Access-Control-Allow-Credentials", "true");//允许cookies 38 | response.addHeader("Access-Control-Allow-Methods", "ACL, CANCELUPLOAD, CHECKIN, CHECKOUT, COPY, DELETE, GET, HEAD, LOCK, MKCALENDAR, MKCOL, MOVE, OPTIONS, POST, PROPFIND, PROPPATCH, PUT, REPORT, SEARCH, UNCHECKOUT, UNLOCK, UPDATE, VERSION-CONTROL"); 39 | response.addHeader("Access-Control-Allow-Headers", "useXDomain, withCredentials, Overwrite, Destination, Content-Type, Depth, User-Agent, Translate, Range, Content-Range, Timeout, X-File-Size, X-Requested-With, If-Modified-Since, X-File-Name, Cache-Control, Location, Lock-Token, If"); 40 | response.addHeader("Access-Control-Expose-Headers", "DAV, content-length, Allow"); 41 | response.addHeader("Access-Control-Max-Age", "86400"); 42 | } 43 | 44 | @Override 45 | public void destroy() { 46 | // TODO Auto-generated method stub 47 | 48 | } 49 | 50 | @Override 51 | public void init(FilterConfig arg0) throws ServletException { 52 | // TODO Auto-generated method stub 53 | 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /framework-config/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | framework-parent 7 | com.centit.framework 8 | ${revision} 9 | 10 | 4.0.0 11 | 12 | framework-config 13 | com.centit.framework:framework-config 14 | jar 15 | 框架配置类 16 | 17 | 18 | 19 | com.centit.framework 20 | framework-core 21 | ${project.version} 22 | provided 23 | 24 | 25 | 26 | com.centit.framework 27 | framework-security 28 | ${project.version} 29 | 30 | 31 | 32 | 33 | org.springframework.security 34 | spring-security-cas 35 | 41 | 42 | 43 | 44 | org.jasig.cas.client 45 | cas-client-core 46 | 47 | 48 | bcpkix-jdk15on 49 | org.bouncycastle 50 | 51 | 52 | 53 | 54 | 55 | 56 | org.springframework.session 57 | spring-session-core 58 | 59 | 60 | 61 | com.h2database 62 | h2 63 | 2.2.220 64 | compile 65 | 66 | 67 | 68 | javax.servlet 69 | javax.servlet-api 70 | provided 71 | 72 | 73 | 74 | 75 | 76 | -------------------------------------------------------------------------------- /framework-config/src/main/java/com/centit/framework/config/BaseSpringMvcConfig.java: -------------------------------------------------------------------------------- 1 | package com.centit.framework.config; 2 | 3 | import com.centit.framework.core.controller.MvcConfigUtil; 4 | import org.springframework.beans.BeansException; 5 | import org.springframework.context.ApplicationContext; 6 | import org.springframework.context.ApplicationContextAware; 7 | import org.springframework.context.annotation.EnableAspectJAutoProxy; 8 | import org.springframework.http.converter.HttpMessageConverter; 9 | import org.springframework.http.converter.StringHttpMessageConverter; 10 | import org.springframework.web.servlet.config.annotation.*; 11 | import org.springframework.web.servlet.view.InternalResourceViewResolver; 12 | 13 | import java.nio.charset.Charset; 14 | import java.nio.charset.StandardCharsets; 15 | import java.util.List; 16 | 17 | /** 18 | * Created by zou_wy on 2017/3/29. 19 | */ 20 | @EnableWebMvc 21 | @EnableAspectJAutoProxy(proxyTargetClass = true) 22 | public class BaseSpringMvcConfig implements WebMvcConfigurer, ApplicationContextAware { 23 | 24 | @Override 25 | public void configurePathMatch(PathMatchConfigurer configurer) { 26 | //configurer.setUseSuffixPatternMatch(false); 27 | configurer.setUseSuffixPatternMatch(false); 28 | } 29 | 30 | @Override 31 | public void configureMessageConverters(List> converters) { 32 | converters.add(MvcConfigUtil.fastJsonHttpMessageConverter()); 33 | converters.add(new StringHttpMessageConverter(StandardCharsets.UTF_8)); 34 | } 35 | 36 | @Override 37 | public void configureViewResolvers(ViewResolverRegistry registry) { 38 | InternalResourceViewResolver resolver = new InternalResourceViewResolver(); 39 | resolver.setViewClass(org.springframework.web.servlet.view.JstlView.class); 40 | resolver.setPrefix("/WEB-INF/jsp/"); 41 | resolver.setSuffix(".jsp"); 42 | registry.viewResolver(resolver); 43 | } 44 | 45 | /** 46 | * {@inheritDoc} 47 | *

This implementation is empty. 48 | */ 49 | @Override 50 | public void addResourceHandlers(ResourceHandlerRegistry registry) { 51 | registry.addResourceHandler("classpath:i18n/**"); 52 | } 53 | 54 | /** 55 | * 重型排序 return Value Handlers 56 | * @param applicationContext 应用环境上下文 57 | * @throws BeansException 异常 58 | */ 59 | @Override 60 | public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { 61 | MvcConfigUtil.setApplicationContext(applicationContext, 62 | MvcConfigUtil.fastJsonHttpMessageConverter()); 63 | } 64 | 65 | /*@Override 66 | public void configureHandlerExceptionResolvers(List exceptionResolvers) { 67 | exceptionResolvers.add(new GlobalHandlerExceptionResolver()); 68 | }*/ 69 | } 70 | -------------------------------------------------------------------------------- /framework-filter/src/main/java/com/centit/framework/filter/GZIPResponseWrapper.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2003 Jayson Falkner (jayson@jspinsider.com) 3 | * This code is from "Servlets and JavaServer pages; the J2EE Web Tier", 4 | * http://www.jspbook.com. You may freely use the code both commercially 5 | * and non-commercially. If you like the code, please pick up a copy of 6 | * the book and help support the authors, development of more free code, 7 | * and the JSP/Servlet/J2EE community. 8 | */ 9 | package com.centit.framework.filter; 10 | 11 | import org.slf4j.Logger; 12 | import org.slf4j.LoggerFactory; 13 | 14 | import javax.servlet.ServletOutputStream; 15 | import javax.servlet.http.HttpServletResponse; 16 | import javax.servlet.http.HttpServletResponseWrapper; 17 | import java.io.IOException; 18 | import java.io.OutputStreamWriter; 19 | import java.io.PrintWriter; 20 | 21 | public class GZIPResponseWrapper extends HttpServletResponseWrapper { 22 | protected HttpServletResponse origResponse = null; 23 | protected ServletOutputStream stream = null; 24 | protected PrintWriter writer = null; 25 | protected Logger logger = LoggerFactory.getLogger(GZIPResponseWrapper.class); 26 | public GZIPResponseWrapper(HttpServletResponse response) { 27 | super(response); 28 | origResponse = response; 29 | } 30 | 31 | public ServletOutputStream createOutputStream() throws IOException { 32 | return (new GZIPResponseStream(origResponse)); 33 | } 34 | 35 | public void finishResponse() { 36 | try { 37 | if (writer != null) { 38 | writer.close(); 39 | } else { 40 | if (stream != null) { 41 | stream.close(); 42 | } 43 | } 44 | } catch (IOException e) { 45 | logger.error(e.getMessage(),e);//e.printStackTrace(); 46 | } 47 | } 48 | 49 | public void flushBuffer() throws IOException { 50 | stream.flush(); 51 | } 52 | 53 | public ServletOutputStream getOutputStream() throws IOException { 54 | if (writer != null) { 55 | throw new IllegalStateException("getWriter() has already been called!"); 56 | } 57 | 58 | if (stream == null) 59 | stream = createOutputStream(); 60 | return (stream); 61 | } 62 | 63 | public PrintWriter getWriter() throws IOException { 64 | if (writer != null) { 65 | return (writer); 66 | } 67 | 68 | if (stream != null) { 69 | throw new IllegalStateException("getOutputStream() has already been called!"); 70 | } 71 | 72 | stream = createOutputStream(); 73 | writer = new PrintWriter(new OutputStreamWriter(stream, "UTF-8")); 74 | return (writer); 75 | } 76 | 77 | public void setContentLength(int length) { 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /framework-adapter/src/main/java/com/centit/framework/model/basedata/UserRoleId.java: -------------------------------------------------------------------------------- 1 | package com.centit.framework.model.basedata; 2 | 3 | import com.centit.framework.core.dao.DictionaryMap; 4 | import org.hibernate.validator.constraints.NotBlank; 5 | 6 | import javax.persistence.Column; 7 | import javax.persistence.Embeddable; 8 | 9 | /** 10 | * FUserroleId entity. 11 | * 12 | * @author MyEclipse Persistence Tools 13 | */ 14 | //用户角色的主键 15 | @Embeddable 16 | public class UserRoleId implements java.io.Serializable { 17 | 18 | // Fields 19 | private static final long serialVersionUID = 893187890652550538L; 20 | 21 | @Column(name = "USER_CODE") 22 | @NotBlank 23 | @DictionaryMap(value="userCode", fieldName = "userName") 24 | private String userCode;// 用户代码 25 | 26 | @Column(name = "ROLE_CODE") 27 | @NotBlank 28 | @DictionaryMap(value="roleCode", fieldName = "roleName") 29 | private String roleCode; // 角色代码 30 | 31 | // Constructors 32 | 33 | /** 34 | * default constructor 35 | */ 36 | public UserRoleId() { 37 | } 38 | 39 | /** 40 | * full constructor 41 | * @param userCode String 42 | * @param roleCode String 43 | */ 44 | public UserRoleId(String userCode, String roleCode) { 45 | this.userCode = userCode; 46 | this.roleCode = roleCode; 47 | } 48 | 49 | // Property accessors 50 | 51 | public String getUserCode() { 52 | return this.userCode; 53 | } 54 | 55 | public void setUserCode(String userCode) { 56 | this.userCode = userCode; 57 | } 58 | 59 | public String getRoleCode() { 60 | return this.roleCode; 61 | } 62 | 63 | public void setRoleCode(String rolecode) { 64 | this.roleCode = rolecode; 65 | } 66 | 67 | 68 | public boolean equals(Object other) { 69 | if ((this == other)) 70 | return true; 71 | if ((other == null)) 72 | return false; 73 | if (!(other instanceof UserRoleId)) 74 | return false; 75 | UserRoleId castOther = (UserRoleId) other; 76 | 77 | return ((this.getUserCode() == castOther.getUserCode()) || (this 78 | .getUserCode() != null 79 | && castOther.getUserCode() != null && this.getUserCode() 80 | .equals(castOther.getUserCode()))) 81 | && ((this.getRoleCode() == castOther.getRoleCode()) || (this 82 | .getRoleCode() != null 83 | && castOther.getRoleCode() != null && this 84 | .getRoleCode().equals(castOther.getRoleCode()))); 85 | } 86 | 87 | public int hashCode() { 88 | int result = 17; 89 | 90 | result = 37 * result 91 | + (getUserCode() == null ? 0 : this.getUserCode().hashCode()); 92 | result = 37 * result 93 | + (getRoleCode() == null ? 0 : this.getRoleCode().hashCode()); 94 | return result; 95 | } 96 | 97 | } 98 | -------------------------------------------------------------------------------- /framework-core/src/main/java/com/centit/framework/common/HttpContextUtils.java: -------------------------------------------------------------------------------- 1 | package com.centit.framework.common; 2 | 3 | /** 4 | * @author zfg 5 | */ 6 | 7 | import com.centit.framework.model.security.CentitUserDetails; 8 | import org.springframework.web.context.request.RequestContextHolder; 9 | import org.springframework.web.context.request.ServletRequestAttributes; 10 | 11 | import javax.servlet.http.HttpServletRequest; 12 | import javax.servlet.http.HttpSession; 13 | import java.util.Map; 14 | 15 | public class HttpContextUtils { 16 | 17 | //用來存储RPC调用时的session相关信息 18 | public static ThreadLocal> threadLocal = new ThreadLocal>(); 19 | 20 | public static HttpServletRequest getRequest() { 21 | ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); 22 | if (servletRequestAttributes == null) { 23 | return null; 24 | } 25 | HttpServletRequest request = servletRequestAttributes.getRequest(); 26 | return request; 27 | } 28 | 29 | public static HttpSession getSession() { 30 | if (getRequest() == null) { 31 | return null; 32 | } 33 | HttpSession session = getRequest().getSession(); 34 | return session; 35 | } 36 | 37 | /** 38 | * 获取sessionId 39 | * 40 | * @return 41 | */ 42 | public static String getSessionId() { 43 | HttpSession session = getSession(); 44 | if (null != session) { 45 | //从http session中获取 46 | return session.getId(); 47 | } else { 48 | //从线程本地存储中获取,判断当前线程是否有数据 49 | Map data = HttpContextUtils.threadLocal.get(); 50 | return null != data ? (String) data.get("sessionid") : null; 51 | } 52 | } 53 | 54 | private static CentitUserDetails getUserByThreadLocal() { 55 | //从线程本地存储中获取,判断当前线程是否有数据 56 | Map data = HttpContextUtils.threadLocal.get(); 57 | return null != data ? (CentitUserDetails) data.get("userinfo") : null; 58 | } 59 | 60 | public static CentitUserDetails getCurrentUserInfo() { 61 | HttpSession session = getSession(); 62 | if (null != session) { 63 | //从http session中获取 64 | CentitUserDetails centitUserDetails = WebOptUtils.innerGetUserDetail(session); 65 | if (centitUserDetails == null) { 66 | return getUserByThreadLocal(); 67 | } 68 | return centitUserDetails; 69 | } else { 70 | return getUserByThreadLocal(); 71 | } 72 | } 73 | 74 | public static String getTraceId() { 75 | Map data = HttpContextUtils.threadLocal.get(); 76 | return null != data ? (String) data.get("traceid") : null; 77 | } 78 | 79 | public static void clear() { 80 | threadLocal.remove(); 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /framework-adapter/src/main/java/com/centit/framework/model/basedata/UnitRoleId.java: -------------------------------------------------------------------------------- 1 | package com.centit.framework.model.basedata; 2 | 3 | import com.centit.framework.core.dao.DictionaryMap; 4 | import org.hibernate.validator.constraints.NotBlank; 5 | 6 | import javax.persistence.Column; 7 | import javax.persistence.Embeddable; 8 | 9 | /** 10 | * FUserroleId entity. 11 | * 12 | * @author MyEclipse Persistence Tools 13 | */ 14 | //用户角色的主键 15 | @Embeddable 16 | public class UnitRoleId implements java.io.Serializable { 17 | 18 | // Fields 19 | 20 | private static final long serialVersionUID = 893187890652550538L; 21 | 22 | @Column(name = "UNIT_CODE") 23 | @NotBlank 24 | @DictionaryMap(value="unitCode", fieldName = "unitName") 25 | private String unitCode;// 用户代码 26 | 27 | @Column(name = "ROLE_CODE") 28 | @NotBlank 29 | @DictionaryMap(value="roleCode", fieldName = "roleName") 30 | private String roleCode; // 角色代码 31 | 32 | // Constructors 33 | 34 | /** 35 | * default constructor 36 | */ 37 | public UnitRoleId() { 38 | } 39 | 40 | /** 41 | * full constructor 42 | * @param unitCode String 43 | * @param rolecode String 44 | */ 45 | public UnitRoleId(String unitCode, String rolecode) { 46 | this.unitCode = unitCode; 47 | this.roleCode = rolecode; 48 | } 49 | 50 | // Property accessors 51 | 52 | public String getUnitCode() { 53 | return this.unitCode; 54 | } 55 | 56 | public void setUnitCode(String userCode) { 57 | this.unitCode = userCode; 58 | } 59 | 60 | public String getRoleCode() { 61 | return this.roleCode; 62 | } 63 | 64 | public void setRoleCode(String rolecode) { 65 | this.roleCode = rolecode; 66 | } 67 | 68 | 69 | public boolean equals(Object other) { 70 | if ((this == other)) 71 | return true; 72 | if ((other == null)) 73 | return false; 74 | if (!(other instanceof UnitRoleId)) 75 | return false; 76 | UnitRoleId castOther = (UnitRoleId) other; 77 | 78 | return ((this.getUnitCode() == castOther.getUnitCode()) || (this 79 | .getUnitCode() != null 80 | && castOther.getUnitCode() != null && this.getUnitCode() 81 | .equals(castOther.getUnitCode()))) 82 | && ((this.getRoleCode() == castOther.getRoleCode()) || (this 83 | .getRoleCode() != null 84 | && castOther.getRoleCode() != null && this 85 | .getRoleCode().equals(castOther.getRoleCode()))); 86 | } 87 | 88 | public int hashCode() { 89 | int result = 17; 90 | 91 | result = 37 * result 92 | + (getUnitCode() == null ? 0 : this.getUnitCode().hashCode()); 93 | result = 37 * result 94 | + (getRoleCode() == null ? 0 : this.getRoleCode().hashCode()); 95 | return result; 96 | } 97 | 98 | } 99 | -------------------------------------------------------------------------------- /framework-adapter/src/main/java/com/centit/framework/model/basedata/DataDictionaryId.java: -------------------------------------------------------------------------------- 1 | package com.centit.framework.model.basedata; 2 | 3 | import org.hibernate.validator.constraints.NotBlank; 4 | 5 | import javax.persistence.Column; 6 | import javax.persistence.Embeddable; 7 | import javax.persistence.OrderBy; 8 | 9 | /** 10 | * FDatadictionaryId entity. 11 | * 12 | * @author MyEclipse Persistence Tools 13 | * @author codefan 14 | */ 15 | //数据字典的主键 16 | @Embeddable 17 | public class DataDictionaryId implements java.io.Serializable { 18 | private static final long serialVersionUID = -477457533900099603L; 19 | // Fields 20 | @OrderBy 21 | @Column(name = "CATALOG_CODE") 22 | @NotBlank 23 | private String catalogCode; // 类别代码 24 | 25 | @Column(name = "DATA_CODE") 26 | @NotBlank 27 | private String dataCode; // 数据代码 28 | 29 | // Constructors 30 | 31 | /** 32 | * default constructor 33 | */ 34 | public DataDictionaryId() { 35 | } 36 | 37 | /** 38 | * full constructor 39 | * @param catalogcode String 40 | * @param datacode String 41 | */ 42 | public DataDictionaryId(String catalogcode, String datacode) { 43 | this.catalogCode = catalogcode; 44 | this.dataCode = datacode; 45 | } 46 | 47 | // Property accessors 48 | 49 | public String getCatalogCode() { 50 | return this.catalogCode; 51 | } 52 | 53 | public void setCatalogCode(String catalogcode) { 54 | this.catalogCode = catalogcode; 55 | } 56 | 57 | public String getDataCode() { 58 | return this.dataCode; 59 | } 60 | 61 | public void setDataCode(String datacode) { 62 | this.dataCode = datacode; 63 | } 64 | 65 | public boolean equals(Object other) { 66 | if ((this == other)) 67 | return true; 68 | if ((other == null)) 69 | return false; 70 | if (!(other instanceof DataDictionaryId)) 71 | return false; 72 | DataDictionaryId castOther = (DataDictionaryId) other; 73 | 74 | return ((this.getCatalogCode() == castOther.getCatalogCode()) || (this 75 | .getCatalogCode() != null 76 | && castOther.getCatalogCode() != null && this.getCatalogCode() 77 | .equals(castOther.getCatalogCode()))) 78 | && ((this.getDataCode() == castOther.getDataCode()) || (this 79 | .getDataCode() != null 80 | && castOther.getDataCode() != null && this 81 | .getDataCode().equals(castOther.getDataCode()))); 82 | } 83 | 84 | public int hashCode() { 85 | int result = 17; 86 | 87 | result = 37 88 | * result 89 | + (getCatalogCode() == null ? 0 : this.getCatalogCode() 90 | .hashCode()); 91 | result = 37 * result 92 | + (getDataCode() == null ? 0 : this.getDataCode().hashCode()); 93 | return result; 94 | } 95 | 96 | } 97 | -------------------------------------------------------------------------------- /framework-dubbo-config/src/main/java/com/centit/framework/dubbo/config/DubboConfig.java: -------------------------------------------------------------------------------- 1 | package com.centit.framework.dubbo.config; 2 | 3 | import org.apache.dubbo.config.*; 4 | import org.slf4j.Logger; 5 | import org.slf4j.LoggerFactory; 6 | import org.springframework.beans.factory.annotation.Value; 7 | import org.springframework.context.annotation.Bean; 8 | 9 | public class DubboConfig { 10 | Logger logger = LoggerFactory.getLogger(DubboConfig.class); 11 | 12 | @Value("${centit.dubbo.nacos.url:nacos://192.168.134.10:8848}") 13 | private String nacosUrl; 14 | @Value("${centit.dubbo.app.name:centit-provider}") 15 | private String appName; 16 | @Value("${centit.dubbo.provider.timeout:50000}") 17 | private Integer timeout; 18 | 19 | @Value("${centit.dubbo.dubboprotocol.name:dubbo}") 20 | private String dubboProtocolName; 21 | @Value("${centit.dubbo.dubboprotocol.server:}") 22 | private String dubboprotocolServer; 23 | @Value("${centit.dubbo.dubboprotocol.port:20885}") 24 | private Integer dubboprotocolPort; 25 | 26 | @Value("${centit.dubbo.consumer.check:false}") 27 | private Boolean check; 28 | 29 | @Value("${centit.dubbo.consumer.retries:0}") 30 | private Integer retries; 31 | 32 | /** 33 | * 应用名 34 | * @return ApplicationConfig 35 | */ 36 | @Bean 37 | public ApplicationConfig applicationConfig() { 38 | ApplicationConfig applicationConfig = new ApplicationConfig(); 39 | applicationConfig.setName(appName); 40 | return applicationConfig; 41 | } 42 | 43 | /** 44 | * 地址配置 45 | * @return registryConfig 46 | */ 47 | @Bean 48 | public RegistryConfig registryConfig() { 49 | RegistryConfig registryConfig = new RegistryConfig(); 50 | registryConfig.setAddress(nacosUrl); 51 | return registryConfig; 52 | } 53 | 54 | /** 55 | * 56 | * @return providerConfig 57 | */ 58 | @Bean 59 | public ProviderConfig providerConfig() { 60 | ProviderConfig providerConfig = new ProviderConfig(); 61 | providerConfig.setTimeout(timeout); 62 | return providerConfig; 63 | } 64 | 65 | /** 66 | * 协议配置,等同于 67 | * @return ProtocolConfig 68 | */ 69 | @Bean 70 | public ProtocolConfig protocolConfig() { 71 | ProtocolConfig protocolConfig = new ProtocolConfig(); 72 | protocolConfig.setName(dubboProtocolName); 73 | protocolConfig.setPort(dubboprotocolPort); 74 | protocolConfig.setServer(dubboprotocolServer); 75 | return protocolConfig; 76 | } 77 | 78 | @Bean 79 | public ConsumerConfig consumerConfig(){ 80 | ConsumerConfig consumerConfig = new ConsumerConfig(); 81 | consumerConfig.setCheck(check); 82 | consumerConfig.setRetries(retries); 83 | return consumerConfig; 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /framework-security/src/main/java/com/centit/framework/security/AjaxAuthenticationFailureHandler.java: -------------------------------------------------------------------------------- 1 | package com.centit.framework.security; 2 | 3 | import com.centit.framework.common.JsonResultUtils; 4 | import com.centit.framework.common.ResponseData; 5 | import com.centit.framework.common.ResponseMapData; 6 | import com.centit.framework.common.WebOptUtils; 7 | import com.centit.framework.components.OperationLogCenter; 8 | import com.centit.framework.model.basedata.OperationLog; 9 | import com.centit.support.algorithm.DatetimeOpt; 10 | import com.centit.support.security.SecurityOptUtils; 11 | import org.springframework.security.authentication.CredentialsExpiredException; 12 | import org.springframework.security.core.AuthenticationException; 13 | import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler; 14 | 15 | import javax.servlet.ServletException; 16 | import javax.servlet.http.HttpServletRequest; 17 | import javax.servlet.http.HttpServletResponse; 18 | import java.io.IOException; 19 | 20 | public class AjaxAuthenticationFailureHandler extends SimpleUrlAuthenticationFailureHandler { 21 | 22 | private boolean writeLog = false; 23 | 24 | public void setWriteLog(boolean writeLog) { 25 | this.writeLog = writeLog; 26 | } 27 | 28 | public AjaxAuthenticationFailureHandler() { 29 | } 30 | 31 | @Override 32 | public void onAuthenticationFailure(HttpServletRequest request, 33 | HttpServletResponse response, AuthenticationException exception) 34 | throws IOException, ServletException { 35 | if(writeLog){ 36 | String loginName = SecurityOptUtils.decodeSecurityString(request.getParameter("username")); 37 | String loginHost = WebOptUtils.getRequestAddr(request);//request.getRemoteHost()+":"+request.getRemotePort(); 38 | OperationLogCenter.log( 39 | OperationLog.create().user(loginName).method("loginError").application("mainframe") 40 | .operation("login").content( 41 | "用户 :"+loginName+"于"+DatetimeOpt.convertDatetimeToString(DatetimeOpt.currentUtilDate()) 42 | + "从主机"+loginHost+"尝试登录,失败原因:"+exception.getMessage()).loginIp(loginHost)); 43 | } 44 | int tryTimes = CheckFailLogs.getHasTriedTimes(request); 45 | boolean isAjaxQuery = WebOptUtils.isAjax(request); 46 | if(isAjaxQuery){ 47 | ResponseMapData resData = new ResponseMapData( 48 | exception instanceof CredentialsExpiredException ? ResponseData.ERROR_USER_PASSWORD_EXPIRED 49 | : ResponseData.ERROR_USER_LOGIN_ERROR , 50 | exception.getMessage()); 51 | resData.addResponseData("hasTriedTimes", tryTimes); 52 | JsonResultUtils.writeResponseDataAsJson(resData, response); 53 | }else { 54 | request.setAttribute("hasTriedTimes",tryTimes); 55 | super.onAuthenticationFailure(request, response, exception); 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /framework-adapter/src/main/java/com/centit/framework/model/basedata/UserSettingId.java: -------------------------------------------------------------------------------- 1 | package com.centit.framework.model.basedata; 2 | 3 | import com.centit.framework.core.dao.DictionaryMap; 4 | import org.hibernate.validator.constraints.Length; 5 | 6 | import javax.persistence.Column; 7 | import javax.persistence.Embeddable; 8 | 9 | 10 | /** 11 | * UserSetting Id. 12 | * 13 | * @author codefan@codefan.com 14 | */ 15 | @Embeddable 16 | public class UserSettingId implements java.io.Serializable { 17 | private static final long serialVersionUID = 1L; 18 | /** 19 | * 用户代码 20 | */ 21 | @Column(name = "USER_CODE") 22 | @DictionaryMap(fieldName = "userName", value = "userCode") 23 | private String userCode; 24 | 25 | /** 26 | * 参数代码 27 | */ 28 | @Column(name = "PARAM_CODE") 29 | @Length(max = 16) 30 | private String paramCode; 31 | 32 | // Constructors 33 | 34 | /** 35 | * default constructor 36 | */ 37 | public UserSettingId() { 38 | } 39 | 40 | /** 41 | * full constructor 42 | * @param userCode String 43 | * @param paramCode String 44 | */ 45 | public UserSettingId(String userCode, String paramCode) { 46 | 47 | this.userCode = userCode; 48 | this.paramCode = paramCode; 49 | } 50 | 51 | 52 | public String getUserCode() { 53 | return this.userCode; 54 | } 55 | 56 | public void setUserCode(String userCode) { 57 | this.userCode = userCode; 58 | } 59 | 60 | public String getParamCode() { 61 | return this.paramCode; 62 | } 63 | 64 | public void setParamCode(String paramCode) { 65 | this.paramCode = paramCode; 66 | } 67 | 68 | 69 | public boolean equals(Object other) { 70 | if ((this == other)) 71 | return true; 72 | if ((other == null)) 73 | return false; 74 | if (!(other instanceof UserSettingId)) 75 | return false; 76 | 77 | UserSettingId castOther = (UserSettingId) other; 78 | boolean ret = true; 79 | 80 | ret =this.getUserCode() == castOther.getUserCode() || 81 | (this.getUserCode() != null && castOther.getUserCode() != null 82 | && this.getUserCode().equals(castOther.getUserCode())); 83 | 84 | ret = ret && (this.getParamCode() == castOther.getParamCode() || 85 | (this.getParamCode() != null && castOther.getParamCode() != null 86 | && this.getParamCode().equals(castOther.getParamCode()))); 87 | 88 | return ret; 89 | } 90 | 91 | public int hashCode() { 92 | int result = 17; 93 | 94 | result = 37 * result + 95 | (this.getUserCode() == null ? 0 : this.getUserCode().hashCode()); 96 | 97 | result = 37 * result + 98 | (this.getParamCode() == null ? 0 : this.getParamCode().hashCode()); 99 | 100 | return result; 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /framework-dubbo-config/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | framework-parent 7 | com.centit.framework 8 | ${revision} 9 | 10 | 4.0.0 11 | framework-dubbo-config 12 | com.centit.framework:framework-dubbo-server-config 13 | jar 14 | 15 | 16 | 17 | com.alibaba.nacos 18 | nacos-spring-context 19 | 1.1.1 20 | 21 | 22 | com.alibaba.nacos 23 | nacos-client 24 | 25 | 26 | 27 | 28 | 29 | org.apache.dubbo 30 | dubbo-registry-nacos 31 | 3.1.7 32 | 33 | 34 | io.netty 35 | netty-all 36 | 37 | 38 | 39 | 40 | 41 | org.apache.dubbo 42 | dubbo-spring-boot-starter 43 | 3.1.7 44 | 45 | 46 | io.netty 47 | netty-all 48 | 49 | 50 | 51 | 52 | org.slf4j 53 | slf4j-api 54 | 55 | 56 | com.centit.framework 57 | framework-core 58 | ${project.version} 59 | 60 | 61 | javax.servlet 62 | javax.servlet-api 63 | provided 64 | 65 | 66 | 67 | org.apache.dubbo 68 | dubbo-metrics-api 69 | 3.1.7 70 | 71 | 72 | io.micrometer 73 | micrometer-registry-prometheus 74 | 1.10.0 75 | 76 | 77 | 78 | -------------------------------------------------------------------------------- /framework-adapter/src/main/java/com/centit/framework/model/adapter/UserUnitFilterCalcContext.java: -------------------------------------------------------------------------------- 1 | package com.centit.framework.model.adapter; 2 | 3 | import com.centit.framework.model.basedata.UnitInfo; 4 | import com.centit.framework.model.basedata.UserInfo; 5 | import com.centit.framework.model.basedata.UserRole; 6 | import com.centit.framework.model.basedata.UserUnit; 7 | 8 | import java.util.List; 9 | import java.util.Map; 10 | import java.util.Set; 11 | 12 | public interface UserUnitFilterCalcContext { 13 | 14 | String getTopUnit(); 15 | 16 | void setVarTrans(UserUnitVariableTranslate varTrans); 17 | 18 | UserUnitVariableTranslate getVarTrans(); 19 | 20 | boolean hasError(); 21 | 22 | void clearError(); 23 | 24 | String getLastErrMsg(); 25 | 26 | void setLastErrMsg(String lastErrMsg); 27 | 28 | void clearParams() ; 29 | 30 | void addUnitParam(String paramName, String unitCode) ; 31 | 32 | void addAllUnitParam(Map> unitParam); 33 | 34 | void addUnitParam(String paramName, Set unitCodes); 35 | 36 | void addUserParam(String paramName, String userCode); 37 | 38 | void addAllUserParam(Map> userParam); 39 | 40 | void addUserParam(String paramName, Set userCodes); 41 | 42 | void addRankParam(String paramName, String r); 43 | 44 | void addAllRankParam(Map rankParam); 45 | 46 | Set getUnitCode(String paramName); 47 | 48 | Set getUserCode(String paramName); 49 | 50 | String getRank(String paramName); 51 | 52 | void setFormula(String sFormula); 53 | 54 | void writeBackAWord(String preWord); 55 | 56 | void setCanAcceptOpt(boolean canAcceptOpt); 57 | 58 | boolean isLabel(String sWord); 59 | 60 | String getAWord( ); 61 | 62 | boolean seekToRightBracket(); 63 | 64 | List listAllUserInfo(); 65 | 66 | List listAllUnitInfo(); 67 | 68 | /** 69 | * 获得机构所有的子机构 70 | * @param unitCode 机构代码 71 | * @return 子机构集合 72 | */ 73 | List listSubUnit(String unitCode); 74 | 75 | UserInfo getUserInfoByCode(String userCode); 76 | 77 | UnitInfo getUnitInfoByCode(String unitCode); 78 | 79 | UserInfo getUserInfoByWord(String userWord); 80 | 81 | UnitInfo getUnitInfoByWord(String unitWord); 82 | 83 | UnitInfo getUnitInfoByDepNo(String depNo); 84 | 85 | List listAllUserUnits(); 86 | 87 | List listUnitUsers(String unitCode); 88 | 89 | List listUserUnits(String userCode); 90 | 91 | List listUserRoles(String userCode); 92 | 93 | List listRoleUsers(String roleCode); 94 | 95 | //-----------------通用的常量--------------------- 96 | // 系统角色 97 | Map listAllSystemRole(); 98 | // 岗位 99 | Map listAllStation(); 100 | 101 | // 行政角色 代码、名称 、等级 102 | Map listAllRank(); 103 | 104 | String getUserRank(String userCode); 105 | 106 | String getUserUnitRank(String userCode, String unitCode); 107 | } 108 | -------------------------------------------------------------------------------- /framework-session-redis/src/main/java/com/centit/framework/session/redis/RedisSessionPersistenceConfig.java: -------------------------------------------------------------------------------- 1 | package com.centit.framework.session.redis; 2 | 3 | import com.centit.framework.session.CentitSessionRepo; 4 | import com.centit.support.security.SecurityOptUtils; 5 | import org.apache.commons.lang3.StringUtils; 6 | import org.slf4j.Logger; 7 | import org.slf4j.LoggerFactory; 8 | import org.springframework.beans.factory.annotation.Autowired; 9 | import org.springframework.beans.factory.annotation.Value; 10 | import org.springframework.context.annotation.Bean; 11 | import org.springframework.context.annotation.Configuration; 12 | import org.springframework.data.redis.connection.RedisConnectionFactory; 13 | import org.springframework.data.redis.connection.RedisPassword; 14 | import org.springframework.data.redis.connection.RedisStandaloneConfiguration; 15 | import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory; 16 | import org.springframework.security.core.session.SessionRegistry; 17 | import org.springframework.session.data.redis.RedisIndexedSessionRepository; 18 | import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession; 19 | import org.springframework.session.security.SpringSessionBackedSessionRegistry; 20 | /** 21 | * Created by zou_wy on 2017/6/14. 22 | */ 23 | @Configuration 24 | @EnableRedisHttpSession(maxInactiveIntervalInSeconds = 7200) 25 | public class RedisSessionPersistenceConfig{ 26 | private Logger logger = LoggerFactory.getLogger(RedisSessionPersistenceConfig.class); 27 | 28 | @Value("${session.redis.host:}") 29 | private String host; 30 | 31 | @Value("${session.redis.port:6379}") 32 | private Integer port; 33 | 34 | @Value("${session.redis.password:}") 35 | private String password; 36 | 37 | @Value("${session.redis.database:0}") 38 | private Integer database; 39 | 40 | @Bean 41 | public RedisConnectionFactory springSessionRedisConnectionFactory() { 42 | RedisStandaloneConfiguration configuration = 43 | new RedisStandaloneConfiguration(host,port); 44 | logger.debug("Redis Session服务器URL:"+host+":"+port+"/"+database); 45 | System.out.println("Redis Session服务器URL:"+host+":"+port+"/"+database); 46 | configuration.setDatabase(database); 47 | if(StringUtils.isNotBlank(password)){ 48 | configuration.setPassword(RedisPassword.of( 49 | SecurityOptUtils.decodeSecurityString(password))); 50 | } 51 | return new LettuceConnectionFactory(configuration); 52 | } 53 | 54 | @Bean 55 | public SessionRegistry sessionRegistry( 56 | @Autowired RedisIndexedSessionRepository sessionRepository){ 57 | // sessionRepository.setDefaultSerializer(new FastJsonRedisSerializer<>(Object.class)); 58 | SpringSessionBackedSessionRegistry sessionRegistry = new SpringSessionBackedSessionRegistry(sessionRepository); 59 | return sessionRegistry; 60 | } 61 | 62 | @Bean 63 | public CentitSessionRepo centitSessionRepo(@Autowired RedisIndexedSessionRepository sessionRepository){ 64 | return new CentitSessionRedisRepo(sessionRepository); 65 | } 66 | 67 | } 68 | -------------------------------------------------------------------------------- /centit-persistence-extend/src/main/java/com/centit/framework/core/service/impl/CurrentUserContext.java: -------------------------------------------------------------------------------- 1 | package com.centit.framework.core.service.impl; 2 | 3 | import com.centit.framework.components.CodeRepositoryUtil; 4 | import com.centit.framework.model.basedata.UnitInfo; 5 | import com.centit.framework.model.basedata.UserInfo; 6 | import com.centit.framework.model.basedata.UserRole; 7 | import com.centit.framework.model.basedata.UserUnit; 8 | import org.apache.commons.lang3.StringUtils; 9 | 10 | import java.util.ArrayList; 11 | import java.util.HashMap; 12 | import java.util.List; 13 | import java.util.Map; 14 | 15 | public class CurrentUserContext { 16 | public UserInfo userInfo; 17 | public String currentUnit; 18 | public String topUnit; 19 | 20 | public CurrentUserContext(UserInfo userInfo, String topUnit, String currentUnit){ 21 | this.userInfo = userInfo; 22 | this.topUnit = topUnit; 23 | this.currentUnit = StringUtils.isBlank(currentUnit)? 24 | userInfo.getPrimaryUnit() : currentUnit; 25 | } 26 | 27 | 28 | public UnitInfo getCurrentUnit(){ 29 | return CodeRepositoryUtil 30 | .getUnitInfoByCode(topUnit, currentUnit); 31 | } 32 | 33 | public UnitInfo getPrimaryUnit(){ 34 | return CodeRepositoryUtil 35 | .getUnitInfoByCode(topUnit, userInfo.getPrimaryUnit()); 36 | } 37 | 38 | public List listUserUnits(){ 39 | return CodeRepositoryUtil 40 | .listUserUnits(topUnit, userInfo.getUserCode()); 41 | } 42 | 43 | public Map> getRankUnitsMap(){ 44 | List userUnits = listUserUnits(); 45 | Map> rankUnits = new HashMap<>(5); 46 | for(UserUnit uu : userUnits ){ 47 | List rankUnit = rankUnits.get(uu.getUserRank()); 48 | if(rankUnit==null){ 49 | rankUnit = new ArrayList<>(4); 50 | } 51 | rankUnit.add(uu); 52 | rankUnits.put(uu.getUserRank(),rankUnit); 53 | } 54 | return rankUnits; 55 | } 56 | 57 | public Map> getStationUnitsMap(){ 58 | List userUnits = listUserUnits(); 59 | Map> stationUnits = new HashMap<>(5); 60 | for(UserUnit uu : userUnits ){ 61 | List stationUnit = stationUnits.get(uu.getUserStation()); 62 | if(stationUnit==null){ 63 | stationUnit = new ArrayList<>(4); 64 | } 65 | stationUnit.add(uu); 66 | stationUnits.put(uu.getUserStation(),stationUnit); 67 | } 68 | return stationUnits; 69 | } 70 | 71 | public List listUserRoles() { 72 | return CodeRepositoryUtil.listUserRoles(topUnit, userInfo.getUserCode()); 73 | } 74 | 75 | public List listSubUnits(){ 76 | return CodeRepositoryUtil.getSubUnits(topUnit, currentUnit); 77 | } 78 | 79 | public List listAllSubUnits(){ 80 | List allSubUnits=CodeRepositoryUtil.getAllSubUnits(topUnit, currentUnit); 81 | allSubUnits.add(CodeRepositoryUtil 82 | .getUnitInfoByCode(topUnit, currentUnit)); 83 | return allSubUnits; 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /framework-core/src/main/java/com/centit/framework/security/CentitSecurityMetadata.java: -------------------------------------------------------------------------------- 1 | package com.centit.framework.security; 2 | 3 | import com.centit.framework.components.CodeRepositoryCache; 4 | import com.centit.support.common.CachedMap; 5 | import org.springframework.security.access.ConfigAttribute; 6 | 7 | import javax.servlet.http.HttpServletRequest; 8 | import java.util.List; 9 | 10 | public abstract class CentitSecurityMetadata { 11 | 12 | public static final String ROLE_PREFIX = "R_"; 13 | public static boolean isForbiddenWhenAssigned = false; 14 | private final static SystemSecurityMetadata systemSecurityMetadata = new SystemSecurityMetadata(); 15 | private final static CachedMap> apiSecurityMetadata = 16 | new CachedMap<>((apiId)->CodeRepositoryCache.getPlatformEnvironment().getRolesWithApiId(apiId), 17 | CodeRepositoryCache.CACHE_FRESH_PERIOD_SECONDS); 18 | private static final String DDE_RUN = "/dde/run/"; 19 | private static final int DDE_RUN_TAG_LENGTH = 9; 20 | private static final String DDE_RUN_DRAFT = "draft"; 21 | 22 | 23 | public static void evictCache(int apiOrSystem){ 24 | if(apiOrSystem==0){ 25 | systemSecurityMetadata.evictCache(); 26 | }else /*if(apiOrSystem==1) */{ 27 | apiSecurityMetadata.evictCache(); 28 | } 29 | } 30 | /** 31 | * @param isForbiddenWhenAssigned 设置为true时,将url分配到菜单后 该url需要授权才能访问; 32 | * 设置为false时,将url分配到菜单后不会对该url进行拦截,只有将该url分配给某个角色,其他角色才会被拦截 33 | */ 34 | public static void setIsForbiddenWhenAssigned(boolean isForbiddenWhenAssigned) { 35 | CentitSecurityMetadata.isForbiddenWhenAssigned = isForbiddenWhenAssigned; 36 | } 37 | 38 | public static List matchUrlToRole(String sUrl, HttpServletRequest request) { 39 | //String apiId = parseUrlToApi(sUrl); 40 | //if (StringUtils.isBlank(apiId)) { 41 | return systemSecurityMetadata.matchUrlToRole(sUrl, request); 42 | //} 43 | //return apiSecurityMetadata.getCachedValue(apiId); 44 | } 45 | 46 | public static List getApiRoleList(String apiId) { 47 | return apiSecurityMetadata.getCachedValue(apiId); 48 | } 49 | 50 | public static String parseUrlToApi(String sUrl) { 51 | String apiId = ""; 52 | int nPos = sUrl.indexOf(DDE_RUN); 53 | if (nPos>=0){ 54 | int beginPos = nPos + DDE_RUN_TAG_LENGTH; 55 | int endPos = sUrl.indexOf('/', beginPos); 56 | if(endPos<=0){ 57 | endPos = sUrl.indexOf('?', beginPos); 58 | } 59 | if(endPos<=0){ 60 | endPos = sUrl.length(); 61 | } 62 | apiId = sUrl.substring(beginPos, endPos); 63 | if(DDE_RUN_DRAFT.equals(apiId)){ 64 | beginPos = endPos +1; 65 | endPos = sUrl.indexOf('/', beginPos); 66 | if(endPos<=0){ 67 | endPos = sUrl.indexOf('?', beginPos); 68 | } 69 | if(endPos<=0){ 70 | endPos = sUrl.length(); 71 | } 72 | return sUrl.substring(beginPos, endPos); 73 | } 74 | } 75 | return apiId; 76 | } 77 | 78 | } 79 | -------------------------------------------------------------------------------- /framework-adapter/src/main/java/com/centit/framework/model/basedata/NoticeMessage.java: -------------------------------------------------------------------------------- 1 | package com.centit.framework.model.basedata; 2 | 3 | import com.alibaba.fastjson2.JSON; 4 | import lombok.Data; 5 | 6 | import java.util.HashMap; 7 | import java.util.Map; 8 | 9 | @Data 10 | public class NoticeMessage implements java.io.Serializable { 11 | 12 | private static final long serialVersionUID = 1; 13 | private static String defaultMsgType = "msg"; 14 | /** 15 | * 消息类别 默认值 msg 16 | * 客户端可以根据不同的消息类别提供不同的 响应方式 或者 展示方式 17 | */ 18 | private String msgType; 19 | /** 消息主题 这不是必须的 20 | * */ 21 | private String msgSubject; 22 | /** 消息内容,为一个文本,不同的消息类别 可以有不同的格式 23 | */ 24 | private String msgContent; 25 | /** 26 | * 所属租户 27 | */ 28 | private String topUnit; 29 | /** 30 | * 所属业务id 31 | */ 32 | private String osId;//application id 33 | /** 关联业务 34 | */ 35 | private String optId; 36 | /**关联业务中的 方法、功能、模块 37 | */ 38 | private String optMethod; 39 | /** 关联对象组件,多个主键用url参数的方式链接 40 | */ 41 | private String optTag; 42 | 43 | /** 44 | * 扩展属性 45 | * 用于不同的消息类别提供不同的 发送消息参数 46 | */ 47 | private Map extProps; 48 | 49 | public static void setDefaultMsgType(String defaultMsgType) { 50 | NoticeMessage.defaultMsgType = defaultMsgType; 51 | } 52 | 53 | public NoticeMessage(){ 54 | this.extProps = null; 55 | this.msgType = defaultMsgType; 56 | } 57 | 58 | public static NoticeMessage create(){ 59 | return new NoticeMessage(); 60 | } 61 | 62 | public NoticeMessage typeOf(String stype){ 63 | this.msgType = stype; 64 | return this; 65 | } 66 | 67 | public NoticeMessage subject(String ssubject){ 68 | this.msgSubject = ssubject; 69 | return this; 70 | } 71 | 72 | public NoticeMessage content(String scontent){ 73 | this.msgContent = scontent; 74 | return this; 75 | } 76 | 77 | public NoticeMessage topUnit(String stopUnit){ 78 | this.topUnit = stopUnit; 79 | return this; 80 | } 81 | 82 | public NoticeMessage application(String osId){ 83 | this.osId = osId; 84 | return this; 85 | } 86 | 87 | public NoticeMessage operation(String soptid){ 88 | this.optId = soptid; 89 | return this; 90 | } 91 | 92 | public NoticeMessage method(String smethod){ 93 | this.optMethod = smethod; 94 | return this; 95 | } 96 | 97 | public NoticeMessage tag(String stag){ 98 | this.optTag = stag; 99 | return this; 100 | } 101 | 102 | public NoticeMessage extProp(String skey, Object svalue){ 103 | if(this.extProps==null){ 104 | this.extProps = new HashMap<>(); 105 | } 106 | this.extProps.put(skey, svalue); 107 | return this; 108 | } 109 | 110 | public Object getExtProp(String skey){ 111 | if(this.extProps==null){ 112 | return null; 113 | } 114 | return this.extProps.get(skey); 115 | } 116 | 117 | @Override 118 | public String toString() { 119 | return JSON.toJSONString(this); 120 | } 121 | } 122 | -------------------------------------------------------------------------------- /framework-core/src/main/java/com/centit/framework/security/StandardPasswordEncoderImpl.java: -------------------------------------------------------------------------------- 1 | package com.centit.framework.security; 2 | 3 | 4 | import com.centit.framework.model.security.CentitPasswordEncoder; 5 | import org.apache.commons.lang3.StringUtils; 6 | import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; 7 | import org.springframework.security.crypto.password.PasswordEncoder; 8 | 9 | import java.util.function.Function; 10 | 11 | /** 12 | * Created by codefan on 17-1-20. 13 | * 采用Spring 推荐的 BCryptPasswordEncoder 加密方式 14 | */ 15 | public class StandardPasswordEncoderImpl 16 | implements CentitPasswordEncoder, PasswordEncoder { 17 | 18 | private BCryptPasswordEncoder passwordEncoder; 19 | 20 | public void setPasswordPreteat(Function passwordPreteat) { 21 | this.passwordPreteat = passwordPreteat; 22 | } 23 | 24 | private Function passwordPreteat; 25 | 26 | public StandardPasswordEncoderImpl() { 27 | this(11); 28 | } 29 | 30 | public StandardPasswordEncoderImpl(int strength) { 31 | if (strength < 5 || strength > 31) { 32 | passwordEncoder = new BCryptPasswordEncoder(11); 33 | } else { 34 | passwordEncoder = new BCryptPasswordEncoder(strength); 35 | } 36 | passwordPreteat = null; 37 | } 38 | 39 | @Override 40 | public String encodePassword(String rawPass, Object salt) { 41 | return passwordEncoder.encode(rawPass); 42 | } 43 | 44 | @Override 45 | public String createPassword(String rawPass, Object salt) { 46 | return encodePassword(rawPass, salt); 47 | } 48 | 49 | @Override 50 | public boolean isPasswordValid(String encodedPassword, String rawPass, Object salt) { 51 | return passwordEncoder.matches(rawPass, encodedPassword); 52 | } 53 | 54 | /** 55 | * Encode the raw password. Generally, a good encoding algorithm applies a SHA-1 or 56 | * greater hash combined with an 8-byte or greater randomly generated salt. 57 | * 58 | * @param rawPassword rawPassword 59 | * @return encode 60 | */ 61 | @Override 62 | public String encode(CharSequence rawPassword) { 63 | return passwordEncoder.encode(rawPassword); 64 | } 65 | 66 | /** 67 | * Verify the encoded password obtained from storage matches the submitted raw 68 | * password after it too is encoded. Returns true if the passwords match, false if 69 | * they do not. The stored password itself is never decoded. 70 | * 71 | * @param rawPassword the raw password to encode and match 72 | * @param encodedPassword the encoded password from storage to compare with 73 | * @return true if the raw password, after encoding, matches the encoded password from 74 | * storage 75 | */ 76 | @Override 77 | public boolean matches(CharSequence rawPassword, String encodedPassword) { 78 | return passwordEncoder.matches(passwordPreteat != null ? passwordPreteat.apply(rawPassword.toString()) : rawPassword, encodedPassword); 79 | } 80 | 81 | @Override 82 | public boolean isCorrectPasswordFormat(String password) { 83 | if (StringUtils.isBlank(password) || password.length() < 48) { 84 | return false; 85 | } 86 | return password.charAt(0) == '$' 87 | && password.charAt(3) == '$' 88 | && password.charAt(6) == '$'; 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /framework-core-web/src/main/java/com/centit/framework/system/controller/EnvironmentController.java: -------------------------------------------------------------------------------- 1 | package com.centit.framework.system.controller; 2 | 3 | import com.centit.framework.common.ResponseData; 4 | import com.centit.framework.components.CodeRepositoryCache; 5 | import com.centit.framework.core.controller.BaseController; 6 | import com.centit.framework.core.controller.WrapUpResponseBody; 7 | import io.swagger.annotations.Api; 8 | import io.swagger.annotations.ApiImplicitParam; 9 | import io.swagger.annotations.ApiOperation; 10 | import org.springframework.stereotype.Controller; 11 | import org.springframework.web.bind.annotation.PathVariable; 12 | import org.springframework.web.bind.annotation.RequestMapping; 13 | import org.springframework.web.bind.annotation.RequestMethod; 14 | 15 | @Controller 16 | @RequestMapping("/environment") 17 | @Api(tags= "框架系统刷新缓存接口") 18 | public class EnvironmentController extends BaseController { 19 | 20 | public String getOptId (){ 21 | return "environment"; 22 | } 23 | 24 | /** 25 | * 系统心跳,有回复说明系统没有死机 26 | * @return ResponseData 27 | */ 28 | @ApiOperation(value="系统心跳",notes="系统心跳,有回复说明系统没有死机") 29 | @RequestMapping(value ="/heartbeat",method = RequestMethod.GET) 30 | @WrapUpResponseBody 31 | public ResponseData heartbeat() { 32 | return ResponseData.makeErrorMessage(0,"heartbeat Ok!"); 33 | } 34 | 35 | /** 36 | * 刷新框架中的所有缓存信息 37 | * @return ResponseData 38 | */ 39 | @ApiOperation(value="刷新框架中的所有缓存信息",notes="刷新框架中的所有缓存信息") 40 | //@PreAuthorize("hasPermission(#contact, 'admin')") 41 | @RequestMapping(value ="/reload/refreshall",method = RequestMethod.GET) 42 | @WrapUpResponseBody 43 | public ResponseData environmentRefreshAll() { 44 | CodeRepositoryCache.evictAllCache(); 45 | return ResponseData.makeErrorMessage(0,"缓存全部失效!"); 46 | } 47 | 48 | /** 49 | * 刷新指定的缓存 50 | * @param cacheCode 缓存名称 51 | * @return ResponseData 52 | */ 53 | @ApiOperation(value = "刷新指定的缓存", notes = "根据缓存名称刷新指定的缓存") 54 | @ApiImplicitParam( 55 | name = "cacheCode", value="缓存名称", 56 | required= true, paramType = "path", dataType= "String" 57 | ) 58 | @RequestMapping(value ="/reload/refresh/{cacheCode}",method = RequestMethod.GET) 59 | @WrapUpResponseBody 60 | public ResponseData environmentRefresh(@PathVariable String cacheCode) { 61 | CodeRepositoryCache.evictCache(cacheCode); 62 | return ResponseData.makeErrorMessage(0,"缓存"+cacheCode+"已失效!"); 63 | } 64 | 65 | /** 66 | * 刷新框架中和权限有关的缓存 67 | * @return ResponseData 68 | */ 69 | @ApiOperation(value = "刷新框架中和权限有关的缓存", notes = "刷新框架中和权限有关的缓存") 70 | @RequestMapping(value ="/reload/refreshpower",method = RequestMethod.GET) 71 | @WrapUpResponseBody 72 | public ResponseData environmentRefreshPower() { 73 | CodeRepositoryCache.evictCache("OptInfo"); 74 | CodeRepositoryCache.evictCache("OptMethod"); 75 | CodeRepositoryCache.evictCache("RoleInfo"); 76 | CodeRepositoryCache.evictCache("RolePower"); 77 | CodeRepositoryCache.evictCache("UserRoles"); 78 | CodeRepositoryCache.evictCache("RoleUsers"); 79 | CodeRepositoryCache.evictCache("UnitRoles"); 80 | CodeRepositoryCache.evictCache("RoleUnits"); 81 | CodeRepositoryCache.evictCache("optDataScope"); 82 | return ResponseData.makeErrorMessage(0,"和权限有关的缓存全部失效!"); 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /framework-core/src/main/java/com/centit/framework/core/aop/ResubmitDataAspect.java: -------------------------------------------------------------------------------- 1 | package com.centit.framework.core.aop; 2 | 3 | import com.centit.framework.common.WebOptUtils; 4 | import com.centit.support.algorithm.StringBaseOpt; 5 | import com.centit.support.common.ObjectException; 6 | import org.aspectj.lang.ProceedingJoinPoint; 7 | import org.aspectj.lang.annotation.Around; 8 | import org.aspectj.lang.annotation.Aspect; 9 | import org.aspectj.lang.reflect.MethodSignature; 10 | import org.slf4j.Logger; 11 | import org.slf4j.LoggerFactory; 12 | import org.springframework.stereotype.Component; 13 | import org.springframework.web.context.request.RequestContextHolder; 14 | import org.springframework.web.context.request.ServletRequestAttributes; 15 | 16 | import javax.servlet.ServletRequest; 17 | import javax.servlet.ServletResponse; 18 | import javax.servlet.http.HttpServletRequest; 19 | import javax.servlet.http.HttpSession; 20 | import java.lang.reflect.Method; 21 | 22 | /** 23 | * @ClassName RequestDataAspect 24 | * @Description 工作流重复提交校验 25 | **/ 26 | @Aspect 27 | @Component 28 | public class ResubmitDataAspect { 29 | protected Logger logger = LoggerFactory.getLogger(ResubmitDataAspect.class); 30 | 31 | private final static String DATA = "data"; 32 | private final static Object PRESENT = new Object(); 33 | 34 | @Around("@annotation(com.centit.framework.core.aop.NoRepeatCommit)") 35 | public Object handleResubmit(ProceedingJoinPoint joinPoint) throws Throwable { 36 | logger.info("spring AOP 提交校验submit 开始"); 37 | Method method = ((MethodSignature) joinPoint.getSignature()).getMethod(); 38 | //获取注解信息 39 | NoRepeatCommit annotation = method.getAnnotation(NoRepeatCommit.class); 40 | //通过 类名,方法名,当前用户,参数 来确定同一个提交; 41 | StringBuilder sb = new StringBuilder(method.getClass() 42 | .getName()).append(".").append(method.getName()); 43 | 44 | HttpServletRequest request = ((ServletRequestAttributes) 45 | RequestContextHolder.getRequestAttributes()).getRequest(); 46 | sb.append(",user:").append(WebOptUtils.getCurrentUserCode(request)); 47 | 48 | Object[] pointArgs = joinPoint.getArgs(); 49 | for(Object arg: pointArgs){ 50 | sb.append(","); 51 | if(arg instanceof ServletRequest || 52 | arg instanceof ServletResponse || 53 | arg instanceof HttpSession){ 54 | sb.append(arg.getClass().getName()); 55 | } else { 56 | sb.append(StringBaseOpt.objectToString(arg)); 57 | } 58 | } 59 | String key = ResubmitLock.handleKey(sb.toString()); 60 | //执行锁 61 | boolean lock = false; 62 | try { 63 | //设置解锁key 64 | //logger.info("spring AOP key: {}", key); 65 | lock = ResubmitLock.getInstance().lock(key, PRESENT); 66 | if (lock) { 67 | //logger.info("spring AOP 提交校验submit -> 放行"); 68 | //放行 69 | return joinPoint.proceed(); 70 | } else { 71 | logger.info("spring AOP 提交校验submit -> 重复提交"); 72 | //响应重复提交异常 73 | throw new ObjectException("spring AOP 提交校验submit:重复提交:" + sb ); 74 | } 75 | } finally { 76 | //设置解锁key和解锁时间 77 | ResubmitLock.getInstance().unLock(lock, key, annotation.delaySeconds()); 78 | logger.info("spring AOP 提交校验submit -> 解锁"); 79 | } 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /framework-security/src/main/java/com/centit/framework/security/AjaxAccessDeniedHandlerImpl.java: -------------------------------------------------------------------------------- 1 | package com.centit.framework.security; 2 | 3 | import com.centit.framework.common.JsonResultUtils; 4 | import com.centit.framework.common.ResponseData; 5 | import com.centit.framework.common.ResponseSingleData; 6 | import com.centit.framework.common.WebOptUtils; 7 | import org.apache.commons.lang3.StringUtils; 8 | import org.apache.commons.logging.Log; 9 | import org.apache.commons.logging.LogFactory; 10 | import org.springframework.security.access.AccessDeniedException; 11 | import org.springframework.security.web.WebAttributes; 12 | import org.springframework.security.web.access.AccessDeniedHandler; 13 | 14 | import javax.servlet.RequestDispatcher; 15 | import javax.servlet.ServletException; 16 | import javax.servlet.http.HttpServletRequest; 17 | import javax.servlet.http.HttpServletResponse; 18 | import java.io.IOException; 19 | 20 | public class AjaxAccessDeniedHandlerImpl implements AccessDeniedHandler { 21 | // ~ Static fields/initializers 22 | // ===================================================================================== 23 | 24 | protected static final Log logger = LogFactory.getLog(AjaxAccessDeniedHandlerImpl.class); 25 | 26 | // ~ Instance fields 27 | // ================================================================================================ 28 | 29 | private String errorPage; 30 | 31 | // ~ Methods 32 | // ======================================================================================================== 33 | 34 | @Override 35 | public void handle(HttpServletRequest request, HttpServletResponse response, 36 | AccessDeniedException accessDeniedException) throws IOException, 37 | ServletException { 38 | if(! WebOptUtils.isAjax(request) && StringUtils.isNotBlank(errorPage)) { 39 | request.setAttribute(WebAttributes.ACCESS_DENIED_403, 40 | accessDeniedException); 41 | // Set the 403 status code. 42 | response.setStatus(HttpServletResponse.SC_FORBIDDEN); 43 | // forward to error page. 44 | RequestDispatcher dispatcher = request.getRequestDispatcher(errorPage); 45 | dispatcher.forward(request, response); 46 | } else { 47 | if(WebOptUtils.exceptionNotAsHttpError){ 48 | ResponseSingleData responseData = 49 | new ResponseSingleData(ResponseData.ERROR_UNAUTHORIZED, 50 | "无权限访问!"); 51 | responseData.setData("无权限访问!"); 52 | JsonResultUtils.writeResponseDataAsJson(responseData, response); 53 | }else { 54 | JsonResultUtils.writeHttpErrorMessage(ResponseData.ERROR_UNAUTHORIZED, 55 | "无权限访问!", response); 56 | } 57 | } 58 | } 59 | 60 | /** 61 | * The error page to use. Must begin with a "/" and is interpreted relative to the 62 | * current context root. 63 | * 64 | * @param errorPage the dispatcher path to display 65 | * 66 | * @throws IllegalArgumentException if the argument doesn't comply with the above 67 | * limitations 68 | */ 69 | public void setErrorPage(String errorPage) { 70 | if ((errorPage != null) && !errorPage.startsWith("/")) { 71 | throw new IllegalArgumentException("errorPage must begin with '/'"); 72 | } 73 | 74 | this.errorPage = errorPage; 75 | } 76 | } 77 | 78 | -------------------------------------------------------------------------------- /framework-core/src/main/java/com/centit/framework/security/UserDetailsServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.centit.framework.security; 2 | 3 | import com.centit.framework.model.adapter.PlatformEnvironment; 4 | import com.centit.framework.model.security.CentitUserDetails; 5 | import com.centit.framework.model.security.CentitUserDetailsService; 6 | import org.springframework.security.core.Authentication; 7 | import org.springframework.security.core.GrantedAuthority; 8 | import org.springframework.security.core.userdetails.AuthenticationUserDetailsService; 9 | import org.springframework.security.core.userdetails.UserDetails; 10 | import org.springframework.security.core.userdetails.UsernameNotFoundException; 11 | 12 | import java.util.Collection; 13 | import java.util.regex.Matcher; 14 | import java.util.regex.Pattern; 15 | 16 | public class UserDetailsServiceImpl implements 17 | CentitUserDetailsService, 18 | AuthenticationUserDetailsService 19 | { 20 | private static Pattern pattern = Pattern.compile("[0-9]*"); 21 | private PlatformEnvironment platformEnvironment; 22 | 23 | public void setPlatformEnvironment(PlatformEnvironment platformEnvironment) { 24 | this.platformEnvironment = platformEnvironment; 25 | } 26 | 27 | //来自 UserDetailsService 28 | @Override 29 | public UserDetails loadUserByUsername(String userLoginName) throws UsernameNotFoundException { 30 | UserDetails ud = null; 31 | if(userLoginName.indexOf('@')>=0){//邮箱 32 | ud = loadDetailsByRegEmail(userLoginName); 33 | } else{ 34 | Matcher isNum = pattern.matcher(userLoginName); 35 | if(userLoginName.length() == 11 && isNum.matches()){ 36 | ud = loadDetailsByRegCellPhone(userLoginName); 37 | }else{ 38 | ud = loadDetailsByLoginName(userLoginName); 39 | } 40 | } 41 | if(ud==null) { 42 | throw new UsernameNotFoundException("用户名或密码错误"); 43 | } 44 | return ud; 45 | } 46 | 47 | //来自 AuthenticationUserDetailsService 48 | @Override 49 | public UserDetails loadUserDetails(Authentication token) throws UsernameNotFoundException { 50 | return loadUserByUsername(token.getName()); 51 | } 52 | 53 | @Override 54 | public Collection loadUserAuthorities(String loginname) throws UsernameNotFoundException { 55 | CentitUserDetails ud = loadDetailsByLoginName(loginname); 56 | if(ud==null) { 57 | return null; 58 | } 59 | return ud.getAuthorities(); 60 | } 61 | 62 | @Override 63 | public CentitUserDetails loadDetailsByLoginName(String loginName) { 64 | return platformEnvironment.loadUserDetailsByLoginName(loginName); 65 | } 66 | 67 | @Override 68 | public CentitUserDetails loadDetailsByUserCode(String userCode) { 69 | return platformEnvironment.loadUserDetailsByUserCode(userCode); 70 | } 71 | 72 | @Override 73 | public CentitUserDetails loadDetailsByRegEmail(String regEmail) { 74 | return platformEnvironment.loadUserDetailsByRegEmail(regEmail); 75 | } 76 | 77 | @Override 78 | public CentitUserDetails loadDetailsByRegCellPhone(String regCellPhone) { 79 | return platformEnvironment.loadUserDetailsByRegCellPhone(regCellPhone); 80 | } 81 | 82 | @Override 83 | public void saveUserSetting(String userCode, String paramCode, String paramValue, String paramClass, 84 | String paramName) { 85 | 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /framework-core/src/main/java/com/centit/framework/core/dao/DictionaryMapColumn.java: -------------------------------------------------------------------------------- 1 | package com.centit.framework.core.dao; 2 | 3 | import org.apache.commons.lang3.StringUtils; 4 | 5 | import java.io.Serializable; 6 | import java.util.ArrayList; 7 | import java.util.List; 8 | import java.util.Objects; 9 | 10 | public class DictionaryMapColumn implements Serializable { 11 | private static final long serialVersionUID = 1L; 12 | /**原始数据字段名*/ 13 | private String fieldName; 14 | /**新增数据字段名*/ 15 | private String mapFieldName; 16 | /**数据字典类别代码*/ 17 | private String dictCatalog; 18 | 19 | private boolean isExpression; 20 | 21 | public DictionaryMapColumn(){ 22 | fieldName = null; 23 | mapFieldName = null; 24 | isExpression = false; 25 | } 26 | 27 | /** 28 | * @param fn 原始数据字段名 29 | * @param mfn 新增数据字段名 30 | * @param catalog 数据字典类别代码 31 | */ 32 | public DictionaryMapColumn(String fn, String mfn, String catalog){ 33 | fieldName = fn; 34 | mapFieldName = mfn; 35 | dictCatalog = catalog; 36 | isExpression = false; 37 | } 38 | 39 | public static List mapAnnotation(String fn, DictionaryMap dictionaryMap){ 40 | if(/*dictionaryMap.value()==null ||*/ dictionaryMap.value().length==0) 41 | return null; 42 | List columns = new ArrayList<>(dictionaryMap.value().length); 43 | String [] fieldNams = dictionaryMap.fieldName(); 44 | int i=0; 45 | for(String sValue : dictionaryMap.value()){ 46 | DictionaryMapColumn col = new DictionaryMapColumn(); 47 | col.setFieldName(fn); 48 | col.setDictCatalog(sValue); 49 | col.setExpression(dictionaryMap.isExpression()); 50 | col.setMapFieldName( 51 | /*fieldNams !=null &&*/ fieldNams.length>i && StringUtils.isNotBlank(fieldNams[i])? 52 | fieldNams[i] : fn+ "Aux"+i); 53 | columns.add(col); 54 | i++; 55 | } 56 | return columns; 57 | } 58 | 59 | @Override 60 | public boolean equals(Object o) { 61 | if (this == o) return true; 62 | if (!(o instanceof DictionaryMapColumn)) return false; 63 | DictionaryMapColumn that = (DictionaryMapColumn) o; 64 | return Objects.equals(getFieldName(), that.getFieldName()) && 65 | Objects.equals(getMapFieldName(), that.getMapFieldName()); 66 | } 67 | 68 | @Override 69 | public int hashCode() { 70 | return Objects.hash(getFieldName(), getMapFieldName()); 71 | } 72 | 73 | public String getFieldName() { 74 | return fieldName; 75 | } 76 | 77 | public void setFieldName(String fieldName) { 78 | this.fieldName = fieldName; 79 | } 80 | 81 | public String getMapFieldName() { 82 | return mapFieldName; 83 | } 84 | 85 | public void setMapFieldName(String mapFieldName) { 86 | this.mapFieldName = mapFieldName; 87 | } 88 | 89 | public String getDictCatalog() { 90 | return dictCatalog; 91 | } 92 | 93 | public void setDictCatalog(String dictCatalog) { 94 | this.dictCatalog = dictCatalog; 95 | } 96 | 97 | public boolean isExpression() { 98 | return isExpression; 99 | } 100 | 101 | public void setExpression(boolean expression) { 102 | isExpression = expression; 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /framework-core/src/main/java/com/centit/framework/core/controller/MvcConfigUtil.java: -------------------------------------------------------------------------------- 1 | package com.centit.framework.core.controller; 2 | 3 | import com.alibaba.fastjson2.JSONReader; 4 | import com.alibaba.fastjson2.JSONWriter; 5 | import com.alibaba.fastjson2.support.config.FastJsonConfig; 6 | import com.alibaba.fastjson2.support.spring.http.converter.FastJsonHttpMessageConverter; 7 | import com.centit.support.json.JSONOpt; 8 | import org.springframework.beans.BeansException; 9 | import org.springframework.context.ApplicationContext; 10 | import org.springframework.http.MediaType; 11 | import org.springframework.web.method.support.HandlerMethodReturnValueHandler; 12 | import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter; 13 | 14 | import java.util.ArrayList; 15 | import java.util.List; 16 | 17 | public abstract class MvcConfigUtil { 18 | 19 | private static FastJsonHttpMessageConverter jsonHttpMessageConverter 20 | = createFastJsonHttpMessageConverter(); 21 | 22 | public static FastJsonHttpMessageConverter fastJsonHttpMessageConverter(){ 23 | return jsonHttpMessageConverter; 24 | } 25 | public static FastJsonHttpMessageConverter createFastJsonHttpMessageConverter(){ 26 | FastJsonHttpMessageConverter fastJsonHttpMessageConverter = 27 | new FastJsonHttpMessageConverter(); 28 | 29 | List supportedMediaTypes = new ArrayList<>(); 30 | supportedMediaTypes.add(MediaType.APPLICATION_JSON); 31 | supportedMediaTypes.add(MediaType.APPLICATION_JSON_UTF8); 32 | 33 | fastJsonHttpMessageConverter.setSupportedMediaTypes(supportedMediaTypes); 34 | 35 | JSONOpt.fastjsonGlobalConfig(); 36 | FastJsonConfig fastJsonConfig = new FastJsonConfig(); 37 | //Feature.AllowArbitraryCommas, Feature.DisableCircularReferenceDetect 38 | fastJsonConfig.setReaderFeatures(JSONReader.Feature.AllowUnQuotedFieldNames); 39 | fastJsonConfig.setWriterFeatures(JSONWriter.Feature.WriteEnumsUsingName); 40 | fastJsonConfig.setDateFormat("yyyy-MM-dd HH:mm:ss"); 41 | 42 | fastJsonHttpMessageConverter.setFastJsonConfig(fastJsonConfig); 43 | return fastJsonHttpMessageConverter; 44 | } 45 | 46 | public static void fastjsonGlobalConfig(){ 47 | JSONOpt.fastjsonGlobalConfig(); 48 | } 49 | 50 | public static void setApplicationContext(ApplicationContext applicationContext, FastJsonHttpMessageConverter jsonHttpMessageConverter) throws BeansException { 51 | 52 | RequestMappingHandlerAdapter requestMappingHandlerAdapter = 53 | applicationContext.getBean(RequestMappingHandlerAdapter.class); 54 | 55 | List sortedHandlers = new ArrayList<>(20); 56 | List defaultHandlers = requestMappingHandlerAdapter.getReturnValueHandlers(); 57 | 58 | // 建议都使用框架的这个注解处理,为了提高性能可以放在最前面: 59 | sortedHandlers.add(new WrapUpResponseBodyReturnValueHandler(jsonHttpMessageConverter)); 60 | sortedHandlers.addAll(defaultHandlers); 61 | // 下面的代码式 放到 Spring 定义的 Annotation-based 组中 排在 sortedHandlers 后面 62 | /*for(HandlerMethodReturnValueHandler handler : defaultHandlers ){ 63 | sortedHandlers.add(handler); 64 | if(handler instanceof RequestResponseBodyMethodProcessor){ 65 | sortedHandlers.add(new WrapUpResponseBodyReturnValueHandler(jsonHttpMessageConverter)); 66 | } 67 | }*/ 68 | requestMappingHandlerAdapter.setReturnValueHandlers(sortedHandlers); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /centit-persistence-extend/src/main/java/com/centit/framework/core/service/impl/DataScopePowerManagerImpl.java: -------------------------------------------------------------------------------- 1 | package com.centit.framework.core.service.impl; 2 | 3 | import com.centit.framework.components.CodeRepositoryUtil; 4 | import com.centit.framework.core.dao.DataPowerFilter; 5 | import com.centit.framework.core.service.DataScopePowerManager; 6 | import com.centit.framework.model.basedata.UserInfo; 7 | import com.centit.framework.model.security.CentitUserDetails; 8 | 9 | import java.util.List; 10 | 11 | public class DataScopePowerManagerImpl implements DataScopePowerManager { 12 | /** 13 | * 获取用户数据权限过滤器 14 | * @param sUserCode sUserCode 15 | * @param sOptId 业务名称 16 | * @param sOptMethod 对应的方法名称 17 | * @return 过滤条件列表,null或者空位不过来 18 | */ 19 | @Override 20 | public List listUserDataFiltersByOptIdAndMethod(String topUnit, String sUserCode, String sOptId, String sOptMethod) { 21 | return CodeRepositoryUtil.listUserDataFiltersByOptIdAndMethod(topUnit, sUserCode, sOptId, sOptMethod); 22 | } 23 | 24 | @Override 25 | public DataPowerFilter createUserDataPowerFilter(UserInfo userInfo, String topUnit, String currentUnit) { 26 | 27 | DataPowerFilter dpf = new DataPowerFilter(topUnit); 28 | //当前用户信息 29 | dpf.addSourceData("currentUser", userInfo); 30 | dpf.addSourceData("currentStation", currentUnit); 31 | dpf.addSourceData("topUnitCode",topUnit); 32 | dpf.addSourceData("currentUnitCode", currentUnit); 33 | 34 | CurrentUserContext context = new CurrentUserContext(userInfo, topUnit, currentUnit); 35 | dpf.addSourceData("currentUnit", context::getCurrentUnit); 36 | dpf.addSourceData("primaryUnit", context::getPrimaryUnit); 37 | dpf.addSourceData("userUnits", context::listUserUnits); 38 | dpf.addSourceData("rankUnits", context::getRankUnitsMap); 39 | dpf.addSourceData("stationUnits", context::getStationUnitsMap); 40 | dpf.addSourceData("userRoles", context::listUserRoles); 41 | dpf.addSourceData("allSubUnits", context::listAllSubUnits); 42 | dpf.addSourceData("subUnits", context::listSubUnits); 43 | return dpf; 44 | } 45 | 46 | @Override 47 | public DataPowerFilter createUserDataPowerFilter(CentitUserDetails userDetails) { 48 | 49 | DataPowerFilter dpf = new DataPowerFilter(userDetails.getTopUnitCode()); 50 | //当前用户信息 51 | dpf.addSourceData("currentUser", userDetails.getUserInfo()); 52 | dpf.addSourceData("currentUnit", userDetails.getCurrentStation()); 53 | dpf.addSourceData("currentStation", userDetails.getCurrentUnitCode()); 54 | dpf.addSourceData("currentUnitCode", userDetails.getCurrentUnitCode()); 55 | dpf.addSourceData("topUnitCode", userDetails.getTopUnitCode()); 56 | //dpf.addSourceData("userSetting", userDetails.getUserSettings()); 57 | dpf.addSourceData("userUnits", userDetails.getUserUnits()); 58 | dpf.addSourceData("userRoles", userDetails.getUserRoles()); 59 | CurrentUserContext context = new CurrentUserContext(userDetails.getUserInfo(), userDetails.getTopUnitCode(), 60 | userDetails.getCurrentUnitCode()); 61 | dpf.addSourceData("primaryUnit", context::getPrimaryUnit); 62 | dpf.addSourceData("rankUnits", context::getRankUnitsMap); 63 | dpf.addSourceData("stationUnits", context::getStationUnitsMap); 64 | dpf.addSourceData("allSubUnits", context::listAllSubUnits); 65 | dpf.addSourceData("subUnits", context::listSubUnits); 66 | return dpf; 67 | } 68 | 69 | } 70 | -------------------------------------------------------------------------------- /framework-adapter/src/main/java/com/centit/framework/model/basedata/FVUserOptList.java: -------------------------------------------------------------------------------- 1 | package com.centit.framework.model.basedata; 2 | 3 | import com.alibaba.fastjson2.annotation.JSONField; 4 | import org.hibernate.validator.constraints.Length; 5 | 6 | import javax.persistence.Column; 7 | import javax.persistence.EmbeddedId; 8 | import javax.persistence.Entity; 9 | import javax.persistence.Table; 10 | 11 | /** 12 | * FVUseroptlist entity. 13 | * 14 | * @author MyEclipse Persistence Tools 15 | */ 16 | //用户业务操作 view 17 | @Entity 18 | @Table(name = "F_V_USEROPTLIST") 19 | public class FVUserOptList implements java.io.Serializable { 20 | 21 | // Fields 22 | private static final long serialVersionUID = 1L; 23 | @JSONField(serialize = false, deserialize = false) 24 | @EmbeddedId 25 | private FVUserOptListId id; //主键 26 | 27 | @Column(name = "OPT_NAME") 28 | @Length(max = 50) 29 | private String optName; //业务名字 30 | 31 | @Column(name = "OPT_ID") 32 | @Length(max = 8) 33 | private String optId; //业务编号 34 | 35 | @Column(name = "OPT_METHOD") 36 | @Length(max = 50) 37 | private String optMethod; //业务方法?? 38 | 39 | // Constructors 40 | 41 | /** 42 | * default constructor 43 | */ 44 | public FVUserOptList() { 45 | } 46 | 47 | /** 48 | * full constructor 49 | * 50 | * @param id FVUserOptListId 51 | */ 52 | public FVUserOptList(FVUserOptListId id) { 53 | this.id = id; 54 | } 55 | 56 | /** 57 | * full constructor 58 | * 59 | * @param id FVUserOptListId 60 | * @param optname String 61 | * @param optid String 62 | * @param optmethod String 63 | */ 64 | public FVUserOptList(FVUserOptListId id, String optname, 65 | String optid, String optmethod) { 66 | this.id = id; 67 | this.optName = optname; 68 | this.optId = optid; 69 | this.optMethod = optmethod; 70 | } 71 | // Property accessors 72 | public FVUserOptListId getId() { 73 | return this.id; 74 | } 75 | 76 | public void setId(FVUserOptListId id) { 77 | this.id = id; 78 | } 79 | 80 | public String getUserCode() { 81 | if(this.id==null) 82 | this.id = new FVUserOptListId(); 83 | return this.id.getUserCode(); 84 | } 85 | 86 | public void setUserCode(String userCode) { 87 | if(this.id==null) 88 | this.id = new FVUserOptListId(); 89 | this.id.setUserCode(userCode); 90 | } 91 | 92 | public String getOptcode() { 93 | if(this.id==null) 94 | this.id = new FVUserOptListId(); 95 | return this.id.getOptcode(); 96 | } 97 | 98 | public void setOptcode(String optcode) { 99 | if(this.id==null) 100 | this.id = new FVUserOptListId(); 101 | this.id.setOptcode(optcode); 102 | } 103 | 104 | public String getOptName() { 105 | return this.optName; 106 | } 107 | 108 | public void setOptName(String optname) { 109 | this.optName = optname; 110 | } 111 | 112 | public String getOptId() { 113 | return this.optId; 114 | } 115 | 116 | public void setOptId(String optid) { 117 | this.optId = optid; 118 | } 119 | 120 | public String getOptMethod() { 121 | return this.optMethod; 122 | } 123 | 124 | public void setOptMethod(String optmethod) { 125 | this.optMethod = optmethod; 126 | } 127 | 128 | } 129 | -------------------------------------------------------------------------------- /framework-core/src/main/java/com/centit/framework/components/README.md: -------------------------------------------------------------------------------- 1 | # 公共组件 2 | 3 | ## 数据字典工具类 CodeRepositoryUtil 4 | 5 | 这个工具类通过静态方法可以访问框架中所有数据资源,包括: 6 | 1. 组织、人员、人员组织关系信息。 7 | 2. 操作、权限、角色信息。 8 | 3. 所有数据字典信息。 9 | 4. 配置参数信息。 10 | 11 | ## 机构过滤引擎 SysUnitFilterEngine 12 | 13 | 机构过滤引擎通过机构表达式过滤机构,机构表达式形式如下: 14 | 15 | 1. 常量:empty (空)| all (所有)| "机构代码" ;empty和all其实意义上是一样的,因为在节点机构中只能填写一个机构代码,如果空就表示所有,在权限表达式中如果要表示所有就要用all 16 | 2. 变量:C(当前操作用户所在机构)| P(上个节点机构)| F (流程所在机构)|N(节点所属机构)| L 相同节点上一个实例所在机构 (Last Same Node Instance UnitCode) 17 | 3. 数值:层次 18 | 4. 操作符:+ (下层机构,层次由后面的数值决定)| - (上层机构)| * (最上层机构的下层机构 ,+- 的层次是相对当前的机构来计算的,* 的层次是相对当前机构的最上层机构来计算的) 19 | 5. 简单表达式:变量|常量 | 常量 + 数值| 变量 *|+|- 数值 | 变量 - 数值 + 数值 20 | 6. 机构表达式: 简单表达式 | (机构表达式) | 机构表达式 || 机构表达式 | 机构表达式 && 机构表达式 | 机构表达式 ! 机构表达式 | S(机构表达式[,机构表达式]+) 21 | 22 | 机构表达式的结构是一个机构集合,||、&&、!均为集合运算符,||是取两个集合的并集,&&取两个集合的交集,!是在前一个集合中减去后一个集合。 23 | * S(机构表达式[,机构表达式]+) ,这个表达式表示返回多个表达式中的 第一个结果不为空的集合 24 | 25 | 表达式示例,示例中的表达式变量,无论是 U、P、F、L假设其值都是下图中的D111,红色框表示的。 26 | 27 | ![机构示意图](https://github.com/ndxt/ndxt.github.io/blob/master/docs/assets/jigoushiyitu.jpg) 28 | 29 | 简单表达式就一下10种形式 30 | 31 | 1. empty=> 32 | 2. all => D1,D2,D11,D12,D111,D112,D1111,D1112 33 | 3. “D12” =>D12 34 | 4. empty+1 =>D1,D2 35 | 5. all+1 => D11,D12,D111,D112,D1111,D1112 36 | 6. A => D111 37 | 7. U+1 => D1111,D1112 38 | 8. U-1 => D11 39 | 9. P-1+1 => D111,D112 40 | 11. W*1 => D1 41 | 42 | 机构表达式就是 简单表达式的基础上做集合运算。 节点的机构表达式只记录表达式返回的第一个机构,如果表达式返回的是空就记录空。 43 | 44 | ## 人员过滤引擎 SysUserFilterEngine 45 | 46 | 权限表达式组成主要由 机构、人员、岗位角色、行政角色或者行政角色等级来决定。 47 | 48 | 1. 机构表达式:参见上节 49 | 2. 人员表达式:("人员代码"| 变量,变量可以 C 当前操作人员即提交节点的人员 F 流程的所属人员 L 相同节点上一个实例所属人员 P 上一个节点操作人员)[, "人员代码"| 变量]* 50 | 3. 岗位角色:岗位角色代码[,岗位角色代码] * 51 | 4. 行政角色:行政角色代码[,行政角色代码] * 52 | 5. 行政角色等级 : R(等级常量)| R(变量,变量可以 C 业务的创建人比如申请人等级 O 当前操作人员即提交节点的人员等级)| R(变量+|-等级); 等级计算,+1,比表示当前等级低一等的最高级,比如,当前等级为3 ,+1范围4,如果没有4 只有5则返回5,-也一样 53 | 7. 权限简单表达式:[D/P(机构表达式,[机构表达式,]*)][gw(岗位角色)][xz(行政角色)|R(行政角色等级)] | RO(系统操作角色)| U(人员表达式) 54 | 8. 权限表达式 :权限简单表达式 | S(权限表达式[,权限表达式]+) | (权限表达式) | 权限表达式 || 权限表达式 | 权限表达式 && 权限表达式 | 权限表达式 ! 权限表达式 55 | 56 | 权限表达式的结构是一个人员集合,||、&&、!均为集合运算符,||是取两个集合的并集,&&取两个集合的交集,!是在前一个集合中减去后一个集合。 57 | 58 | * S(权限表达式[,权限表达式]+),这个表达式表示返回多个表达式中的 第一个结果不为空的集合。 59 | 60 | 工作流权限引擎中的机构表达式中有一个特有的变量N,N代表节点的所属机构及引用节点机构引擎的结果。 61 | 62 | D/P:D和P对应的都是机构表达式,不同的是D是选择所有的用户P只选择主机构用户,所以一个【权限简单表达式】中只能有一个D或者P,不能同时存在。 63 | 64 | ## OperationLogCenter 65 | 66 | 日志记录操作工具类,参见[日志写入操作](https://github.com/ndxt/centit-framework/tree/master/framework-core/src/main/java/com/centit/framework/operationlog)。 67 | 68 | ## impl/NotificationCenterImpl 69 | 70 | 通知中心的实现方式和操作日志不同,通知中心是也业务系统在同一个事务中的,所有没有提供工具类,而是通过bean的形式调用。 71 | 72 | 1. 开发人员通过通知中心调用消息的发送操作,并不关系具体的发送方式。 73 | 2. 通知中心可以注册多种发送方式,比如:邮件、短信等等,用户可以设置自己的接收方式,可以设置多种接收方式。 74 | 3. 业务系统可以开发自己的消息发送[MessageSender](https://github.com/ndxt/centit-framework/tree/master/framework-adapter/src/main/java/com/centit/framework/model/adapter)接口,并注册到通知中心中。 75 | 76 | 通知中心的配置方式如下: 77 | 78 | ```java 79 | /** 80 | * Created by codefan on 17-7-6. 81 | * 需要在配置类中创建这个 Bean 才能是日志生效 82 | */ 83 | public class InstantiationServiceBeanPostProcessor implements ApplicationListener 84 | { 85 | 86 | @Autowired 87 | protected NotificationCenter notificationCenter; 88 | 89 | @Autowired(required = false) 90 | private MessageSender innerMessageManager; 91 | 92 | @Override 93 | public void onApplicationEvent(ContextRefreshedEvent event) 94 | { 95 | if(innerMessageManager!=null) { 96 | //注入消息发送接口可以是多个 97 | notificationCenter.registerMessageSender("innerMsg", innerMessageManager); 98 | } 99 | } 100 | 101 | } 102 | 103 | ``` 104 | -------------------------------------------------------------------------------- /framework-security/src/main/java/com/centit/framework/security/AjaxAuthenticationSuccessHandler.java: -------------------------------------------------------------------------------- 1 | package com.centit.framework.security; 2 | 3 | import com.centit.framework.common.JsonResultUtils; 4 | import com.centit.framework.common.ResponseData; 5 | import com.centit.framework.common.WebOptUtils; 6 | import com.centit.framework.components.OperationLogCenter; 7 | import com.centit.framework.model.adapter.PlatformEnvironment; 8 | import com.centit.framework.model.basedata.OperationLog; 9 | import com.centit.framework.model.security.CentitUserDetails; 10 | import com.centit.support.algorithm.DatetimeOpt; 11 | import org.springframework.security.core.Authentication; 12 | import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler; 13 | 14 | import javax.servlet.ServletException; 15 | import javax.servlet.http.Cookie; 16 | import javax.servlet.http.HttpServletRequest; 17 | import javax.servlet.http.HttpServletResponse; 18 | import java.io.IOException; 19 | 20 | public class AjaxAuthenticationSuccessHandler extends SavedRequestAwareAuthenticationSuccessHandler { 21 | 22 | private boolean writeLog = false; 23 | 24 | public void setWriteLog(boolean writeLog) { 25 | this.writeLog = writeLog; 26 | } 27 | 28 | private PlatformEnvironment platformEnvironment; 29 | 30 | public void setPlatformEnvironment(PlatformEnvironment platformEnvironment) { 31 | this.platformEnvironment = platformEnvironment; 32 | } 33 | 34 | public AjaxAuthenticationSuccessHandler() { 35 | } 36 | 37 | public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, 38 | Authentication authentication) throws IOException, ServletException { 39 | 40 | CentitUserDetails ud = (CentitUserDetails) authentication.getPrincipal(); 41 | SecurityContextUtils.fetchAndSetLocalParams(ud, request, platformEnvironment); 42 | 43 | if(writeLog){ 44 | String remoteHost = request.getRemoteHost(); 45 | String loginIp = ud.getLoginIp(); 46 | if(!loginIp.startsWith(remoteHost)){ 47 | loginIp = remoteHost + ":" + loginIp; 48 | } 49 | String osId = request.getParameter("osId"); 50 | OperationLogCenter.log( 51 | OperationLog.create().user(ud.getUserCode()).operation("mainframe") 52 | .unit(ud.getCurrentUnitCode()).method("login") 53 | .content("用户 :"+ud.getUserInfo().getUserName() + " 于" 54 | +DatetimeOpt.convertDatetimeToString(DatetimeOpt.currentUtilDate()) + "从主机"+loginIp+"登录。") 55 | .loginIp(loginIp).topUnit(ud.getTopUnitCode()) 56 | .application(osId)); 57 | } 58 | Cookie cookie = new Cookie(WebOptUtils.SESSION_ID_TOKEN, 59 | request.getSession().getId()); 60 | cookie.setPath("/"); 61 | response.addCookie(cookie); 62 | boolean isAjaxQuery = WebOptUtils.isAjax(request); 63 | if(isAjaxQuery){ 64 | ResponseData resData = SecurityContextUtils.makeLoginSuccessResponse(ud, request); 65 | JsonResultUtils.writeResponseDataAsJson(resData, response); 66 | //request.getSession().setAttribute("SPRING_SECURITY_AUTHENTICATION", authentication); 67 | //JsonResultUtils.writeSingleErrorDataJson(0,authentication.getName() + " login ok!",request.getSession().getId(), response); 68 | }else{ 69 | response.setHeader(WebOptUtils.SESSION_ID_TOKEN, 70 | request.getSession().getId()); 71 | response.setHeader(SecurityContextUtils.SecurityContextTokenName, 72 | request.getSession().getId()); 73 | super.onAuthenticationSuccess(request, response, authentication); 74 | } 75 | } 76 | } 77 | --------------------------------------------------------------------------------