初始化

This commit is contained in:
zer0Black
2022-08-31 14:06:07 +08:00
commit 77ca26d6c7
447 changed files with 28526 additions and 0 deletions
+4
View File
@@ -0,0 +1,4 @@
/target/
/.idea/
*.iml
rebel.xml
+100
View File
@@ -0,0 +1,100 @@
## ADC-DA组件升级公告
2019.09.09
1.更新maven地址
2.adc-da-swagger版本升级导出doc的功能
3.代码生成器版本改成RELEASE
2019.03.04
1.框架2.3.0发布
2.代码生成器改为2.3.0-SNAPSHOT,修复生产缺少{}
3.Swagger组件升级至2.3.0,解决tags包含中文调用异常的问题
4.@MapperScan 位置转移
5.前端替换为layui版本
2019.01.21
@author LeeKwanho 李坤澔
组件改为Release 版本,自动检测私服的Jar包
升级Mysql驱动版本至8.0.13 支持SSL 连接 5.7支持SSL连接
2018.12.21
@author LeeKwanho 李坤澔
adc-da-base升级2.0.1BaseEntity的toString方法复习,实现返回对象本身属性
解决部分pom文件重复依赖的问题
2018.12.14
adc-da-util升级2.2.45,解决xss将类似updateTime视为非法字符的问题
2018.12.11
adc-da-sys 2.2.5
adc-da-login 2.2.10
adc-da-file 2.2.2
2018.11.2:
adc-da-gen升级2.2.0 代码生成器支持SQL Server
2018.10.24:
adc-da-login升级2.2.9 增加查询在线用户功能
2018.10.9:
adc-da-util升级2.2.43 解决空指针bug
2018.9.30:
adc-da-util升级2.2.5 增加低标准的xss过滤器来源于林工的售后件溯源系统需要低标准的xss过滤器
2018.8.31:
adc-da-login升级2.2.8 写入日志增加记录访问ip
2018.8.29:
adc-da-sys升级2.2.2 增加登录用户不能删除自己的限制
adc-da-login升级2.2.7 逻辑删除用户不能登录
2018.8.15:
adc-da-login升级2.2.6版本 测试部测试标准总变,验证码验证成功也要从Session里清空
2018.8.13:
adc-da-gen升级2.1.0版本 代码生成器支持MySQL
2018.7.27:
adc-da-sys升级到2.2.1版本 解决密码修改的问题
adc-da-login升级到2.2.3版本 解决密码修改的问题
2018.7.26:
adc-da-util升级到2.2.41版本 解决过滤json xss时转小写的问题
2018.7.16:
adc-da-util升级2.2.4版本 解决json的xss过滤问题
2018.7.12:
adc-da-util升级2.2.3版本 加入伪造JsessionID的安全测试Filter
adc-da-login升级2.2.2版本 解决安全测试问题
adc-da-login升级2.2.1版本 将main BusinessLogAspect类移入
+9
View File
@@ -0,0 +1,9 @@
FROM java:8
VOLUME /tmp
COPY ./adc-da-main/target/adc-da-main-2.5.0.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "app.jar", "--spring.profiles.active=test", "--server.port=8080", "> /log/app.log"]
+119
View File
@@ -0,0 +1,119 @@
# 数据资源中心高效研发框架 **ADC-DA**
## 1.官网地址
* http://221.239.111.146:50006/html/index.html
## 2.平台测试接口地址
* http://localhost:8080/swagger-ui.html
## 3.详细使用步骤 IDEA
0. 详细文档请参考官网,以下仅用IDEA演示
1. 忽略SSL验证
```sh
git config --global http.sslVerify false
```
2. 获取源码方式有二
|-1. 用Git Bash
```sh
git clone https://60.247.58.117:50018/ADC-DA-Open/ADC-DA-2.0.git
```
|-2. 用idea
![avatar](img/use_idea_git_01.PNG)![avatar](img/use_idea_git_02.PNG)
3. 启动平台 方法有二
|-1.从spring-bootrun启动
![avatar](img/spring-boot-run.PNG )
|-2.从AdcDaApplication启动 (可能需要修改pom.xml中的参数)
![avatar](img/adc_run.jpg)
* 若无法正常用idea运行,请将根目录下的pom.xml中的如下代码注释掉
```xml
<!-- Provided -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
<version>${spring.boot.version}</version>
</dependency>
```
3. 启动成功 访问swagger
|-1.
![avatar](img/Successful_startup.PNG)
|-2.
![avatar](img/swagger.PNG)
4. 访问前端页面
http://localhost:8080/index.html
layui版本框架可以直接访问,也可以采用nginx进行分离式部署
5. 启动nginx (建议)
|-1. 配置nginx目录下conf目录中的nginx.conf文件,不要用记事本编辑conf文件,可以用写字板或其他编写代码的程序
|-1.1 需要配置的有 serverrootproxy_pass
server {
listen 8011;
#前端端口号
root C:/IDEA/test/ADC-DA-2.0/adc-da-ui/src/main/resources;
#项目路径,定位到adc-da-ui/main/resources,注意"/"
location / {
# 动态页面 后端端口号
if ( !-e $request_filename) {
proxy_pass http://localhost:8080;
}
#root html;
#index index.html index.htm;
}
}
|-2.启动nginx 任务管理器-详细里面会有2个nginx信息
![avatar](img/nginx_start.PNG)
|-3. 访问 http://localhost:8011/html/index.html
|-3.1 如果可以访问 http://localhost:8011/swagger-ui.html ,不能访问index.html,则一定是root路径错误。
|-3.2若可以访问 http://localhost:8080/swagger-ui.html ,不能访问 http://localhost:8011/swagger-ui.html ,则一定是端口配置错误。
RSA非对称加密
methods: {
login () {
let pubkey = `MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAKtSP3y2DkyoDQsFGr6sn4saLBFwcijEPWsWQ1Hnz8sIvn7V3TyNrSesf+7nPgnUk9Gt/7aKsXUkY67BzMJ5xkECAwEAAQ==`
let pwd = this.encryptedData(pubkey, this.loginForm.password)
let username = this.encryptedData(pubkey, this.loginForm.username)
this.$axios
.post('/login', {
username: username,
password: pwd
})
.then(successRes => {
if (successRes.data.code === 200) {
this.$store.commit('login', this.loginForm)
let path = this.$route.query.redirect
this.$router.replace({path: path === '/' || path === undefined ? '/index' : path})
}
})
.catch(failRes => {
})
},
// 加密
encryptedData (publicKey, str) {
// 私钥 和后端沟通
// 新建JSEncrypt对象
let encryptor = new JSEncrypt()
// 设置公钥
encryptor.setPublicKey(publicKey)
// 加密数据
let decrypt = encryptor.encrypt(str.toString())
return decrypt
}
}
+53
View File
@@ -0,0 +1,53 @@
# 登录组件
## 2.3.1
date 2019-03-04
dingqiang 修复登陆错误缓存常驻内存的问题
## 2.3.0
继承2.2.11-SNAPSHOT改动
release-date 2019-1-30
0.增加校验验证码接口,增加角色鉴权功能
1.采用tags代替description
2.验证码加入参数由配置文件获取出现次数
3.base64加密默认UTF-8字符集
4.登录成功失败次数清零,取消初始化等多余操作
5.pom文件追加更新Release版本的配置
6.解决非序列化问题
## 2.2.11-SNAPSHOT
Date 2019-1-14
pom 文件修改,相关组件改为RELEASE版本
DATE 2019-1-11
增加校验验证码接口,增加角色鉴权功能
由 dingqiang 提交
## 2.2.10
release date 2018-11-06
在线人数bug修复
头像相关功能合并
## 2.2.9 / 2018-10-24
新增当前在线人数功能
新增更新用户信息接口
对get登录标记弃用
## 2.2.8
登陆写ip
## 2.3.1
修复登录错误次数永驻内存bug
+201
View File
@@ -0,0 +1,201 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>com.adc</groupId>
<artifactId>ca-data</artifactId>
<version>2.5.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>adc-da-login</artifactId>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<java_source_version>1.8</java_source_version>
<java_target_version>1.8</java_target_version>
<ehcache.version>2.6.6</ehcache.version>
<shiro.version>1.4.0-RC2</shiro.version>
<!--<spring.version>4.3.9.RELEASE</spring.version>-->
<aspectj.version>1.8.5</aspectj.version>
<org.apache.maven.plugins.version>3.7.0</org.apache.maven.plugins.version>
<!--adc-da-version-->
<adc-da-sys.version>4.0.0</adc-da-sys.version>
<adc-da-util.version>RELEASE</adc-da-util.version>
<adc-da-base.version>RELEASE</adc-da-base.version>
<adc-da-swagger.version>RELEASE</adc-da-swagger.version>
</properties>
<repositories>
<repository>
<id>central</id>
<url>http://60.247.58.121:8182/repository/public</url>
<releases>
<enabled>true</enabled>
<updatePolicy>always</updatePolicy>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
<repository>
<id>snapshot</id>
<url>http://60.247.58.121:8182/repository/snapshots/</url>
<releases>
<enabled>false</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
<updatePolicy>always</updatePolicy>
<checksumPolicy>warn</checksumPolicy>
</snapshots>
</repository>
</repositories>
<distributionManagement>
<repository>
<id>thirdparty</id>
<name>Nexus Thirdparty Repository</name>
<url>http://60.247.58.121:8182/repository/thirdparty/</url>
</repository>
<snapshotRepository>
<id>snapshots</id>
<name>User Project SNAPSHOTS</name>
<url>http://60.247.58.121:8182/repository/snapshots/</url>
</snapshotRepository>
</distributionManagement>
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.18</version>
</dependency>
<dependency>
<groupId>com.adc</groupId>
<artifactId>adc-da-base</artifactId>
<version>${adc-da-base.version}</version>
</dependency>
<dependency>
<groupId>com.adc</groupId>
<artifactId>adc-da-swagger</artifactId>
<version>${adc-da-swagger.version}</version>
<exclusions>
<exclusion>
<groupId>javax.mail</groupId>
<artifactId>mailapi</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.adc</groupId>
<artifactId>adc-da-util</artifactId>
<version>${adc-da-util.version}</version>
<exclusions>
<exclusion>
<artifactId>jackson-annotations</artifactId>
<groupId>com.fasterxml.jackson.core</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.adc</groupId>
<artifactId>adc-da-sys</artifactId>
<version>2.5.0</version>
<!--<exclusions>-->
<!--<exclusion>-->
<!--<artifactId>adc-da-util</artifactId>-->
<!--<groupId>com.adc</groupId>-->
<!--</exclusion>-->
<!--<exclusion>-->
<!--<artifactId>spring-context</artifactId>-->
<!--<groupId>org.springframework</groupId>-->
<!--</exclusion>-->
<!--</exclusions>-->
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>${aspectj.version}</version>
</dependency>
<!-- SECURITY begin -->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
<version>${shiro.version}</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>${shiro.version}</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-web</artifactId>
<version>${shiro.version}</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-ehcache</artifactId>
<version>${shiro.version}</version>
</dependency>
<!-- SECURITY end -->
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>2.0.1.Final</version>
</dependency>
<!-- EHCACHE begin -->
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache-core</artifactId>
<version>${ehcache.version}</version>
</dependency>
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache-web</artifactId>
<version>2.0.4</version>
</dependency>
<dependency>
<groupId>com.adc</groupId>
<artifactId>adc-da-util</artifactId>
<version>2.3.2</version>
</dependency>
<!-- EHCACHE end -->
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>${org.apache.maven.plugins.version}</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
<compilerVersion>${java.version}</compilerVersion>
<encoding>${project.build.sourceEncoding}</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.7</version>
</plugin>
</plugins>
</build>
</project>
@@ -0,0 +1,15 @@
package com.adc.da.login;
public enum LoginType {
PASSWORD("password"), // 密码登录
NOPASSWD("nopassword"); // 免密登录
private String code;// 状态值
private LoginType(String code) {
this.code = code;
}
public String getCode () {
return code;
}
}
@@ -0,0 +1,41 @@
package com.adc.da.login;
import com.adc.da.login.security.UsernamePasswordToken;
import com.adc.da.login.util.EncryptUtil;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
public class NewHashedCredentialsMatcher extends HashedCredentialsMatcher {
public NewHashedCredentialsMatcher(String hashAlgorithmName) {
super(hashAlgorithmName);
}
@Override
public boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) {
UsernamePasswordToken upt = (UsernamePasswordToken) token;
if(LoginType.NOPASSWD.equals(upt.getType())){
return true;
}
Object tokenHashedCredentials = encrypt((String.valueOf((upt.getPassword()))));
Object accountCredentials =info.getCredentials();
return equals(tokenHashedCredentials, accountCredentials);
}
// public boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) {
// UsernamePasswordToken upt = (UsernamePasswordToken)token;
// if (LoginType.NOPASSWD.equals(upt.getType())) {
// return true;
// } else {
// Object tokenHashedCredentials = this.hashProvidedCredentials(token, info);
// Object accountCredentials = this.getCredentials(info);
// return this.equals(tokenHashedCredentials, accountCredentials);
// }
// }
public String encrypt(String code){
return EncryptUtil.encrypt(code);
}
}
@@ -0,0 +1,136 @@
package com.adc.da.login.aspect;
import java.lang.reflect.Method;
import java.util.Date;
import com.adc.da.log.entity.LogEO;
import com.adc.da.sys.entity.UserEO;
import com.adc.da.util.utils.IpUtil;
import com.adc.da.util.utils.UUID;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import javax.annotation.Resource;
import org.springframework.stereotype.Component;
import com.adc.da.log.annotation.BusinessLog;
import com.adc.da.log.constant.LogConstants;
import com.adc.da.log.service.LogEOService;
import com.adc.da.login.util.UserUtils;
import com.adc.da.sys.dao.mysql.UserEODao;
import javax.servlet.http.HttpServletRequest;
/**
* 用于记录调用service层日志,
* 日志会记录在TS_LOG中
*
*/
@Aspect
@Component
public class BusinessLogAspect {
/**
* @see LogEOService
*/
@Resource
private LogEOService logEOService;
@Resource
private HttpServletRequest request;
@Resource
private UserEODao userEODao;
/**
* 读取配置文件
* 系统日志类别
* dev:开发模式不拦截方法记日志,
* custom:客户自定义需要拦截记日志的方法,
* sys:系统原设需要拦截记日志的方法
*/
// @Value("${sysLogType}")
private String sysLogType="custom";
/**
* 匹配Service层的save, update, delete, get, find, page等方法
* com.adc.da.login.rest
*/
@Pointcut(value = "( execution(* com.adc.da.*.controller..*(..)) " +
"|| execution(* com.adc.da.*.rest..*(..))) "
+ "&& !execution(* com.adc.da.log.service.LogEOService.*(..))")
private void servicePointcut() {
throw new UnsupportedOperationException("servicePointcut error");
}
@Around(value = "servicePointcut()")
public Object process(ProceedingJoinPoint joinPoint) throws Throwable {
Class cls = joinPoint.getTarget().getClass();
String signature = joinPoint.getSignature().getName();
Object result;
// 调用service层开始时间
long startTime = System.currentTimeMillis();
result = joinPoint.proceed();
// 调用service层结束时间
long endTime = System.currentTimeMillis();
// dev模式下不记系统日志
if (LogConstants.LOG_TYPE_DEV.equalsIgnoreCase(sysLogType)) {
return result;
}
String userId = UserUtils.getUserId();
// 非登录模式下不记系统日志
if (userId == null) {
return result;
}
// 业务日志组件开始工作,sys模式
if (LogConstants.LOG_TYPE_SYS.equalsIgnoreCase(sysLogType)) {
writeLog(cls.getName(), signature, null, userId, startTime, endTime);
} else {
for (Method method : cls.getDeclaredMethods()) {
BusinessLog logAnnotation = method.getAnnotation(BusinessLog.class);
if (logAnnotation != null) {
String methodName = method.getName();
if (signature.equals(methodName)) {
writeLog(cls.getName(), signature, logAnnotation.description(), userId, startTime, endTime);
}
}
}
}
// 业务日志组件工作结束
return result;
}
/**
* 写日志
*
* @param className 类名
* @param methodName 方法名
* @param logAnnotation 描述
* @param userId 用户名
* @param startTime 开始时间
* @param endTime 结束时间
* @throws Exception
*/
private void writeLog(String className, String methodName, String logAnnotation, String userId,
long startTime, long endTime) throws Exception {
// LogEO logEO = new LogEO();
// logEO.setId(UUID.randomUUID10());
//
// logEO.setClassName(className);
// logEO.setMethod(methodName);
// if (logAnnotation != null && !"".equals(logAnnotation)) {
// logEO.setDescription(logAnnotation);
// }
// logEO.setUsid(userId);
// UserEO userEO = userEODao.selectById(userId);
// // 写入ip信息
// logEO.setIpAddress(IpUtil.getIpAddr(request));
// if (userEO != null) {
// logEO.setAccount(userEO.getAccount());
// }
// logEO.setStartTime(new Date(startTime));
// logEO.setEndTime(new Date(endTime));
// logEOService.insertSelective(logEO);
}
}
@@ -0,0 +1,160 @@
package com.adc.da.login.config;
import com.adc.da.login.security.SystemAuthorizingRealm;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.cache.ehcache.EhCacheManager;
import org.apache.shiro.codec.Base64;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAO;
import org.apache.shiro.session.mgt.eis.JavaUuidSessionIdGenerator;
import org.apache.shiro.session.mgt.eis.SessionIdGenerator;
import org.apache.shiro.spring.LifecycleBeanPostProcessor;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.web.mgt.CookieRememberMeManager;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.servlet.SimpleCookie;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.cache.ehcache.EhCacheManagerFactoryBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;
import org.springframework.core.io.ClassPathResource;
/**
* shiro 配置
*/
@Configuration
public class ShiroConfiguration {
@Bean(name = "ehCacheManagerFactoryBean")
public EhCacheManagerFactoryBean ehCacheManagerFactoryBean() {
EhCacheManagerFactoryBean ehCacheManagerFactoryBean = new EhCacheManagerFactoryBean();
ClassPathResource classPathResource = new ClassPathResource("cache/ehcache-local.xml");
ehCacheManagerFactoryBean.setConfigLocation(classPathResource);
return ehCacheManagerFactoryBean;
}
@Bean(name = "shiroCacheManager")
@DependsOn({"ehCacheManagerFactoryBean"})
public EhCacheManager shiroCacheManager() {
EhCacheManager ehCacheManager = new EhCacheManager();
ehCacheManager.setCacheManager(ehCacheManagerFactoryBean().getObject());
return ehCacheManager;
}
@Bean
@DependsOn({"lifecycleBeanPostProcessor"})
public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
DefaultAdvisorAutoProxyCreator proxyCreator = new DefaultAdvisorAutoProxyCreator();
proxyCreator.setProxyTargetClass(true);
return proxyCreator;
}
/**
* @return
*/
@Bean(name = "lifecycleBeanPostProcessor")
public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {
return new LifecycleBeanPostProcessor();
}
@Bean(name = "securityManager")
public SecurityManager securityManager() {
DefaultWebSecurityManager defaultWebSecurityManager = new DefaultWebSecurityManager();
defaultWebSecurityManager.setRealm(systemAuthorizingRealm());
defaultWebSecurityManager.setCacheManager(shiroCacheManager());
SecurityUtils.setSecurityManager(defaultWebSecurityManager);
return defaultWebSecurityManager;
}
/**
* session管理器
*
* @author FastKing
* @date 13:06 2018/9/28
**/
@Bean(name = "defaultWebSessionManager")
public DefaultWebSessionManager getDefaultWebSessionManager() {
DefaultWebSessionManager defaultWebSessionManager = new DefaultWebSessionManager();
//设置过期时间30分钟
// defaultWebSessionManager.setGlobalSessionTimeout(1800000);
//session cookie
defaultWebSessionManager.setSessionIdCookie(getSessionIdCookie());
defaultWebSessionManager.setSessionIdCookieEnabled(true);
defaultWebSessionManager.setCacheManager(shiroCacheManager());
defaultWebSessionManager.setSessionDAO(sessionDao());
return defaultWebSessionManager;
}
@Bean(name = "sessionDao")
public EnterpriseCacheSessionDAO sessionDao() {
EnterpriseCacheSessionDAO sessionDao = new EnterpriseCacheSessionDAO();
sessionDao.setActiveSessionsCacheName("shiro-activeSessionCache");
//sessionId生成器
sessionDao.setSessionIdGenerator(sessionIdGenerator());
return sessionDao;
}
/**
* 配置会话ID生成器
*
* @return
*/
@Bean
public SessionIdGenerator sessionIdGenerator() {
return new JavaUuidSessionIdGenerator();
}
/**
* rememberMe cookie对象
*
* @author FastKing
* @date 12:49 2018/9/28
**/
private SimpleCookie rememberMeCookie() {
SimpleCookie simpleCookie = new SimpleCookie("rememberMe");
//防止cookie暴露给客户端
simpleCookie.setHttpOnly(true);
//设置过期时间30天
//simpleCookie.setMaxAge(2592000);
return simpleCookie;
}
private SimpleCookie getSessionIdCookie() {
SimpleCookie simpleCookie = new SimpleCookie("sid");
simpleCookie.setHttpOnly(true);
// simpleCookie.setMaxAge(-1);
return simpleCookie;
}
/**
* 记住我管理器
*
* @author FastKing
* @date 12:52 2018/9/28
**/
private CookieRememberMeManager cookieRememberMeManager() {
CookieRememberMeManager cookieRememberMeManager = new CookieRememberMeManager();
cookieRememberMeManager.setCookie(rememberMeCookie());
cookieRememberMeManager.setCipherKey(Base64.decode("4AvVhmFLUs0KTA3Kprsdag=="));
return cookieRememberMeManager;
}
@Bean
public SystemAuthorizingRealm systemAuthorizingRealm() {
return new SystemAuthorizingRealm();
}
@Bean
public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor() {
AuthorizationAttributeSourceAdvisor advisor = new AuthorizationAttributeSourceAdvisor();
advisor.setSecurityManager(securityManager());
return advisor;
}
}
@@ -0,0 +1,153 @@
package com.adc.da.login.config;
import com.adc.da.login.filter.BasicAuthFilter;
import com.adc.da.login.filter.DdmRSAAuthFilter;
import com.adc.da.login.filter.jwtFilter;
import com.adc.da.login.security.AdcFormAuthenticationFilter;
import com.adc.da.util.constant.GlobalConfig;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import javax.annotation.Resource;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import sun.misc.Cache;
import javax.annotation.PostConstruct;
import javax.servlet.Filter;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
/**
* shiro 权限配置
* 设置各连接的权限需求
*/
@Configuration
public class ShiroFilterConfiguration {
private static final String LOGIN = "/login";
/**
* 认证用户,需要登录才能使用的接口
*/
private static final String AUTHC = "authc";
/**
* 匿名用户,无需登录
*/
private static final String ANON = "anon";
private String portalPath = "";
@Resource
private Environment env;
/**
* 初始化,设置adminPath和restPath
* 参数在 application.properties 下
* 预设 adminPath = /a
* 预设 restPath =/api
*/
@PostConstruct
public void init() {
GlobalConfig.setAdminPath(env.getProperty("adminPath"));
GlobalConfig.setRestApiPath(env.getProperty("restPath"));
portalPath=env.getProperty("portalPath");
}
/**
* 设置过滤器
*
* @param securityManager 必须参数
*/
@Bean(name = "shiroFilter")
public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager) {
String adminPath = GlobalConfig.getAdminPath();
String restPath = GlobalConfig.getRestApiPath();
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
/* 必须参数 */
shiroFilterFactoryBean.setSecurityManager(securityManager);
//未登录跳转的url
shiroFilterFactoryBean.setLoginUrl("/notLogin");
// 设置无权限时跳转的 url;
shiroFilterFactoryBean.setUnauthorizedUrl("/notRole");
/* 登陆成功跳转页,可选参数 */
shiroFilterFactoryBean.setSuccessUrl(restPath);
Map<String, Filter> filterMap = new LinkedHashMap<>();
filterMap.put(AUTHC, new AdcFormAuthenticationFilter());
filterMap.put("jwtFilter",new jwtFilter());
filterMap.put("ddmFilter",new DdmRSAAuthFilter());
shiroFilterFactoryBean.setFilters(filterMap);
Map<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
/* 校验单点登录ticket 不需要认证 */
filterChainDefinitionMap.put(restPath + "/login", ANON);
/* 登出不需认证 */
filterChainDefinitionMap.put(restPath + "/logout/**", ANON);
/* 验证码,不需要认证 */
filterChainDefinitionMap.put(restPath + "/verifyCode", ANON);
/* 注册,不需要认证 */
filterChainDefinitionMap.put(restPath + "/register", ANON);
/* 找回密码,不需要认证 */
filterChainDefinitionMap.put(restPath + "/findPassWord", ANON);
/* 找回密码,不需要认证 */
filterChainDefinitionMap.put(restPath + "/sendPassWord", ANON);
/* 注册链接,不需要认证 */
filterChainDefinitionMap.put(restPath + "/registerUser", ANON);
/* 验证码预校验,不需要认证 */
filterChainDefinitionMap.put(restPath + "/judgeVerify", ANON);
/* 用户信息不用认证 */
filterChainDefinitionMap.put(restPath + "/userInfo", ANON);
/* 在线用户列表不用验证 */
filterChainDefinitionMap.put(restPath + "/onlineUser", ANON);
/* 用户所属菜单信息不需认证 */
filterChainDefinitionMap.put(restPath + "/userMenu", ANON);
filterChainDefinitionMap.put(restPath + "/updateUserInfo", ANON);
filterChainDefinitionMap.put(restPath + "/updatePassword", ANON);
filterChainDefinitionMap.put(restPath + "/user/supplierRegistry/*", ANON);
filterChainDefinitionMap.put(restPath + "/**", AUTHC);
/* static 不需登录 */
filterChainDefinitionMap.put("/static/**", ANON);
/* userfiles 用户文件 不需登录 */
filterChainDefinitionMap.put("/userfiles/**", ANON);
filterChainDefinitionMap.put(adminPath + LOGIN, AUTHC);
filterChainDefinitionMap.put(adminPath + "/logout", "logout");
filterChainDefinitionMap.put("/swagger-ui.html", ANON);
// filterChainDefinitionMap.put("/swagger-ui.html", "jwtFilter");
/* 全api一般需要登录才能使用 */
filterChainDefinitionMap.put(portalPath+"/**", ANON);
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
return shiroFilterFactoryBean;
}
}
@@ -0,0 +1,48 @@
package com.adc.da.login.entity;
import com.adc.da.sys.entity.UserEO;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
/**
* 授权用户信息
*/
public class MyPrincipal implements Serializable {
private static final long serialVersionUID = 1L;
private String id;
private String loginName;
private String name;
private transient Map<String, Object> cacheMap;
public MyPrincipal(UserEO user) {
this.id = user.getUsid() == null ? "" : String.valueOf(user.getUsid());
this.loginName = user.getAccount();
}
public String getId() {
return id;
}
public String getLoginName() {
return loginName;
}
public String getName() {
return name;
}
public Map<String, Object> getCacheMap() {
if (cacheMap == null) {
cacheMap = new HashMap<>();
}
return cacheMap;
}
}
@@ -0,0 +1,39 @@
package com.adc.da.login.entity;
import java.io.Serializable;
import java.util.Date;
public class OnlineUserEO implements Serializable {
private static final long serialVersionUID = 5949014199725915501L;
private String ip;
private String account;
private Date loginTime;
public String getIp() {
return ip;
}
public void setIp(String ip) {
this.ip = ip;
}
public String getAccount() {
return account;
}
public void setAccount(String account) {
this.account = account;
}
public Date getLoginTime() {
return loginTime;
}
public void setLoginTime(Date loginTime) {
this.loginTime = loginTime;
}
}
@@ -0,0 +1,56 @@
package com.adc.da.login.filter;
import com.adc.da.util.exception.AdcDaBaseException;
import com.adc.da.util.utils.StringUtils;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Base64;
import org.springframework.beans.factory.annotation.Value;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Properties;
@Slf4j
@Data
public class BasicAuthFilter implements Filter {
private String appId ;
private String appSecrect ;
@Override
public void init(FilterConfig filterConfig) throws ServletException {
log.info("-----------BasicAuthFilter-------------");
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
Properties properties = System.getProperties();
appId = properties.get("appId").toString();
appSecrect = properties.get("appSecrect").toString();
HttpServletRequest request = (HttpServletRequest) servletRequest;
String token = request.getHeader("Authorization");
log.info("接口请求Authorization"+token);
if (StringUtils.isNotEmpty(token)) {
// 值为Basic 用户名:密码的base64编码
String str1 = new String(Base64.decodeBase64(token), StandardCharsets.UTF_8);
String str2 = "Basic "+appId+":"+appSecrect;
if (!str1.equals(str2)) {
throw new AdcDaBaseException("token不对");
} else {
filterChain.doFilter(request, servletResponse);
}
} else {
throw new AdcDaBaseException("token不对");
}
}
@Override
public void destroy() {
}
}
@@ -0,0 +1,51 @@
package com.adc.da.login.filter;
import com.adc.da.util.exception.AdcDaBaseException;
import com.adc.da.util.utils.StringUtils;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Base64;
import javax.annotation.Resource;
import org.springframework.core.env.Environment;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Properties;
@Slf4j
@Data
public class DdmRSAAuthFilter implements Filter {
@Resource
private Environment env;
@Override
public void init(FilterConfig filterConfig) throws ServletException {
log.info("-----------BasicAuthFilter-------------");
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
Properties properties = System.getProperties();
HttpServletRequest request = (HttpServletRequest) servletRequest;
String token = request.getHeader("token");
log.info("接口请求Authorization"+token);
if (StringUtils.isNotEmpty(token)) {
// 用公钥解密
} else {
throw new AdcDaBaseException("token不对");
}
}
@Override
public void destroy() {
}
}
@@ -0,0 +1,68 @@
package com.adc.da.login.filter;
import com.adc.da.login.util.CacheUtils;
import com.adc.da.login.util.JWTUtils;
import com.adc.da.util.exception.AdcDaBaseException;
import com.adc.da.util.http.Result;
import com.adc.da.util.utils.StringUtils;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Optional;
@Slf4j
public class jwtFilter implements Filter {
private final static String CACHE_NAME="jwtcahe";
@Override
public void init(FilterConfig filterConfig) throws ServletException {
log.info("-----------jwtfilter-------------");
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request=(HttpServletRequest)servletRequest;
String token=request.getHeader("access_token");
if(StringUtils.isNotEmpty(token)){
token=token.substring(7);
}
Object cacheToken=CacheUtils.get(CACHE_NAME,token);
if(!StringUtils.isEmpty(cacheToken)){
if(JWTUtils.isExp(cacheToken.toString())){
CacheUtils.remove(CACHE_NAME,token);
throw new AdcDaBaseException("token不对");
//renderJson(servletResponse,Result.error("401","token无效"));
}
else{
filterChain.doFilter(request,servletResponse);
}
}
else{
throw new AdcDaBaseException("token不对");
//renderJson(servletResponse,Result.error("401","token无效"));
}
}
@Override
public void destroy() {
}
public static void renderJson(ServletResponse response, Object jsonObject) {
try {
response.setContentType("application/json");
response.setCharacterEncoding("UTF-8");
PrintWriter writer = response.getWriter();
writer.write(JSON.toJSONString(jsonObject));
} catch (IOException var3) {
log.info("token错误");
}
}
}
@@ -0,0 +1,57 @@
package com.adc.da.login.rest;
import com.adc.da.log.controller.LogEOController;
import com.adc.da.log.dao.mysql.LogEODao;
import com.adc.da.log.entity.MiLogEO;
import com.adc.da.login.util.UserUtils;
import com.adc.da.sys.entity.UserEO;
import com.adc.da.util.http.ResponseMessage;
import com.adc.da.util.http.Result;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.annotation.Resource;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Date;
import java.util.UUID;
/**
* @Author sima
* @Date 2022/7/8 16:54
*/
@RestController
@RequestMapping("/${restPath}/log/log")
@Api(tags = "Sys-日志管理1")
public class LogController {
private static final Logger logger = LoggerFactory.getLogger(LogController.class);
@Resource
private LogEODao dao;
@ApiOperation(value = "|mi|save")
@GetMapping("/save")
public ResponseMessage save(String accessPage) {
// if(null == UserUtils.getUser()){
// logger.error("未登录");
// }
try {
UserEO user = UserUtils.getUser();
MiLogEO miLogEO = new MiLogEO();
miLogEO.setId(UUID.randomUUID().toString().replaceAll("-",""));
miLogEO.setAccessPage(accessPage);
miLogEO.setAccount(user.getAccount());
miLogEO.setUserName(user.getUsname());
miLogEO.setDepartment(user.getDepartment());
miLogEO.setOperateDate(new Date());
dao.save(miLogEO);
} catch (Exception e) {
logger.error("日志添加异常", e);
}
return Result.success();
}
}
@@ -0,0 +1,23 @@
package com.adc.da.login.rest;
import com.adc.da.util.http.Result;
import javax.annotation.Resource;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import com.adc.da.util.http.ResponseMessage;
@RestController
public class LoginController {
@RequestMapping(value = "/notLogin", method = RequestMethod.GET)
public ResponseMessage notLogin() {
return Result.error("401", "未登录", null);
}
@RequestMapping(value = "/notRole", method = RequestMethod.GET)
public ResponseMessage notRole() {
return Result.error("401", "未授权", null);
}
}
@@ -0,0 +1,535 @@
package com.adc.da.login.rest;
import com.adc.da.log.annotation.BusinessLog;
import com.adc.da.login.entity.OnlineUserEO;
import com.adc.da.login.security.SystemAuthorizingRealm;
import com.adc.da.login.security.UsernamePasswordToken;
import com.adc.da.login.security.exception.CaptchaException;
import com.adc.da.login.security.validatecode.IVerifyCodeGen;
import com.adc.da.login.security.validatecode.SimpleCharVerifyCodeGenImpl;
import com.adc.da.login.security.validatecode.VerifyCode;
import com.adc.da.login.service.OnlineUserListener;
import com.adc.da.login.util.CacheUtils;
import com.adc.da.login.util.EncryptUtil;
import com.adc.da.login.util.UserUtils;
import com.adc.da.login.vo.LoginVO;
import com.adc.da.login.vo.OnlineUserVO;
import com.adc.da.sys.dao.mysql.UserEODao;
import com.adc.da.sys.entity.MenuEO;
import com.adc.da.sys.entity.UserEO;
import com.adc.da.sys.service.iservice.IUserEoService;
import com.adc.da.sys.util.RSAUtil;
import com.adc.da.sys.vo.UserVO;
import com.adc.da.util.http.ResponseMessage;
import com.adc.da.util.http.Result;
import com.adc.da.util.utils.BeanMapper;
import com.adc.da.util.utils.RequestUtils;
import com.google.gson.Gson;
import com.google.gson.JsonElement;
import com.google.gson.JsonParser;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.subject.Subject;
import javax.annotation.Resource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.*;
import static org.apache.commons.lang3.StringUtils.isBlank;
/**
* 登录接口
* 1.登录 get,已弃用
* 2.登录 post
* 3.登出
* 4.修改密码
* 5.修改用户信息
* 6.获取登录用户信息
* 7.获取登录用户菜单权限,已弃用
* 8.生成4位验证码
* 9.生成6位验证码
*
* @author comments created by Lee Kwanho
* date 2018-09-06
**/
@Validated
@Controller
@RequestMapping(value = "${restPath}/")
@Api(tags = "Login-登录模块")
@Slf4j
public class LoginRestController {
/**
* 无缓存,用于校验
*/
private static final String NO_CACHE = "no-cache";
/**
* 登录失败Map字段
*/
private static final String LOGIN_FAIL_MAP = "loginFailMap";
/**
* 服务层装配
*
* @see UserEOService
*/
@Resource
private IUserEoService userService;
@Resource
private SystemAuthorizingRealm systemAuthorizingRealm;
@Resource
private UserEODao userEODao;
/**
* eo vo 转换
*
* @see BeanMapper
* @see dozer
*/
@Resource
BeanMapper beanMapper;
/**
* 读取配置文件判断是否需要开启Base64加密
* 默认值为false
*/
@Value("${isPassEncrypted}")
private boolean isPassEncrypted;
/**
* 4位验证码
*
* @param request 请求信息
* @param response 返回信息
*/
@GetMapping("/verifyCode")
public void verifyCode(HttpServletRequest request, HttpServletResponse response) {
verifyCode(request, response, 80, 28, 4);
}
/**
* 6位验证码
*
* @param request 请求信息
* @param response 返回信息
*/
@GetMapping("/verifyCode6")
public void verifyCode6(HttpServletRequest request, HttpServletResponse response) {
verifyCode(request, response, 100, 28, 6);
}
/**
* 生成验证码
* 由 verifyCode6 和 verifyCode 调用
*
* @param request 请求信息
* @param response 返回信息
* @param width 宽度
* @param height 高度
* @param number 字符数
* @author Lee Kwanho 李坤澔
* date 2018-09-06
*/
private void verifyCode(HttpServletRequest request, HttpServletResponse response, int width, int height,
int number) {
IVerifyCodeGen iVerifyCodeGen = new SimpleCharVerifyCodeGenImpl();
try {
VerifyCode verifyCode = iVerifyCodeGen.generate(width, height, number);
request.getSession().setAttribute("VerifyCode", verifyCode.getCode());
response.setHeader("Pragma", NO_CACHE);
response.setHeader("Cache-Control", NO_CACHE);
response.setDateHeader("Expires", 0);
response.setContentType("image/jpeg");
response.getOutputStream().write(verifyCode.getImgBytes());
response.getOutputStream().flush();
} catch (IOException e) {
log.error("verifyCode Error", e);
}
}
/**
* 预校验验证码
*
* @param request 请求信息
* @param verify 输入数据
* @author dingqiang 丁强
* date 2018-12-18
*/
@ApiOperation(value = "预校验验证码")
@PutMapping("/judgeVerify")
@ResponseBody
public ResponseMessage judgeVerify(HttpServletRequest request, @RequestParam String verify) {
String verifyCode = (String) request.getSession().getAttribute("VerifyCode");
if (verify == null) {
return Result.error("验证码不能为空!");
}
if (null == verifyCode) {
return Result.error("验证码生成失败,请联系管理员!");
}
if (!verify.equalsIgnoreCase(verifyCode)) {
return Result.error("验证码不正确!");
}
return Result.success("验证码输入正确");
}
/**
* 获取密码最近一次更换时间
*/
/*@GetMapping(value = "/passwordUpdateTime")
@ResponseBody
public ResponseMessage passwordUpdateTime(){
//获取登录用户的userid
String usid = UserUtils.getUserId();
Date lodDate = userEODao.getUpdatePasswordTime(usid);
if(null == lodDate){
return Result.success();
}
long lodTime = lodDate.getTime();
Date nweDate =new Date();
long newTime = nweDate.getTime();
//相差的天
long i = (newTime - lodTime)/1000/60/60/24;
if(i>90){
//超过90天未更改密码
return Result.error("r0020", "已超过90天未更换密码,请及时更换");
}else{
return Result.success();
}
}
public Boolean isExpire(String usname){
Date lodDate = userEODao.getUpdatePasswordTimeByAccount(usname);
if(null == lodDate){
return true;
}
long lodTime = lodDate.getTime();
Date nweDate =new Date();
long newTime = nweDate.getTime();
//相差的天
long i = (newTime - lodTime)/1000/60/60/24;
if(i>180){
//超过180天未更改密码
return false;
}else{
return true;
}
}*/
/**
* Post方式登录
*
* @param request 请求体
* @return 登录结果
*/
@ApiOperation(value = "Post方式登录")
@PostMapping(value = "/login")
@ResponseBody
@BusinessLog(description = "登录")
public ResponseMessage postLogin(HttpServletRequest request, @RequestBody String requestString) throws Exception {
String username;
String password;
JsonParser parser=new JsonParser();
Gson gson=new Gson();
String data=new String(Base64.decodeBase64(requestString),StandardCharsets.UTF_8);
JsonElement element = parser.parse(data);
LoginVO loginVO=gson.fromJson(element,LoginVO.class);
String verifyCode = loginVO.getVerifyCode();
if (isBlank(loginVO.getUsername())) {
return Result.error("r0014", "登录名不能为空");
}
if (isBlank(loginVO.getPassword())) {
return Result.error("r0016", "密码不能为空");
}
// 前台如果base64传输密文,则需要解码
if (isPassEncrypted) {
/*
* 用户与密码都需要加解密
*/
username = new String(RSAUtil.decryptByPrivateKey(Base64.decodeBase64(loginVO.getUsername()),RSAUtil.PrivateKey));
password = new String(RSAUtil.decryptByPrivateKey(Base64.decodeBase64(loginVO.getPassword()),RSAUtil.PrivateKey));
// username = new String(Encodes.decodeBase64(loginVO.getUsername()), StandardCharsets.UTF_8);
// password = new String(Encodes.decodeBase64(loginVO.getPassword()), StandardCharsets.UTF_8);
} else {
username = loginVO.getUsername();
password = loginVO.getPassword();
}
UsernamePasswordToken token = new UsernamePasswordToken(username, password.toCharArray(), verifyCode);
return login(request, token);
}
/**
*
* loginPage testcontroller
*
* @param request 请求体
* @return 登录结果
*/
@ApiOperation(value = "loginPage_betaVersion")
@GetMapping(value = "/loginPage")
@ResponseBody
public ResponseMessage loginPage(HttpServletRequest request) {
return new ResponseMessage("302", "/login.html", false);
}
/**
* 登录方法
*
* @param request 请求体
* @param token UsernamePasswordToken
* @return 登录信息
*/
private ResponseMessage login(HttpServletRequest request, UsernamePasswordToken token) {
Subject subject = SecurityUtils.getSubject();
UserEO userEO;
String username = token.getUsername();
try {
subject.login(token);
//认证完成删除session中VerifyCode
request.getSession().removeAttribute("VerifyCode");
//认证成功将库里错误次数改为0
// userService.updatePasswordErrorsNumberByAccount(username,0);
userEO = UserUtils.getUser();
request.getSession().setAttribute(RequestUtils.LOGIN_USER, userEO);
UserEO returnEO = userService.getUserWithRoles(userEO.getUsid());
request.getSession().setAttribute(RequestUtils.LOGIN_USER_ID, userEO.getUsid());
request.getSession().setAttribute(RequestUtils.LOGIN_ROLE_ID, UserUtils.getRoleIds());
HttpSession session = request.getSession();
String sessionid = session.getId();
System.out.println(sessionid);
//首先将原session中的数据转移至一临时map中
Map<String,Object> tempMap = new HashMap();
Enumeration<String> sessionNames = session.getAttributeNames();
while(sessionNames.hasMoreElements()){
String sessionName = sessionNames.nextElement();
tempMap.put(sessionName, session.getAttribute(sessionName));
}
//注销原session,为的是重置sessionId
//session.invalidate();
subject.logout();
//将临时map中的数据转移至新session
session = request.getSession();
for(Map.Entry<String, Object> entry : tempMap.entrySet()){
session.setAttribute(entry.getKey(), entry.getValue());
}
System.out.println(session.getId());
// Session session = subject.getSession();
if (null != session) {
CacheUtils.putShiroSessionCache(userEO.getUsid(), session.getId());
}
return Result.success(beanMapper.map(returnEO, UserVO.class));
} catch (CaptchaException e) {
// systemAuthorizingRealm.increaseLoginErrorCount(username);
log.info("验证码验证失败");
return Result.error("r0012", "您输入的验证码不正确", systemAuthorizingRealm.isNeedValidCode(username));
} catch (UnknownAccountException e) {
// systemAuthorizingRealm.increaseLoginErrorCount(username);
log.info("用户[{}]身份验证失败", username);
return Result.error("r0011", "您输入的帐号或密码有误", systemAuthorizingRealm.isNeedValidCode(username));
} catch (IncorrectCredentialsException e) {
// systemAuthorizingRealm.increaseLoginErrorCount(username);
log.info("用户[{}]密码验证失败", username);
//增加错误次数
// return passwordErrorsNumber(username);
return Result.error("r0011", "您输入的帐号或密码有误", systemAuthorizingRealm.isNeedValidCode(username));
} catch (Exception e) {
// systemAuthorizingRealm.increaseLoginErrorCount(username);
log.error(e.getMessage(), e);
return Result.error("r0013", e.getMessage(), systemAuthorizingRealm.isNeedValidCode(username));
}
}
/**
* 获取在线用户
*
* @param response 请求体
* @return 当前在线用户列表
*/
@ApiOperation(value = "获取在线用户")
@GetMapping("/onlineUser")
@ResponseBody
public ResponseMessage<OnlineUserVO> onlineUser(HttpServletResponse response) {
Map<String, OnlineUserEO> map = OnlineUserListener.getOnlineMap();
List<OnlineUserEO> onlineUsers = new ArrayList<>(map.values());
OnlineUserVO onlineUserVO = new OnlineUserVO();
onlineUserVO.setOnlineUsers(onlineUsers);
onlineUserVO.setTotal(onlineUsers.size());
return Result.success(onlineUserVO);
}
/**
* 退出登录
*
* @return success
*/
@ApiOperation(value = "退出登录")
@GetMapping("/logout")
@ResponseBody
public ResponseMessage logout(HttpServletRequest request) {
UserEO userEO = UserUtils.getUser();
HttpSession session = request.getSession(false);
if(null != session){
session.invalidate();
}
if(null !=userEO ) {
CacheUtils.removeShiroSessionCache(userEO.getUsid());
}
if(userEO != null) {
// UserUtils.flush();
UserUtils.logout();
}
return Result.success();
}
/**
* 登录成功之后获取当前登录用户信息的接口
*
* @param response 请求体
* @return 当前用户信息
*
*/
@ApiOperation(value = "获取登录用户信息")
@GetMapping("/userInfo")
@ResponseBody
public ResponseMessage<UserVO> userInfo(HttpServletResponse response) {
try {
UserEO user = UserUtils.getUser();
if (user != null) {
String id = user.getUsid();
/* 获取用户信息,角色信息,组织信息 */
UserVO userVO = beanMapper.map(userService.getUserWithRoles(id), UserVO.class);
return Result.success(userVO);
} else {
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
return Result.error("401", "未授权", null);
}
} catch (Exception e) {
log.error("获取登录用户信息", e);
return Result.error("500", "获取登录用户信息" + e.getMessage(), null);
}
}
/**
* 获取用户菜单,已用菜单管理实现
*
* @return 菜单权限
* @author Lee Kwanho 李坤澔
* date 2018-09-06
* @see com.adc.da.sys.controller.MenuEOController
* @deprecated 使用菜单管理替代
*/
@ApiOperation(value = "获取登录用户菜单权限")
@GetMapping("/userMenu")
@ResponseBody
@Deprecated
public ResponseMessage<MenuEO> userMenu() {
return Result.success(UserUtils.getMenuTree());
}
@GetMapping("getIp")
@ResponseBody
public static String getIp(HttpServletRequest request) throws Exception{
//发给nginx请求的地址
String ip = request.getHeader("X-Real-IP");
if (!StringUtils.isBlank(ip) && !"unknown".equalsIgnoreCase(ip)) {
return ip;
}
//一个或多个地址,每次代理都会多一个ip,所以第一为真实地址(类似于这种形式:192.168.1.2, 192.168.1.3, 192.168.1.n
ip = request.getHeader("X-Forwarded-For");
if (!StringUtils.isBlank(ip) && !"unknown".equalsIgnoreCase(ip)) {
// 多次反向代理后会有多个IP值,第一个为真实IP。
int index = ip.indexOf(',');
if (index != -1) {
return ip.substring(0, index);
} else {
return ip;
}
} else {
//ng的地址
return request.getRemoteAddr();
}
}
// public static void main(String[] args) {
// String json="";
// Base64.encodeBase64String()
// }
@GetMapping("/testtest")
@ResponseBody
public ResponseMessage test(HttpServletRequest request){
HttpSession session = request.getSession();
if(session.getAttribute("haha")==null){
session.setAttribute("haha","haha");
session.setMaxInactiveInterval(20);
}
return Result.success();
}
public static void main(String[] args) throws Exception {
String decrypt = EncryptUtil.decrypt("F6lnqMmPc/zkC8LcdSnDIMkH3Pt3DC1/53blM5P0FkM=");
System.out.println(decrypt);
}
}
@@ -0,0 +1,132 @@
//package com.adc.da.login.rest.cas.controller;
//
//import com.adc.da.login.rest.cas.util.CASServiceUtil;
//import com.adc.da.login.rest.cas.util.XmlUtils;
//import com.adc.da.login.security.UsernamePasswordToken;
//import com.adc.da.login.util.CacheUtils;
//import com.adc.da.login.util.UserUtils;
//import com.adc.da.sys.entity.UserEO;
//import com.adc.da.sys.service.iservice.IUserEoService;
//import com.adc.da.sys.vo.UserVO;
//import com.adc.da.util.http.ResponseMessage;
//import com.adc.da.util.http.Result;
//import com.adc.da.util.utils.BeanMapper;
//import com.adc.da.util.utils.RequestUtils;
//import lombok.extern.slf4j.Slf4j;
//import org.apache.commons.lang.StringUtils;
//import org.apache.shiro.SecurityUtils;
//import org.apache.shiro.subject.Subject;
//import javax.annotation.Resource;
//import org.springframework.beans.factory.annotation.Value;
//import org.springframework.web.bind.annotation.*;
//
//import javax.servlet.http.HttpServletRequest;
//import javax.servlet.http.HttpServletResponse;
//import javax.servlet.http.HttpSession;
//import java.io.IOException;
//import java.util.Enumeration;
//import java.util.HashMap;
//import java.util.Map;
//
///**
// * <p>
// * CAS单点登录客户端登录认证
// * </p>
// *
// * @Author zhoujf
// * @since 2018-12-20
// */
//@Slf4j
//@RestController
//@RequestMapping(value = "${restPath}/")
//public class CasClientController {
//
// @Value("${restPath}")
// private String restpath;
//
// @Value("${cas.server-url-prefix}")
// private String prefixUrl;
//
// private String serverUrl="http://localhost:7060";
//
// @Resource
// private IUserEoService userService;
//
// @Resource
// BeanMapper beanMapper;
//
// @RequestMapping(value = "/caslogin",method= RequestMethod.GET)
// public void login(HttpServletResponse response, HttpSession session) throws IOException {
// // 单点登录之前先登出
// UserUtils.logout();
// String url = prefixUrl+ "/login?&service=" + serverUrl +restpath+ "/cas/validateLogin";
// response.sendRedirect(url);
// }
//
//
// @GetMapping("/cas/validateLogin")
// public ResponseMessage validateLogin(@RequestParam(name="ticket") String ticket,
// @RequestParam(name="service") String service,
// HttpServletRequest request,
// HttpServletResponse response) throws Exception {
//
// log.info("cas validateLogin");
// try {
// String validateUrl = prefixUrl+"/p3/serviceValidate";
// String res = CASServiceUtil.getSTValidate(validateUrl, ticket, service);
// log.info("res."+res);
// final String error = XmlUtils.getTextForElement(res, "authenticationFailure");
// if(StringUtils.isNotEmpty(error)) {
// throw new Exception(error);
// }
// final String principal = XmlUtils.getTextForElement(res, "user");
// if (StringUtils.isEmpty(principal)) {
// throw new Exception("No principal was found in the response from the CAS server.");
// }
// log.info("-------token----username---"+principal);
//
// UserEO user = userService.getUserByLoginNameNotDeleted(principal);
// if (null == user) {
// return Result.error("401", "该用户不存在", null);
// }
// Subject subject = SecurityUtils.getSubject();
// UsernamePasswordToken token = new UsernamePasswordToken(user.getAccount());
// subject.login(token);
// UserEO returnEO = userService.getUserWithRoles(user.getUsid());//登录成功后存储session
// request.getSession().setAttribute(RequestUtils.LOGIN_USER_ID, user.getUsid());
// request.getSession().setAttribute(RequestUtils.LOGIN_ROLE_ID, UserUtils.getRoleIds());
//
// HttpSession session = request.getSession();
// String sessionid = session.getId();
// System.out.println(sessionid);
// //首先将原session中的数据转移至一临时map中
// Map<String,Object> tempMap = new HashMap();
// Enumeration<String> sessionNames = session.getAttributeNames();
// while(sessionNames.hasMoreElements()){
// String sessionName = sessionNames.nextElement();
// tempMap.put(sessionName, session.getAttribute(sessionName));
// }
// subject.logout();
// //将临时map中的数据转移至新session
// session = request.getSession();
// for(Map.Entry<String, Object> entry : tempMap.entrySet()){
// session.setAttribute(entry.getKey(), entry.getValue());
// }
// System.out.println(session.getId());
//
//// Session session = subject.getSession();
// if (null != session) {
// CacheUtils.putShiroSessionCache(user.getUsid(), session.getId());
// }
// return Result.success(beanMapper.map(returnEO, UserVO.class));
//
//
// } catch (Exception e) {
// //e.printStackTrace();
// return Result.error("401", "未登录", null);
// }
//
// }
//
//
//}
@@ -0,0 +1,105 @@
//package com.adc.da.login.rest.cas.util;
//
//import org.apache.http.HttpResponse;
//import org.apache.http.client.methods.HttpGet;
//import org.apache.http.conn.socket.LayeredConnectionSocketFactory;
//import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
//import org.apache.http.impl.client.CloseableHttpClient;
//import org.apache.http.impl.client.HttpClientBuilder;
//import org.apache.http.impl.client.HttpClients;
//
//import javax.net.ssl.SSLContext;
//import javax.net.ssl.TrustManager;
//import javax.net.ssl.X509TrustManager;
//import java.io.BufferedReader;
//import java.io.IOException;
//import java.io.InputStreamReader;
//import java.security.cert.X509Certificate;
//
//public class CASServiceUtil {
//
// public static void main(String[] args) {
// String serviceUrl = "https://cas.8f8.com.cn:8443/cas/p3/serviceValidate";
// String service = "http://localhost:3003/user/login";
// String ticket = "ST-5-1g-9cNES6KXNRwq-GuRET103sm0-DESKTOP-VKLS8B3";
// String res = getSTValidate(serviceUrl,ticket, service);
//
// System.out.println("---------res-----"+res);
// }
//
//
// /**
// * 验证ST
// */
// public static String getSTValidate(String url,String st, String service){
// try {
// url = url+"?service="+service+"&ticket="+st;
// CloseableHttpClient httpclient = createHttpClientWithNoSsl();
//// CloseableHttpClient httpclient= HttpClientBuilder.create().build();
//
// HttpGet httpget = new HttpGet(url);
// HttpResponse response = httpclient.execute(httpget);
// String res = readResponse(response);
// return res == null ? null : (res == "" ? null : res);
// } catch (Exception e) {
// e.printStackTrace();
// }
// return "";
// }
//
//
// /**
// * 读取 response body 内容为字符串
// *
// * @param response
// * @return
// * @throws IOException
// */
// private static String readResponse(HttpResponse response) throws IOException {
// BufferedReader in = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
// String result = new String();
// String line;
// while ((line = in.readLine()) != null) {
// result += line;
// }
// return result;
// }
//
//
// /**
// * 创建模拟客户端(针对 https 客户端禁用 SSL 验证)
// *
// * @param cookieStore 缓存的 Cookies 信息
// * @return
// * @throws Exception
// */
// private static CloseableHttpClient createHttpClientWithNoSsl() throws Exception {
// // Create a trust manager that does not validate certificate chains
// TrustManager[] trustAllCerts = new TrustManager[]{
// new X509TrustManager() {
// @Override
// public X509Certificate[] getAcceptedIssuers() {
// return null;
// }
//
// @Override
// public void checkClientTrusted(X509Certificate[] certs, String authType) {
// // don't check
// }
//
// @Override
// public void checkServerTrusted(X509Certificate[] certs, String authType) {
// // don't check
// }
// }
// };
//
// SSLContext ctx = SSLContext.getInstance("TLS");
// ctx.init(null, trustAllCerts, null);
// LayeredConnectionSocketFactory sslSocketFactory = new SSLConnectionSocketFactory(ctx);
// return HttpClients.custom()
// .setSSLSocketFactory(sslSocketFactory)
// .build();
// }
//
//}
@@ -0,0 +1,286 @@
//package com.adc.da.login.rest.cas.util;
//
//
//import lombok.extern.slf4j.Slf4j;
//import org.w3c.dom.Document;
//import org.xml.sax.Attributes;
//import org.xml.sax.InputSource;
//import org.xml.sax.SAXException;
//import org.xml.sax.XMLReader;
//import org.xml.sax.helpers.DefaultHandler;
//
//import javax.xml.XMLConstants;
//import javax.xml.parsers.DocumentBuilderFactory;
//import javax.xml.parsers.ParserConfigurationException;
//import javax.xml.parsers.SAXParser;
//import javax.xml.parsers.SAXParserFactory;
//import java.io.StringReader;
//import java.util.*;
//
///**
// * 解析cas,ST验证后的xml
// *
// */
//@Slf4j
//public final class XmlUtils {
//
// /**
// * Creates a new namespace-aware DOM document object by parsing the given XML.
// *
// * @param xml XML content.
// *
// * @return DOM document.
// */
// public static Document newDocument(final String xml) {
// final DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
// final Map<String, Boolean> features = new HashMap<String, Boolean>();
// features.put(XMLConstants.FEATURE_SECURE_PROCESSING, true);
// features.put("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
// for (final Map.Entry<String, Boolean> entry : features.entrySet()) {
// try {
// factory.setFeature(entry.getKey(), entry.getValue());
// } catch (ParserConfigurationException e) {
// log.warn("Failed setting XML feature {}: {}", entry.getKey(), e);
// }
// }
// factory.setNamespaceAware(true);
// try {
// return factory.newDocumentBuilder().parse(new InputSource(new StringReader(xml)));
// } catch (Exception e) {
// throw new RuntimeException("XML parsing error: " + e);
// }
// }
//
// /**
// * Get an instance of an XML reader from the XMLReaderFactory.
// *
// * @return the XMLReader.
// */
// public static XMLReader getXmlReader() {
// try {
// final XMLReader reader = SAXParserFactory.newInstance().newSAXParser().getXMLReader();
// reader.setFeature("http://xml.org/sax/features/namespaces", true);
// reader.setFeature("http://xml.org/sax/features/namespace-prefixes", false);
// reader.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
// return reader;
// } catch (final Exception e) {
// throw new RuntimeException("Unable to create XMLReader", e);
// }
// }
//
//
// /**
// * Retrieve the text for a group of elements. Each text element is an entry
// * in a list.
// * <p>This method is currently optimized for the use case of two elements in a list.
// *
// * @param xmlAsString the xml response
// * @param element the element to look for
// * @return the list of text from the elements.
// */
// public static List<String> getTextForElements(final String xmlAsString, final String element) {
// final List<String> elements = new ArrayList<String>(2);
// final XMLReader reader = getXmlReader();
//
// final DefaultHandler handler = new DefaultHandler() {
//
// private boolean foundElement = false;
//
// private StringBuilder buffer = new StringBuilder();
//
// public void startElement(final String uri, final String localName, final String qName,
// final Attributes attributes) throws SAXException {
// if (localName.equals(element)) {
// this.foundElement = true;
// }
// }
//
// public void endElement(final String uri, final String localName, final String qName) throws SAXException {
// if (localName.equals(element)) {
// this.foundElement = false;
// elements.add(this.buffer.toString());
// this.buffer = new StringBuilder();
// }
// }
//
// public void characters(char[] ch, int start, int length) throws SAXException {
// if (this.foundElement) {
// this.buffer.append(ch, start, length);
// }
// }
// };
//
// reader.setContentHandler(handler);
// reader.setErrorHandler(handler);
//
// try {
// reader.parse(new InputSource(new StringReader(xmlAsString)));
// } catch (final Exception e) {
// log.error(e.getMessage(), e);
// return null;
// }
//
// return elements;
// }
//
// /**
// * Retrieve the text for a specific element (when we know there is only
// * one).
// *
// * @param xmlAsString the xml response
// * @param element the element to look for
// * @return the text value of the element.
// */
// public static String getTextForElement(final String xmlAsString, final String element) {
// final XMLReader reader = getXmlReader();
// final StringBuilder builder = new StringBuilder();
//
// final DefaultHandler handler = new DefaultHandler() {
//
// private boolean foundElement = false;
//
// public void startElement(final String uri, final String localName, final String qName,
// final Attributes attributes) throws SAXException {
// if (localName.equals(element)) {
// this.foundElement = true;
// }
// }
//
// public void endElement(final String uri, final String localName, final String qName) throws SAXException {
// if (localName.equals(element)) {
// this.foundElement = false;
// }
// }
//
// public void characters(char[] ch, int start, int length) throws SAXException {
// if (this.foundElement) {
// builder.append(ch, start, length);
// }
// }
// };
//
// reader.setContentHandler(handler);
// reader.setErrorHandler(handler);
//
// try {
// reader.parse(new InputSource(new StringReader(xmlAsString)));
// } catch (final Exception e) {
// log.error(e.getMessage(), e);
// return null;
// }
//
// return builder.toString();
// }
//
//
// public static Map<String, Object> extractCustomAttributes(final String xml) {
// final SAXParserFactory spf = SAXParserFactory.newInstance();
// spf.setNamespaceAware(true);
// spf.setValidating(false);
// try {
// final SAXParser saxParser = spf.newSAXParser();
// final XMLReader xmlReader = saxParser.getXMLReader();
// final CustomAttributeHandler handler = new CustomAttributeHandler();
// xmlReader.setContentHandler(handler);
// xmlReader.parse(new InputSource(new StringReader(xml)));
// return handler.getAttributes();
// } catch (final Exception e) {
// log.error(e.getMessage(), e);
// return Collections.emptyMap();
// }
// }
//
// private static class CustomAttributeHandler extends DefaultHandler {
//
// private Map<String, Object> attributes;
//
// private boolean foundAttributes;
//
// private String currentAttribute;
//
// private StringBuilder value;
//
// @Override
// public void startDocument() throws SAXException {
// this.attributes = new HashMap<String, Object>();
// }
//
// @Override
// public void startElement(final String namespaceURI, final String localName, final String qName,
// final Attributes attributes) throws SAXException {
// if ("attributes".equals(localName)) {
// this.foundAttributes = true;
// } else if (this.foundAttributes) {
// this.value = new StringBuilder();
// this.currentAttribute = localName;
// }
// }
//
// @Override
// public void characters(final char[] chars, final int start, final int length) throws SAXException {
// if (this.currentAttribute != null) {
// value.append(chars, start, length);
// }
// }
//
// @Override
// public void endElement(final String namespaceURI, final String localName, final String qName)
// throws SAXException {
// if ("attributes".equals(localName)) {
// this.foundAttributes = false;
// this.currentAttribute = null;
// } else if (this.foundAttributes) {
// final Object o = this.attributes.get(this.currentAttribute);
//
// if (o == null) {
// this.attributes.put(this.currentAttribute, this.value.toString());
// } else {
// final List<Object> items;
// if (o instanceof List) {
// items = (List<Object>) o;
// } else {
// items = new LinkedList<Object>();
// items.add(o);
// this.attributes.put(this.currentAttribute, items);
// }
// items.add(this.value.toString());
// }
// }
// }
//
// public Map<String, Object> getAttributes() {
// return this.attributes;
// }
// }
//
//
// public static void main(String[] args) {
// String result = "<cas:serviceResponse xmlns:cas='http://www.yale.edu/tp/cas'>\r\n" +
// " <cas:authenticationSuccess>\r\n" +
// " <cas:user>admin</cas:user>\r\n" +
// " <cas:attributes>\r\n" +
// " <cas:credentialType>UsernamePasswordCredential</cas:credentialType>\r\n" +
// " <cas:isFromNewLogin>true</cas:isFromNewLogin>\r\n" +
// " <cas:authenticationDate>2019-08-01T19:33:21.527+08:00[Asia/Shanghai]</cas:authenticationDate>\r\n" +
// " <cas:authenticationMethod>RestAuthenticationHandler</cas:authenticationMethod>\r\n" +
// " <cas:successfulAuthenticationHandlers>RestAuthenticationHandler</cas:successfulAuthenticationHandlers>\r\n" +
// " <cas:longTermAuthenticationRequestTokenUsed>false</cas:longTermAuthenticationRequestTokenUsed>\r\n" +
// " </cas:attributes>\r\n" +
// " </cas:authenticationSuccess>\r\n" +
// "</cas:serviceResponse>";
//
// String errorRes = "<cas:serviceResponse xmlns:cas='http://www.yale.edu/tp/cas'>\r\n" +
// " <cas:authenticationFailure code=\"INVALID_TICKET\">未能够识别出目标 &#39;ST-5-1g-9cNES6KXNRwq-GuRET103sm0-DESKTOP-VKLS8B3&#39;票根</cas:authenticationFailure>\r\n" +
// "</cas:serviceResponse>";
//
// String error = XmlUtils.getTextForElement(errorRes, "authenticationFailure");
// System.out.println("------"+error);
//
// String error2 = XmlUtils.getTextForElement(result, "authenticationFailure");
// System.out.println("------"+error2);
// String principal = XmlUtils.getTextForElement(result, "user");
// System.out.println("---principal---"+principal);
// Map<String, Object> attributes = XmlUtils.extractCustomAttributes(result);
// System.out.println("---attributes---"+attributes);
// }
//}
@@ -0,0 +1,72 @@
package com.adc.da.login.security;
import com.adc.da.util.exception.AdcDaBaseException;
import com.adc.da.util.http.ResponseMessage;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.util.ThreadContext;
import org.apache.shiro.web.servlet.ShiroHttpServletResponse;
import org.apache.shiro.web.subject.WebSubject;
import org.apache.shiro.web.util.WebUtils;
import org.springframework.stereotype.Service;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletResponse;
/**
* 表单验证(包含验证码)过滤类
*/
@Service
public class AdcFormAuthenticationFilter extends org.apache.shiro.web.filter.authc.FormAuthenticationFilter {
/**
* 验证码
*/
public static final String DEFAULT_CAPTCHA_PARAM = "validateCode";
private String captchaParam = DEFAULT_CAPTCHA_PARAM;
public String getCaptchaParam() {
return captchaParam;
}
protected String getCaptcha(ServletRequest request) {
return WebUtils.getCleanParam(request, getCaptchaParam());
}
@Override
protected AuthenticationToken createToken(ServletRequest request, ServletResponse response) {
// 不知道什么原因,在Spring Boot应用中,无法初始化WebSubject
WebSubject.Builder builder = new WebSubject.Builder(request, response);
WebSubject webSubject = builder.buildWebSubject();
ThreadContext.bind(webSubject);
String username = getUsername(request);
String password = getPassword(request);
String record;
if (password == null) {
record = "";
} else {
record = password;
}
boolean rememberMe = isRememberMe(request);
String host = getHost(request);
String captcha = getCaptcha(request);
return new UsernamePasswordToken(username, record.toCharArray(), rememberMe, host, captcha);
}
protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
Subject subject = this.getSubject(request, response);
if (subject.getPrincipal() == null) {
/* 设置状态码 为401 */
((HttpServletResponse) response).setStatus(401);
((HttpServletResponse) response).sendError(401,"登录失效,请重新登录!");
return true;
} else {
return false;
}
}
}
@@ -0,0 +1,260 @@
package com.adc.da.login.security;
import com.adc.da.login.LoginType;
import com.adc.da.login.NewHashedCredentialsMatcher;
import com.adc.da.login.entity.MyPrincipal;
import com.adc.da.login.util.CacheUtils;
import com.adc.da.sys.entity.UserEO;
import com.adc.da.login.security.exception.CaptchaException;
import com.adc.da.login.util.UserUtils;
import com.adc.da.sys.service.UserEOServiceImpl;
import com.adc.da.sys.service.iservice.IUserEoService;
import com.adc.da.util.utils.Encodes;
import com.adc.da.util.utils.PasswordUtils;
import com.adc.da.util.utils.SpringContextHolder;
import com.google.common.collect.Maps;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.cache.Cache;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.session.Session;
import org.apache.shiro.session.mgt.eis.SessionDAO;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.SimplePrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.annotation.Resource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
import static com.adc.da.util.utils.PasswordUtils.HASH_ALGORITHM;
import static com.adc.da.util.utils.PasswordUtils.HASH_INTERATIONS;
/**
* 系统安全认证实现类
*/
@Service("systemAuthorizingRealm1")
public class SystemAuthorizingRealm extends AuthorizingRealm {
/**
* 日志
*/
private static final Logger LOG = LoggerFactory.getLogger(SystemAuthorizingRealm.class);
/**
* 验证码
*/
private static final Object VERIFY_CODE = "VerifyCode";
/**
* 读取验证码模式配置,
* 1为不开启,2为开启,3为三次输错用户名或密码才开启,
* 默认为1
* <p>
* 若配置文件缺少该参数,将设置为1
*/
@Value("${verifyCodeMode:1}")
private int verifyCodeMode;
/**
* @see IUserEoService
*/
@Resource
private IUserEoService userService;
/**
* 若userService为空,获取userService
*
* @return
*/
public IUserEoService getUserService() {
if (userService == null) {
userService = SpringContextHolder.getBean(UserEOServiceImpl.class);
}
return userService;
}
/**
* 认证回调函数, 登录时调用
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken) {
UsernamePasswordToken token = (UsernamePasswordToken) authcToken;
UserEO user;
if (token.getType().getCode() == LoginType.PASSWORD.getCode()) {
// if (verifyCodeMode == 2
// || (verifyCodeMode == 3 && isNeedValidCode(token.getUsername()))) {
// /* verifyCodeMode == 2 或
// 如果登录失败超过3次需要验证码 */
// doVerifyCode(token);
// }
// 如果登录失败超过3次需要验证码
//if (LoginRestController.isNeedValidCode(token.getUsername())) {
Session session = SecurityUtils.getSubject().getSession();
String verifyCode = (String) session.getAttribute("VerifyCode");
//去掉验证码校验
if (token.getCaptcha() == null || !token.getCaptcha().toUpperCase().equals(verifyCode)) {
if (token.getCaptcha() != null || !token.getCaptcha().toUpperCase().equals(verifyCode)) {
session.removeAttribute("VerifyCode");
}
throw new CaptchaException("验证码错误.");
}
user = getUserService().getUserByLoginNameNotDeleted(token.getUsername());
if (user == null) {
return null;
}
// byte[] salt = Encodes.decodeHex(user.getPassword().substring(0, 8));
// return new SimpleAuthenticationInfo(new MyPrincipal(user), user.getPassword().substring(8),
// ByteSource.Util.bytes(salt), getName());
// byte[] salt = Encodes.decodeHex(user.getPassword().substring(0, 16));
// return new SimpleAuthenticationInfo(new MyPrincipal(user), user.getPassword().substring(16),
// ByteSource.Util.bytes(salt), getName());
} else{
user = this.getUserService().getUserByLoginNameNotDeleted(token.getUsername());
if (user == null) {
return null;
}
}
return new SimpleAuthenticationInfo(new MyPrincipal(user), user.getPassword(),getName());
}
/**
* 登录失败map
*/
private static final String LOGIN_FAIL_MAP = "loginFailMap";
/**
* 10分钟内最大错误次数
*/
@Value("${maxLoginErrorCount:3}")
private int maxLoginErrorCount;
/**
* 判断是否需要验证验证码
*
* @param userName 用户名
* @return
*/
public boolean isNeedValidCode(String userName) {
Map<String, Integer> loginFailMap = (Map<String, Integer>) CacheUtils.getErrorCache(LOGIN_FAIL_MAP);
if (loginFailMap == null) {
return false;
}
Integer loginFailNum = loginFailMap.get(userName);
if (loginFailNum == null) {
return false;
}
return loginFailNum >= maxLoginErrorCount;
}
/**
* 授权查询回调函数, 进行鉴权但缓存中无用户的授权信息时调用
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
MyPrincipal principal = (MyPrincipal) getAvailablePrincipal(principals);
UserEO user = userService.getUserByLoginName(principal.getLoginName(),null);
if (user != null) {
try {
return UserUtils.getAuthInfo();
} catch (NumberFormatException e) {
LOG.error("AuthorizationInfo NumberFormatException", e);
} catch (Exception e) {
LOG.error("AuthorizationInfo Exception", e);
}
} else {
return null;
}
return null;
}
/**
* 验证码验证
*/
private void doVerifyCode(UsernamePasswordToken token) {
Session session = SecurityUtils.getSubject().getSession();
String verifyCode = (String) session.getAttribute(VERIFY_CODE);
/*
* 忽略大小写改用 equalsIgnoreCase
* date 2018-08-29
*/
if (token.getCaptcha() == null || !token.getCaptcha().equalsIgnoreCase(verifyCode)) {
session.removeAttribute(VERIFY_CODE);
throw new CaptchaException("验证码错误.");
}
// 登录成功也清空验证码
session.removeAttribute(VERIFY_CODE);
}
/**
* 设定密码校验的Hash算法与迭代次数,
* 将 HASH_ALGORITHM 和 HASH_INTERATIONS 改为util中的参数
* <p>
* date 2018-09-06
* @author Lee Kwanho
*/
@PostConstruct
public void initCredentialsMatcher() {
NewHashedCredentialsMatcher matcher = new NewHashedCredentialsMatcher(HASH_ALGORITHM);
matcher.setHashIterations(PasswordUtils.HASH_INTERATIONS);
setCredentialsMatcher(matcher);
// HashedCredentialsMatcher matcher = new HashedCredentialsMatcher(HASH_ALGORITHM);
// matcher.setHashIterations(HASH_INTERATIONS);
// setCredentialsMatcher(matcher);
}
/**
* 清空用户关联权限认证,待下次使用时重新加载
*/
public void clearCachedAuthorizationInfo(String principal) {
SimplePrincipalCollection principals = new SimplePrincipalCollection(principal, getName());
clearCachedAuthorizationInfo(principals);
}
/**
* 清空用户关联权限认证,待下次使用时重新加载
*/
public void clearCachedAuthorizationInfo(MyPrincipal principal) {
SimplePrincipalCollection principals = new SimplePrincipalCollection(principal, getName());
clearCachedAuthorizationInfo(principals);
}
/**
* 清空所有关联认证
*/
public void clearAllCachedAuthorizationInfo() {
Cache<Object, AuthorizationInfo> cache = getAuthorizationCache();
if (cache != null) {
for (Object key : cache.keys()) {
cache.remove(key);
}
}
}
}
@@ -0,0 +1,60 @@
package com.adc.da.login.security;
import com.adc.da.login.LoginType;
/**
* 用户和密码(包含验证码)令牌类
*/
public class UsernamePasswordToken extends org.apache.shiro.authc.UsernamePasswordToken {
private String captcha;
private LoginType type;
public UsernamePasswordToken() {
super();
}
public UsernamePasswordToken(String username, char[] password) {
super(username, password);
}
/**
* 账号密码登录
*/
public UsernamePasswordToken(String username, char[] password, String captcha) {
super(username, password);
this.captcha = captcha;
this.type = LoginType.PASSWORD;
}
/**
* 免密登录
*/
public UsernamePasswordToken(String username) {
super(username, "");
this.captcha = captcha;
this.type = LoginType.NOPASSWD;
}
public UsernamePasswordToken(String username, char[] password, boolean rememberMe, String host, String captcha) {
super(username, password, rememberMe, host);
this.captcha = captcha;
}
public String getCaptcha() {
return captcha;
}
public void setCaptcha(String captcha) {
this.captcha = captcha;
}
public LoginType getType() {
return type;
}
public void setType(LoginType type) {
this.type = type;
}
}
@@ -0,0 +1,28 @@
package com.adc.da.login.security.exception;
import org.apache.shiro.authc.AuthenticationException;
/**
* 验证码异常处理类
*/
public class CaptchaException extends AuthenticationException {
private static final long serialVersionUID = 1L;
public CaptchaException() {
super();
}
public CaptchaException(String message, Throwable cause) {
super(message, cause);
}
public CaptchaException(String message) {
super(message);
}
public CaptchaException(Throwable cause) {
super(cause);
}
}
@@ -0,0 +1,29 @@
package com.adc.da.login.security.validatecode;
import java.io.IOException;
import java.io.OutputStream;
/**
* 验证码生成接口
*/
public interface IVerifyCodeGen {
/**
* 生成验证码并返回code,将图片写的os中
* @param width
* @param height
* @param os
* @return
* @throws IOException
*/
String generate(int width, int height, OutputStream os, int number) throws IOException;
/**
* 生成验证码对象
* @param width
* @param height
* @return
* @throws IOException
*/
VerifyCode generate(int width, int height, int number) throws IOException;
}
@@ -0,0 +1,123 @@
package com.adc.da.login.security.validatecode;
import com.adc.da.util.utils.RandomUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.imageio.ImageIO;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Random;
public class SimpleCharVerifyCodeGenImpl implements IVerifyCodeGen {
/**
* 日志
*/
private static final Logger LOG = LoggerFactory.getLogger(SimpleCharVerifyCodeGenImpl.class);
/**
* 字体
*/
private static final String[] FONT_TYPES = {"宋体", "新宋体", "黑体", "楷体", "隶书" };
/**
* 验证码生成
*
* @param width
* @param height
* @param os
* @param number
* @return
* @throws IOException
*/
@Override
public String generate(int width, int height, OutputStream os, int number) throws IOException {
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
Graphics graphics = image.getGraphics();
fillBackground(graphics, width, height);
String randomStr = RandomUtils.randomString(number);
createCharacter(graphics, randomStr);
graphics.dispose();
ImageIO.write(image, "JPEG", os);
return randomStr;
}
/**
* 验证码生成模块
* 改为try-with-resource写法
*
* @param width 宽度
* @param height 高度
* @param number 数字
* @return 验证码
* @author Lee Kwanho 李坤澔
* date 2018-08-29
**/
@Override
public VerifyCode generate(int width, int height, int number) throws IOException {
VerifyCode verifyCode = null;
try (ByteArrayOutputStream baos = new ByteArrayOutputStream();) {
String code = generate(width, height, baos, number);
verifyCode = new VerifyCode();
verifyCode.setCode(code);
verifyCode.setImgBytes(baos.toByteArray());
} catch (Exception e) {
LOG.error(e.getMessage(), e);
verifyCode = null;
}
return verifyCode;
}
/**
* 验证码背景填充
*
* @param graphics 二维码
* @param width 宽度
* @param height 高度
* @author comments created by Lee Kwanho
* date 2018-08-29
**/
private static void fillBackground(Graphics graphics, int width, int height) {
// 填充背景
graphics.setColor(Color.WHITE);
graphics.fillRect(0, 0, width, height);
// 加入干扰线条
for (int i = 0; i < 8; i++) {
graphics.setColor(RandomUtils.randomColor(40, 150));
Random random = new Random();
int x = random.nextInt(width);
int y = random.nextInt(height);
int x1 = random.nextInt(width);
int y1 = random.nextInt(height);
graphics.drawLine(x, y, x1, y1);
}
}
/**
* 生成随机字
*
* @param g 验证码
* @param randomStr 随机字
* @author comments created by Lee Kwanho
* date 2018-08-29
**/
private void createCharacter(Graphics g, String randomStr) {
char[] charArray = randomStr.toCharArray();
for (int i = 0; i < charArray.length; i++) {
g.setColor(new Color(50 + RandomUtils.nextInt(100), 50 + RandomUtils.nextInt(100),
50 + RandomUtils.nextInt(100)));
g.setFont(new Font(FONT_TYPES[RandomUtils.nextInt(FONT_TYPES.length)], Font.BOLD, 26));
g.drawString(String.valueOf(charArray[i]), 15 * i + 5, 19 + RandomUtils.nextInt(8));
}
}
}
@@ -0,0 +1,46 @@
package com.adc.da.login.security.validatecode;
/**
* 验证码实体类
*/
public class VerifyCode {
/**
* 验证码
*/
private String code;
/**
* 背景图片
*/
private byte[] imgBytes;
/**
* 过期时间
*/
private long expireTime;
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public byte[] getImgBytes() {
return imgBytes;
}
public void setImgBytes(byte[] imgBytes) {
this.imgBytes = imgBytes;
}
public long getExpireTime() {
return expireTime;
}
public void setExpireTime(long expireTime) {
this.expireTime = expireTime;
}
}
@@ -0,0 +1,57 @@
package com.adc.da.login.service;
import java.io.Serializable;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionBindingListener;
import com.adc.da.login.entity.OnlineUserEO;
/**
* 用于记录在线用户
*/
public class OnlineUserListener implements HttpSessionBindingListener , Serializable {
private OnlineUserEO onlineUser;
private static final Map<String, OnlineUserEO> ONLINE_MAP = new ConcurrentHashMap<>();
/**
* 初始化
*/
public OnlineUserListener() {
}
public OnlineUserListener(OnlineUserEO onlineUser) {
this.onlineUser = onlineUser;
}
/**
* 用户上线
*/
@Override
public void valueBound(HttpSessionBindingEvent e) {
HttpSession session = e.getSession();
// 把用户名放入在线列表
ONLINE_MAP.put(session.getId(), onlineUser);
}
/**
* 用户下线
*/
@Override
public void valueUnbound(HttpSessionBindingEvent e) {
HttpSession session = e.getSession();
// 把用户名移除在线列表
ONLINE_MAP.remove(session.getId());
}
public static Map<String, OnlineUserEO> getOnlineMap() {
return ONLINE_MAP;
}
}
@@ -0,0 +1,141 @@
package com.adc.da.login.util;
import com.adc.da.util.utils.SpringContextHolder;
import net.sf.ehcache.Cache;
import net.sf.ehcache.CacheManager;
import net.sf.ehcache.Element;
/**
* Cache工具类
*/
public class CacheUtils {
private CacheUtils() {
throw new IllegalStateException("CacheUtils.java");
}
private static CacheManager cacheManager = SpringContextHolder.getBean("ehCacheManagerFactoryBean");
private static final String SYS_CACHE = "sysCache";
private static final String ERROR_CACHE = "errorCache";
private static final String SUBJECT_CACHE = "subjectCache" ;
private static final String SHIRO_ACTIVE_SESSION_CACHE = "shiro-activeSessionCache";
public static Object get(String key) {
return get(SYS_CACHE, key);
}
public static void put(String key, Object value) {
put(SYS_CACHE, key, value);
}
public static void remove(String key) {
remove(SYS_CACHE, key);
}
//以下三个方法由丁强添加,配合main模块下resource/cache/ehcache-local.xml
//<cache name="errorCache" maxElementsInMemory="100" timeToIdleSeconds="180" timeToLiveSeconds="300" eternal="false" overflowToDisk="true"/>
public static Object getErrorCache(String key) {
return get(ERROR_CACHE, key);
}
public static void putErrorCache(String key, Object value) {
put(ERROR_CACHE, key, value);
}
public static void removeErrorCache(String key) {
remove(ERROR_CACHE, key);
}
//以下三个方法由丁强添加,配合main模块下resource/cache/ehcache-local.xml
//<cache name="subjectCache" maxElementsInMemory="100" timeToIdleSeconds="180" timeToLiveSeconds="300" eternal="false" overflowToDisk="true"/>
public static Object getSubjectCache(String key) {
return get(SUBJECT_CACHE, key);
}
public static void putSubjectCache(String key, Object value) {
put(SUBJECT_CACHE, key, value);
}
public static void removeSubjectCache(String key) {
remove(SUBJECT_CACHE, key);
}
public static Cache getSubjectCacheObject() {
Cache cache = cacheManager.getCache(SUBJECT_CACHE);
if (cache == null) {
cacheManager.addCache(SUBJECT_CACHE);
cache = cacheManager.getCache(SUBJECT_CACHE);
cache.getCacheConfiguration().setEternal(true);
}
return cache;
}
//cacheManager.getCache("shiroActiveSessionCache").remove(sessionid)
public static Cache getShiroSessionCacheObject() {
Cache cache = cacheManager.getCache(SHIRO_ACTIVE_SESSION_CACHE);
if (cache == null) {
cacheManager.addCache(SHIRO_ACTIVE_SESSION_CACHE);
cache = cacheManager.getCache(SHIRO_ACTIVE_SESSION_CACHE);
cache.getCacheConfiguration().setEternal(true);
}
return cache;
}
public static void putShiroSessionCache(String key, Object value) {
put(SHIRO_ACTIVE_SESSION_CACHE, key, value);
}
public static Object getShiroSessionCache(String key) {
return get(SUBJECT_CACHE, key);
}
public static void removeShiroSessionCache(String key) {
remove(SHIRO_ACTIVE_SESSION_CACHE, key);
}
public static Object get(String cacheName, String key) {
Element element = getCache(cacheName).get(key);
return element == null ? null : element.getObjectValue();
}
public static void put(String cacheName, String key, Object value) {
Element element = new Element(key, value);
getCache(cacheName).put(element);
}
public static void remove(String cacheName, String key) {
getCache(cacheName).remove(key);
}
/**
* 获得一个Cache,没有则创建一个。
*
* @param cacheName
* @return
*/
private static Cache getCache(String cacheName) {
Cache cache = cacheManager.getCache(cacheName);
if (cache == null) {
cacheManager.addCache(cacheName);
cache = cacheManager.getCache(cacheName);
cache.getCacheConfiguration().setEternal(true);
}
return cache;
}
public static CacheManager getCacheManager() {
return cacheManager;
}
}
@@ -0,0 +1,116 @@
package com.adc.da.login.util;
import com.adc.da.login.entity.MyPrincipal;
import com.adc.da.sys.entity.RoleEO;
import com.adc.da.sys.entity.UserEO;
import com.adc.da.sys.service.RoleEOService;
import com.adc.da.sys.service.UserEOServiceImpl;
import com.adc.da.sys.service.iservice.IUserEoService;
import com.adc.da.sys.vo.LabelReturnVo;
import com.adc.da.util.utils.SpringContextHolder;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.UnavailableSecurityManagerException;
import org.apache.shiro.session.InvalidSessionException;
import org.apache.shiro.subject.Subject;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;
import java.util.stream.Collectors;
/**
* @Author doudxw
* @Date 2021/8/3 14:52
*/
@Slf4j
public class CommonUtils {
private static final RoleEOService roleEOService = SpringContextHolder.getBean(RoleEOService.class);
private static final IUserEoService userService = SpringContextHolder.getBean(UserEOServiceImpl.class);
private static final List<LabelReturnVo> labelTypeList=new ArrayList<>();
private static final ExecutorService executorService = new ThreadPoolExecutor(400,800
,10L,TimeUnit.SECONDS,new LinkedBlockingQueue<>(200)
,new ThreadFactoryBuilder().setNameFormat("price-pool-%d").build());
private static final ExecutorService executorServiceLabel=new ThreadPoolExecutor(100, 200
, 60L, TimeUnit.SECONDS
, new LinkedBlockingQueue<>(),new ThreadFactoryBuilder().setNameFormat("label-pool-%d").build());
static {
labelTypeList.add(new LabelReturnVo("labelOne","1"));
labelTypeList.add(new LabelReturnVo("labelTwo","2"));
labelTypeList.add(new LabelReturnVo("labelThree","3"));
}
public static String getUserId() {
// String userId = null;
// try {
// Subject subject = SecurityUtils.getSubject();
// MyPrincipal principal = (MyPrincipal) subject.getPrincipal();
// if (principal != null) {
// userId = principal.getId();
// }
// } catch (UnavailableSecurityManagerException e) {
// log.error("getUserId UnavailableSecurityManagerException", e);
// } catch (InvalidSessionException e) {
// log.error("getUserId InvalidSessionException", e);
//
// }
// return userId;
// return "BKS7G52TVR";//拆解管理员
return "ZGGJP3N7FT";
}
public static List<RoleEO> getRoleList() throws Exception {
// List<RoleEO> roleList = (List<RoleEO>) CacheUtils.getCache(CACHE_ROLE_LIST);
// if (roleList == null) {
// UserEO user = getUser();
// if (user != null) {
// roleList = roleEOService.getSysRoleListByUserId(user.getUsid());
// }
// CacheUtils.putCache(CACHE_ROLE_LIST, roleList);
// }
if(null == getUserId()) {return null;}
List<RoleEO> roleList = roleEOService.getSysRoleListByUserId(getUserId());
return roleList;
}
public static boolean isAdmin() throws Exception {
List<String> idList = getRoleList().stream().map(RoleEO::getId).collect(Collectors.toList());
if( idList.contains("35LLRCAQ8D")){
return true;
}
return false;
}
public static UserEO getUserInfo(){
UserEO userEO = userService.getUserById(getUserId());
return userEO;
}
public static ExecutorService threadPoolExecutor(){
return executorServiceLabel;
}
public static List<LabelReturnVo> getLableList(){
return labelTypeList;
}
public static ExecutorService getPriceThreadPool(){
return executorService;
}
}
@@ -0,0 +1,480 @@
package com.adc.da.login.util;
import org.apache.commons.codec.binary.Base64;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
import javax.crypto.*;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
/**
* 功能描述 加密常用类
*/
public class EncryptUtil {
// 密钥是16位长度的byte[]进行Base64转换后得到的字符串
public static String key = "LmMGStGtOpF4xNyvYt54EQ==";
/**
* <li>
* 方法名称:encrypt</li> <li>
* 加密方法
*
* @param xmlStr
* 需要加密的消息字符串
* @return 加密后的字符串
*/
public static String encrypt(String xmlStr) {
byte[] encrypt = null;
try {
// 取需要加密内容的utf-8编码。
encrypt = xmlStr.getBytes("utf-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
// 取MD5Hash码,并组合加密数组
byte[] md5Hasn = null;
try {
md5Hasn = EncryptUtil.MD5Hash(encrypt, 0, encrypt.length);
} catch (Exception e) {
e.printStackTrace();
}
// 组合消息体
byte[] totalByte = EncryptUtil.addMD5(md5Hasn, encrypt);
// 取密钥和偏转向量
byte[] key = new byte[8];
byte[] iv = new byte[8];
getKeyIV(EncryptUtil.key, key, iv);
SecretKeySpec deskey = new SecretKeySpec(key, "DES");
IvParameterSpec ivParam = new IvParameterSpec(iv);
// 使用DES算法使用加密消息体
byte[] temp = null;
try {
temp = EncryptUtil.DES_CBC_Encrypt(totalByte, deskey, ivParam);
} catch (Exception e) {
e.printStackTrace();
}
// 使用Base64加密后返回
return new BASE64Encoder().encode(temp);
}
/**
* <li>
* 方法名称:encrypt</li> <li>
* 功能描述:
*
* <pre>
* 解密方法
* </pre>
*
* </li>
*
* @param xmlStr
* 需要解密的消息字符串
* @return 解密后的字符串
* @throws Exception
*/
public static String decrypt(String xmlStr) throws Exception {
// base64解码
BASE64Decoder decoder = new BASE64Decoder();
byte[] encBuf = null;
try {
encBuf = decoder.decodeBuffer(xmlStr);
} catch (IOException e) {
e.printStackTrace();
}
// 取密钥和偏转向量
byte[] key = new byte[8];
byte[] iv = new byte[8];
getKeyIV(EncryptUtil.key, key, iv);
SecretKeySpec deskey = new SecretKeySpec(key, "DES");
IvParameterSpec ivParam = new IvParameterSpec(iv);
// 使用DES算法解密
byte[] temp = null;
try {
temp = EncryptUtil.DES_CBC_Decrypt(encBuf, deskey, ivParam);
} catch (Exception e) {
e.printStackTrace();
}
// 进行解密后的md5Hash校验
byte[] md5Hash = null;
try {
md5Hash = EncryptUtil.MD5Hash(temp, 16, temp.length - 16);
} catch (Exception e) {
e.printStackTrace();
}
// 进行解密校检
for (int i = 0; i < md5Hash.length; i++) {
if (md5Hash[i] != temp[i]) {
// System.out.println(md5Hash[i] + "MD5校验错误。" + temp[i]);
throw new Exception("MD5校验错误。");
}
}
// 返回解密后的数组,其中前16位MD5Hash码要除去。
return new String(temp, 16, temp.length - 16, "utf-8");
}
/**
* <li>
* 方法名称:TripleDES_CBC_Encrypt</li> <li>
* 功能描述:
*
* <pre>
* 经过封装的三重DES/CBC加密算法,如果包含中文,请注意编码。
* </pre>
*
* </li>
*
* @param sourceBuf
* 需要加密内容的字节数组。
* @param deskey
* KEY 由24位字节数组通过SecretKeySpec类转换而成。
* @param ivParam
* IV偏转向量,由8位字节数组通过IvParameterSpec类转换而成。
* @return 加密后的字节数组
* @throws Exception
*/
public static byte[] TripleDES_CBC_Encrypt(byte[] sourceBuf,
SecretKeySpec deskey, IvParameterSpec ivParam) throws Exception {
byte[] cipherByte;
// 使用DES对称加密算法的CBC模式加密
Cipher encrypt = Cipher.getInstance("TripleDES/CBC/PKCS5Padding");
encrypt.init(Cipher.ENCRYPT_MODE, deskey, ivParam);
cipherByte = encrypt.doFinal(sourceBuf, 0, sourceBuf.length);
// 返回加密后的字节数组
return cipherByte;
}
/**
* <li>
* 方法名称:TripleDES_CBC_Decrypt</li> <li>
* 功能描述:
*
* <pre>
* 经过封装的三重DES / CBC解密算法
* </pre>
*
* </li>
*
* @param sourceBuf
* 需要解密内容的字节数组
* @param deskey
* KEY 由24位字节数组通过SecretKeySpec类转换而成。
* @param ivParam
* IV偏转向量,由6位字节数组通过IvParameterSpec类转换而成。
* @return 解密后的字节数组
* @throws Exception
*/
public static byte[] TripleDES_CBC_Decrypt(byte[] sourceBuf,
SecretKeySpec deskey, IvParameterSpec ivParam) throws Exception {
byte[] cipherByte;
// 获得Cipher实例,使用CBC模式。
Cipher decrypt = Cipher.getInstance("TripleDES/CBC/PKCS5Padding");
// 初始化加密实例,定义为解密功能,并传入密钥,偏转向量
decrypt.init(Cipher.DECRYPT_MODE, deskey, ivParam);
cipherByte = decrypt.doFinal(sourceBuf, 0, sourceBuf.length);
// 返回解密后的字节数组
return cipherByte;
}
/**
* <li>
* 方法名称:DES_CBC_Encrypt</li> <li>
* 功能描述:
*
* <pre>
* 经过封装的DES/CBC加密算法,如果包含中文,请注意编码。
* </pre>
*
* </li>
*
* @param sourceBuf
* 需要加密内容的字节数组。
* @param deskey
* KEY 由8位字节数组通过SecretKeySpec类转换而成。
* @param ivParam
* IV偏转向量,由8位字节数组通过IvParameterSpec类转换而成。
* @return 加密后的字节数组
* @throws Exception
*/
public static byte[] DES_CBC_Encrypt(byte[] sourceBuf,
SecretKeySpec deskey, IvParameterSpec ivParam) throws Exception {
byte[] cipherByte;
// 使用DES对称加密算法的CBC模式加密
Cipher encrypt = Cipher.getInstance("DES/CBC/PKCS5Padding");
encrypt.init(Cipher.ENCRYPT_MODE, deskey, ivParam);
cipherByte = encrypt.doFinal(sourceBuf, 0, sourceBuf.length);
// 返回加密后的字节数组
return cipherByte;
}
/**
* <li>
* 方法名称:DES_CBC_Decrypt</li> <li>
* 功能描述:
*
* <pre>
* 经过封装的DES/CBC解密算法。
* </pre>
*
* </li>
*
* @param sourceBuf
* 需要解密内容的字节数组
* @param deskey
* KEY 由8位字节数组通过SecretKeySpec类转换而成。
* @param ivParam
* IV偏转向量,由6位字节数组通过IvParameterSpec类转换而成。
* @return 解密后的字节数组
* @throws Exception
*/
public static byte[] DES_CBC_Decrypt(byte[] sourceBuf,
SecretKeySpec deskey, IvParameterSpec ivParam) throws Exception {
byte[] cipherByte;
// 获得Cipher实例,使用CBC模式。
Cipher decrypt = Cipher.getInstance("DES/CBC/PKCS5Padding");
// 初始化加密实例,定义为解密功能,并传入密钥,偏转向量
decrypt.init(Cipher.DECRYPT_MODE, deskey, ivParam);
cipherByte = decrypt.doFinal(sourceBuf, 0, sourceBuf.length);
// 返回解密后的字节数组
return cipherByte;
}
/**
* <li>
* 方法名称:MD5Hash</li> <li>
* 功能描述:
*
* <pre>
* MD5,进行了简单的封装,以适用于加,解密字符串的校验。
* </pre>
*
* </li>
*
* @param buf
* 需要MD5加密字节数组。
* @param offset
* 加密数据起始位置。
* @param length
* 需要加密的数组长度。
* @return
* @throws Exception
*/
public static byte[] MD5Hash(byte[] buf, int offset, int length)
throws Exception {
MessageDigest md = MessageDigest.getInstance("MD5");
md.update(buf, offset, length);
return md.digest();
}
/**
* <li>
* 方法名称:byte2hex</li> <li>
* 功能描述:
*
* <pre>
* 字节数组转换为二行制表示
* </pre>
*
* </li>
*
* @param inStr
* 需要转换字节数组。
* @return 字节数组的二进制表示。
*/
public static String byte2hex(byte[] inStr) {
String stmp;
StringBuffer out = new StringBuffer(inStr.length * 2);
for (int n = 0; n < inStr.length; n++) {
// 字节做"与"运算,去除高位置字节 11111111
stmp = Integer.toHexString(inStr[n] & 0xFF);
if (stmp.length() == 1) {
// 如果是0至F的单位字符串,则添加0
out.append("0" + stmp);
} else {
out.append(stmp);
}
}
return out.toString();
}
/**
* <li>
* 方法名称:addMD5</li> <li>
* 功能描述:
*
* <pre>
* MD校验码 组合方法,前16位放MD5Hash码。 把MD5验证码byte[],加密内容byte[]组合的方法。
* </pre>
*
* </li>
*
* @param md5Byte
* 加密内容的MD5Hash字节数组。
* @param bodyByte
* 加密内容字节数组
* @return 组合后的字节数组,比加密内容长16个字节。
*/
public static byte[] addMD5(byte[] md5Byte, byte[] bodyByte) {
int length = bodyByte.length + md5Byte.length;
byte[] resutlByte = new byte[length];
// 前16位放MD5Hash码
for (int i = 0; i < length; i++) {
if (i < md5Byte.length) {
resutlByte[i] = md5Byte[i];
} else {
resutlByte[i] = bodyByte[i - md5Byte.length];
}
}
return resutlByte;
}
/**
* <li>
* 方法名称:getKeyIV</li> <li>
* 功能描述:
*
* <pre>
*
* </pre>
* </li>
*
* @param encryptKey
* @param key
* @param iv
*/
public static void getKeyIV(String encryptKey, byte[] key, byte[] iv) {
// 密钥Base64解密
BASE64Decoder decoder = new BASE64Decoder();
byte[] buf = null;
try {
buf = decoder.decodeBuffer(encryptKey);
} catch (IOException e) {
e.printStackTrace();
}
// 前8位为key
int i;
for (i = 0; i < key.length; i++) {
key[i] = buf[i];
}
// 后8位为iv向量
for (i = 0; i < iv.length; i++) {
iv[i] = buf[i + 8];
}
}
/**
* AES加密算法
*
* @param content
* 加密内容
* @param password
* 密匙
* @return
*/
public static String encryptAES(String content, String password) {
try {
if (content == null || content.equalsIgnoreCase("")) {
return "";
}
KeyGenerator kgen = KeyGenerator.getInstance("AES");
SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
secureRandom.setSeed(password.getBytes());
kgen.init(128, secureRandom);
SecretKey secretKey = kgen.generateKey();
byte[] enCodeFormat = secretKey.getEncoded();
SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");
BASE64Encoder coder = new BASE64Encoder();
coder.encode(enCodeFormat);
Cipher cipher = Cipher.getInstance("AES");
byte[] byteContent = content.getBytes("utf-8");
cipher.init(1, key);
byte[] result = cipher.doFinal(byteContent);
String str = Base64.encodeBase64String(result);
return str;
} catch (NoSuchAlgorithmException var13) {
var13.printStackTrace();
} catch (NoSuchPaddingException var14) {
var14.printStackTrace();
} catch (InvalidKeyException var15) {
var15.printStackTrace();
} catch (UnsupportedEncodingException var16) {
var16.printStackTrace();
} catch (IllegalBlockSizeException var17) {
var17.printStackTrace();
} catch (BadPaddingException var18) {
var18.printStackTrace();
}
return null;
}
/**
* AES解密
*
* @param str
* @param password
* @return
*/
public static String decryptAES(String str, String password) {
try {
if (str == null || str.equalsIgnoreCase("")) {
return "";
}
byte[] content = Base64.decodeBase64(str);
KeyGenerator kgen = KeyGenerator.getInstance("AES");
SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
secureRandom.setSeed(password.getBytes());
kgen.init(128, secureRandom);
SecretKey secretKey = kgen.generateKey();
byte[] enCodeFormat = secretKey.getEncoded();
SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");
Cipher cipher = Cipher.getInstance("AES");// 创建密码器
cipher.init(Cipher.DECRYPT_MODE, key);// 初始化
byte[] result = cipher.doFinal(content);
return new String(result, "utf-8"); // 加密
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
return "";
}
}
@@ -0,0 +1,142 @@
package com.adc.da.login.util;
import com.adc.da.sys.service.UserEOServiceImpl;
import com.adc.da.sys.service.iservice.IUserEoService;
import com.adc.da.sys.vo.UserVO;
import com.adc.da.util.utils.SpringContextHolder;
import com.adc.da.util.utils.StringUtils;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import java.util.Date;
import java.util.Map;
import java.util.UUID;
public class JWTUtils {
private static final long EXPIRE_TIME = 30L *60L * 1000L;
//设置存放token的key
private static final String TOKEN_KEY = "Authorization";
private static final String KEY = "tokenkey";
private static IUserEoService userService = SpringContextHolder.getBean(UserEOServiceImpl.class);
/**
* 生成JWT字符串
*
* @param userVO
* @param ttlMillis
* @return
*/
public static String createJWT(Object userVO) {
SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
long nowMillis = System.currentTimeMillis();
long expMills;
//设置过期时间
expMills=nowMillis+EXPIRE_TIME;
Date exp = new Date(expMills);
Date now = new Date(nowMillis);
//添加构成JWT的参数
JwtBuilder builder = Jwts.builder().setHeaderParam("typ", "JWT")
.claim("id", UUID.randomUUID().toString())
.claim("isu", now)
.claim("sub", userVO)
.claim("exp", expMills)
.signWith(signatureAlgorithm, KEY);
//添加Token过期时间
builder.setExpiration(exp).setNotBefore(now);
//生成JWT
return builder.compact();
}
/**
* 解码
*
* @param jwt
* @return
*/
public static Claims parseJWT(String jwt) {
Claims claims = Jwts.parser()
.setSigningKey(KEY)
.parseClaimsJws(jwt).getBody();
return claims;
}
/**
* 校验用户
*
* @param token
* @return
*/
// public static boolean auth(String token) {
// Claims claims = parseJWT(token);
// //校验用户
// Map<String, Object> userMap = (Map<String, Object>) claims.get("sub");
// String id = userMap.get("userId").toString();
// if (StringUtils.isNotBlank(id)) {
// UserVO user = userService.(id);
// if (user != null) {
// return true;
// }
// }
// return false;
// }
/**
* 判断token是否过期
*
* @param
* @return
*/
public static boolean isExp(String token) {
Claims claims = parseJWT(token);
Date exp = claims.getExpiration();
long now = System.currentTimeMillis();
Date currentDate = new Date(now);
return currentDate.after(exp);
}
/**
* 判断token刷新时间是否过期
*
* @param
* @return
*/
public static boolean isAllowRefresh(String token) {
Claims claims = parseJWT(token);
long refreshTime = (long) claims.get("refresh_ttl");
long now = System.currentTimeMillis();
Date refreshDate = new Date(refreshTime);
Date currentDate = new Date(now);
if (currentDate.after(refreshDate)) {
return false;
} else {
return true;
}
}
/**
* 获取token-key
*
* @return
*/
public static String getTokenKey() {
return TOKEN_KEY;
}
public static void main(String[] args) {
System.out.println(createJWT(null));
}
}
@@ -0,0 +1,347 @@
package com.adc.da.login.util;
import com.adc.da.login.entity.MyPrincipal;
import com.adc.da.sys.entity.MenuEO;
import com.adc.da.sys.entity.RoleEO;
import com.adc.da.sys.entity.UserEO;
import com.adc.da.login.security.SystemAuthorizingRealm;
import com.adc.da.sys.service.MenuEOService;
import com.adc.da.sys.service.RoleEOService;
import com.adc.da.sys.service.UserEOServiceImpl;
import com.adc.da.sys.service.iservice.IUserEoService;
import com.adc.da.util.http.ResponseMessage;
import com.adc.da.util.http.Result;
import com.adc.da.util.utils.CollectionUtils;
import com.adc.da.util.utils.ObjectUtils;
import com.adc.da.util.utils.SpringContextHolder;
import com.google.common.collect.Maps;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.UnavailableSecurityManagerException;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.session.InvalidSessionException;
import org.apache.shiro.subject.Subject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.PostMapping;
import java.util.List;
import java.util.Map;
/**
* 用户信息工具类
*
* @author comments created by Lee Kwanho
* date 2018-09-05
**/
public class UserUtils {
/**
* 日志
*/
private static final Logger logger = LoggerFactory.getLogger(UserUtils.class);
/**
* 当前登陆用户
*/
public static final String CURRENT_USER = "currentUser";
/**
* 角色信息
*/
public static final String CACHE_ROLE_LIST = "roleList";
/**
* 菜单信息
*/
public static final String CACHE_MENU_LIST = "menuList";
/**
* 菜单树
*/
public static final String CACHE_MENU_TREE = "menuTree";
/**
* 保留
*/
public static final String CACHE_AREA_LIST = "areaList";
/**
* 保留
*/
public static final String CACHE_OFFICE_LIST = "officeList";
/**
* 行业数据权限
*/
public static final String CACHE_INDUSTRY_LIST = "industryList";
/**
* @see UserEOService
*/
private static IUserEoService userService = SpringContextHolder.getBean(UserEOServiceImpl.class);
/**
* @see MenuEOService
*/
private static MenuEOService menuService = SpringContextHolder.getBean(MenuEOService.class);
/**
* @see RoleEOService
*/
private static RoleEOService roleEOService = SpringContextHolder.getBean(RoleEOService.class);
private UserUtils() {
throw new IllegalStateException("UserUtils.java");
}
/**
* 退出
*/
public static void logout() {
try {
SecurityUtils.getSubject().logout();
} catch (UnavailableSecurityManagerException e) {
logger.error("logout UnavailableSecurityManagerException", e);
} catch (InvalidSessionException e) {
logger.error("logout InvalidSessionException", e);
}
}
/**
* 获取当前登录用户ID
*
* @return userId
*/
public static String getUserId() {
String userId = null;
try {
Subject subject = SecurityUtils.getSubject();
MyPrincipal principal = (MyPrincipal) subject.getPrincipal();
if (principal != null) {
userId = principal.getId();
}
} catch (UnavailableSecurityManagerException e) {
logger.error("getUserId UnavailableSecurityManagerException", e);
} catch (InvalidSessionException e) {
logger.error("getUserId InvalidSessionException", e);
}
return userId;
//return "BKS7G52TVR";
}
/**
* 获取当前登录用户信息
*/
public static UserEO getUser() {
UserEO user = (UserEO) CacheUtils.getCache(CURRENT_USER);
if (user == null) {
String userId = getUserId();
if (StringUtils.isNotEmpty(userId)) {
UserEO userInDb = userService.getUserById(userId);
user = ObjectUtils.clone(userInDb);
user.setPassword(null);
CacheUtils.putCache(CURRENT_USER, user);
}
}
return user;
}
/**
* 修改当前用户信息
*
* @param userVo 用户信息
* @throws Exception 异常信息
*/
public static void updateUserInfo(UserEO userVo) throws Exception {
// UserEO user = (UserEO) CacheUtils.getCache(CURRENT_USER);
// if (user != null) {
// String userId = getUserId();
//
// if (StringUtils.isNotEmpty(userId)) {
// UserEO userInDb = userService.selectByPrimaryKey(userId);
// userInDb.setUsname(userVo.getUsname());
// userService.save(userInDb);
//
// CacheUtils.removeCache(CURRENT_USER);
// }
// }
}
/**
* 获取当前登录用户角色列表
*
* @return 角色信息
* @throws Exception
*/
public static List<RoleEO> getRoleList() throws Exception {
// List<RoleEO> roleList = (List<RoleEO>) CacheUtils.getCache(CACHE_ROLE_LIST);
// if (roleList == null) {
// UserEO user = getUser();
// if (user != null) {
// roleList = roleEOService.getSysRoleListByUserId(user.getUsid());
// }
// CacheUtils.putCache(CACHE_ROLE_LIST, roleList);
// }
if(null == getUserId()) {return null;}
List<RoleEO> roleList = roleEOService.getSysRoleListByUserId(getUserId());
return roleList;
}
/**
* @return
* @throws Exception
*/
public static String getRoleIds() throws Exception {
List<RoleEO> roleList = getRoleList();
if (CollectionUtils.isEmpty(roleList)) {
return "";
}
StringBuilder roleIds = new StringBuilder();
for (RoleEO sysRoleEO : roleList) {
roleIds.append(sysRoleEO.getId()).append(",");
}
return roleIds.substring(0, roleIds.length() - 1);
}
/**
* 获取当前登录用户菜单列表
*/
public static List<MenuEO> getMenuList() throws Exception {
List<MenuEO> menuList = (List<MenuEO>) CacheUtils.getCache(CACHE_MENU_LIST);
if (menuList == null) {
UserEO user = getUser();
if (user != null) {
if (isAdmin(user)) {
menuList = menuService.findAll();
} else {
menuList = menuService.listMenuEOByUserId(String.valueOf(user.getUsid()));
}
CacheUtils.putCache(CACHE_MENU_LIST, menuList);
}
}
return menuList;
}
/**
* 获取当前登录用户菜单树
*/
public static MenuEO getMenuTree() {
MenuEO menu = (MenuEO) CacheUtils.getCache(CACHE_MENU_TREE);
if (menu != null) {
CacheUtils.putCache(CACHE_MENU_TREE, menu);
}
return menu;
}
/**
* 判断用户是否是超级管理员
*
* @param userVo 用户信息
* @return 返回判断
*/
public static boolean isAdmin(UserEO userVo) {
return userVo != null && "GHVRTMA9H2".equals(userVo.getUsid());
}
/**
* 获取用户菜单权限信息
*/
public static SimpleAuthorizationInfo getAuthInfo() throws Exception {
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
List<MenuEO> list = UserUtils.getMenuList();
List<RoleEO> roleEOList = UserUtils.getRoleList();
for (MenuEO menu : list) {
if (StringUtils.isNotBlank(menu.getPermission())) {
// 添加基于Permission的权限信息
for (String permission : StringUtils.split(menu.getPermission(), ",")) {
info.addStringPermission(permission);
}
}
}
for (RoleEO roleEO : roleEOList) {
if (StringUtils.isNotBlank(roleEO.getName()) && roleEO.getDelFlag() == 0) {
// 添加角色信息
info.addRole(roleEO.getName());
}
}
return info;
}
/**
* 清空缓存
*/
public static void flush() {
CacheUtils.removeCache(CURRENT_USER);
CacheUtils.removeCache(CACHE_MENU_LIST);
CacheUtils.removeCache(CACHE_MENU_TREE);
}
/**
*
*/
private static final class CacheUtils {
/**
* @param key
* @return
*/
public static Object getCache(String key) {
return getCache(key, null);
}
/**
* @param key
* @param defaultValue
* @return
*/
public static Object getCache(String key, Object defaultValue) {
Object obj = getCacheMap().get(key);
return obj == null ? defaultValue : obj;
}
/**
* @param key
* @param value
*/
public static void putCache(String key, Object value) {
getCacheMap().put(key, value);
}
/**
* @param key
*/
public static void removeCache(String key) {
getCacheMap().remove(key);
}
/**
* @return
*/
public static Map<String, Object> getCacheMap() {
Map<String, Object> map = Maps.newHashMap();
try {
Subject subject = SecurityUtils.getSubject();
MyPrincipal principal = (MyPrincipal) subject.getPrincipal();
return principal != null ? principal.getCacheMap() : map;
} catch (UnavailableSecurityManagerException e) {
logger.error("getCacheMap UnavailableSecurityManagerException", e);
} catch (InvalidSessionException e) {
logger.error("getCacheMap InvalidSessionException", e);
}
return map;
}
}
}
@@ -0,0 +1,52 @@
package com.adc.da.login.vo;
import com.adc.da.base.entity.BaseEntity;
/**
* <b>功能:</b>LoginVO<br>
* <b>作者:</b>Alex<br>
* <b>日期:</b> 2018-7-31 <br>
* <b>版权所有:<b>版权归天津卡达克数据技术中心所有。<br>
*/
public class LoginVO extends BaseEntity {
/**
* 用户名
*/
private String username;
/**
* 密码
*/
private String password;
/**
* 验证码
*/
private String verifyCode;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getVerifyCode() {
return verifyCode;
}
public void setVerifyCode(String verifyCode) {
this.verifyCode = verifyCode;
}
}
@@ -0,0 +1,29 @@
package com.adc.da.login.vo;
import java.util.List;
import com.adc.da.login.entity.OnlineUserEO;
public class OnlineUserVO {
private List<OnlineUserEO> onlineUsers;
private Integer total;
public List<OnlineUserEO> getOnlineUsers() {
return onlineUsers;
}
public void setOnlineUsers(List<OnlineUserEO> onlineUsers) {
this.onlineUsers = onlineUsers;
}
public Integer getTotal() {
return total;
}
public void setTotal(Integer total) {
this.total = total;
}
}
+454
View File
@@ -0,0 +1,454 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.adc</groupId>
<artifactId>ca-data</artifactId>
<version>2.5.0</version>
</parent>
<artifactId>adc-da-main</artifactId>
<packaging>jar</packaging>
<name>web</name>
<description>web project for Spring Boot</description>
<properties>
<docker.image.prefix>adc</docker.image.prefix>
<!-- 阿里云仓库地址-->
<docker.repository.url>registry.cn-hangzhou.aliyuncs.com</docker.repository.url>
<!-- 阿里云仓库命名空间-->
<docker.repository.namespace>adc-da</docker.repository.namespace>
<docker.repository.serverId>adc-da-docker</docker.repository.serverId>
<docker.registry.name>adc</docker.registry.name>
</properties>
<!--setting.xml-->
<!--<servers>-->
<!--<server>-->
<!--&lt;!&ndash;登陆仓库的账号密码&ndash;&gt;-->
<!--<id>docker-aliyun-my</id>-->
<!--<username>xxxx@xxx.com</username>-->
<!--<password>xxxx</password>-->
<!--<configuration>-->
<!--<email>xxx@xxxx.com</email>-->
<!--</configuration>-->
<!--</server>-->
<!--</servers>-->
<repositories>
<repository>
<id>adc</id>
<url>http://60.247.58.121:8182/repository/public</url>
<releases>
<enabled>true</enabled>
<updatePolicy>always</updatePolicy>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
<repository>
<id>snapshot</id>
<url>http://60.247.58.121:8182/repository/snapshots/</url>
<releases>
<enabled>false</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
<updatePolicy>always</updatePolicy>
<checksumPolicy>warn</checksumPolicy>
</snapshots>
</repository>
</repositories>
<dependencies>
<!--<dependency>-->
<!--<groupId>com.adc</groupId>-->
<!--<artifactId>adc-da-demo</artifactId>-->
<!--<version>2.5.0</version>-->
<!--</dependency>-->
<!--&lt;!&ndash; ADC-DA框架前台 &ndash;&gt;-->
<!--<dependency>-->
<!--<groupId>com.adc</groupId>-->
<!--<artifactId>adc-da-ui</artifactId>-->
<!--<version>2.5.0</version>-->
<!--</dependency>-->
<!-- 框架基础组件 -->
<dependency>
<groupId>com.adc</groupId>
<artifactId>adc-da-base</artifactId>
<version>3.0.0-SNAPSHOT</version>
<exclusions>
<exclusion>
<artifactId>adc-da-util</artifactId>
<groupId>com.adc</groupId>
</exclusion>
</exclusions>
</dependency>
<!-- 工具类组件 -->
<dependency>
<groupId>com.adc</groupId>
<artifactId>adc-da-util</artifactId>
<version>2.3.3-SNAPSHOT</version>
</dependency>
<!-- 系统管理组件 -->
<!--<dependency>-->
<!--<groupId>com.adc</groupId>-->
<!--<artifactId>adc-da-sys</artifactId>-->
<!--<version>2.3.2-SNAPSHOT</version>-->
<!--<exclusions>-->
<!--<exclusion>-->
<!--<artifactId>adc-da-base</artifactId>-->
<!--<groupId>com.adc</groupId>-->
<!--</exclusion>-->
<!--<exclusion>-->
<!--<artifactId>adc-da-util</artifactId>-->
<!--<groupId>com.adc</groupId>-->
<!--</exclusion>-->
<!--</exclusions>-->
<!--</dependency>-->
<!-- 登录组件 -->
<!--<dependency>-->
<!--<groupId>com.adc</groupId>-->
<!--<artifactId>adc-da-login</artifactId>-->
<!--<version>2.3.3-SNAPSHOT</version>-->
<!--<exclusions>-->
<!--<exclusion>-->
<!--<artifactId>adc-da-sys</artifactId>-->
<!--<groupId>com.adc</groupId>-->
<!--</exclusion>-->
<!--<exclusion>-->
<!--<artifactId>adc-da-util</artifactId>-->
<!--<groupId>com.adc</groupId>-->
<!--</exclusion>-->
<!--<exclusion>-->
<!--<artifactId>adc-da-base</artifactId>-->
<!--<groupId>com.adc</groupId>-->
<!--</exclusion>-->
<!--</exclusions>-->
<!--</dependency>-->
<dependency>
<groupId>com.adc</groupId>
<artifactId>adc-da-login</artifactId>
<version>2.5.0</version>
</dependency>
<dependency>
<groupId>com.adc</groupId>
<artifactId>adc-da-sys</artifactId>
<version>2.5.0</version>
</dependency>
<dependency>
<groupId>com.adc</groupId>
<artifactId>adc-da-report</artifactId>
<version>2.5.0</version>
</dependency>
<!-- <dependency>-->
<!-- <groupId>com.adc</groupId>-->
<!-- <artifactId>adc-da-price</artifactId>-->
<!-- <version>2.5.0</version>-->
<!-- </dependency>-->
<!-- <dependency>-->
<!-- <groupId>com.adc</groupId>-->
<!-- <artifactId>adc-da-configuration</artifactId>-->
<!-- <version>2.5.0</version>-->
<!-- </dependency>-->
<!--<dependency>-->
<!--<groupId>com.adc</groupId>-->
<!--<artifactId>adc-da-ui</artifactId>-->
<!--<version>2.5.0</version>-->
<!--</dependency>-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
</dependency>
<!-- <dependency> -->
<!-- <groupId>com.adc</groupId> -->
<!-- <artifactId>adc-da-jmetrics</artifactId> -->
<!-- <version>2.0.0</version> -->
<!-- </dependency> -->
<!-- <dependency> -->
<!-- <groupId>com.adc</groupId> -->
<!-- <artifactId>adc-da-threadpool</artifactId> -->
<!-- <version>2.0.0</version> -->
<!-- </dependency> -->
<!-- <dependency> -->
<!-- <groupId>com.adc</groupId> -->
<!-- <artifactId>adc-da-redis</artifactId> -->
<!-- <version>2.0.0</version> -->
<!-- </dependency> -->
<!-- 文件上传下载组件 -->
<dependency>
<groupId>com.adc</groupId>
<artifactId>adc-da-file</artifactId>
<version>2.0.0</version>
<exclusions>
<exclusion>
<artifactId>adc-da-base</artifactId>
<groupId>com.adc</groupId>
</exclusion>
<exclusion>
<artifactId>adc-da-util</artifactId>
<groupId>com.adc</groupId>
</exclusion>
</exclusions>
</dependency>
<!-- 代码生成组件 -->
<dependency>
<groupId>com.adc</groupId>
<artifactId>adc-da-gen</artifactId>
<version>2.3.2-SNAPSHOT</version>
</dependency>
<!-- Druid数据库连接池组件 -->
<!--<dependency>-->
<!--<groupId>com.adc</groupId>-->
<!--<artifactId>adc-da-druid</artifactId>-->
<!--<version>2.0.2</version>-->
<!--</dependency>-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.9</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<!-- jdk1.7支持2.4.6版本es客户端,jdk1.8支持6.0版本es客户端 -->
<!--<dependency>-->
<!--<groupId>org.elasticsearch</groupId>-->
<!--<artifactId>elasticsearch</artifactId>-->
<!--</dependency>-->
<!--<dependency>-->
<!--<groupId>org.elasticsearch.client</groupId>-->
<!--<artifactId>transport</artifactId>-->
<!--<version>6.0.0</version>-->
<!--</dependency>-->
<!-- 6.0版本es需添加此依赖,解决依赖冲突 -->
<!--<dependency>-->
<!--<groupId>org.apache.logging.log4j</groupId>-->
<!--<artifactId>log4j-core</artifactId>-->
<!--</dependency>-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
</dependency>
<!-- MybatisPlus代码生成器 -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>3.2.0</version>
</dependency>
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.29</version>
</dependency>
<dependency>
<groupId>net.sourceforge.javacsv</groupId>
<artifactId>javacsv</artifactId>
<version>2.0</version>
</dependency>
<dependency>
<groupId>net.sf.opencsv</groupId>
<artifactId>opencsv</artifactId>
<version>2.3</version>
</dependency>
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</dependency>
<dependency>
<groupId>com.mashape.unirest</groupId>
<artifactId>unirest-java</artifactId>
</dependency>
<!-- 支持sql server的驱动 -->
<dependency>
<groupId>com.microsoft.sqlserver</groupId>
<artifactId>mssql-jdbc</artifactId>
</dependency>
<!-- 支持oracle 12c的驱动 -->
<dependency>
<groupId>com.oracle</groupId>
<artifactId>ojdbc7</artifactId>
</dependency>
<!-- 支持MySQL的驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>net.sf.json-lib</groupId>
<artifactId>json-lib</artifactId>
<version>2.4</version>
<classifier>jdk15</classifier>
<exclusions>
<exclusion>
<artifactId>commons-logging</artifactId>
<groupId>commons-logging</groupId>
</exclusion>
<exclusion>
<artifactId>commons-beanutils</artifactId>
<groupId>commons-beanutils</groupId>
</exclusion>
<exclusion>
<artifactId>commons-collections</artifactId>
<groupId>commons-collections</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.4.1</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpcore</artifactId>
<version>4.4.1</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
</dependency>
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>swagger-bootstrap-ui</artifactId>
<version>1.8.9</version>
<exclusions>
<exclusion>
<groupId>javax.mail</groupId>
<artifactId>mailapi</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- <dependency>-->
<!-- <groupId>javax.mail</groupId>-->
<!-- <artifactId>mailapi</artifactId>-->
<!-- <version>1.4.7</version>-->
<!-- </dependency>-->
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<includeSystemScope>true</includeSystemScope>
</configuration>
<!-- <configuration> -->
<!-- <executable>true</executable> -->
<!-- <fork>true</fork> -->
<!-- <addResources>true</addResources> -->
<!-- <includeSystemScope>true</includeSystemScope> -->
<!-- </configuration> -->
<!-- <executions> -->
<!-- <execution> -->
<!-- <goals> -->
<!-- <goal>repackage</goal> -->
<!-- </goals> -->
<!-- <configuration> -->
<!-- 非必填项,即在生成的jar包名称后面追加该分类名称 -->
<!-- <classifier>boot</classifier> -->
<!-- <mainClass>com.adc.StandardApplication</mainClass> -->
<!-- </configuration> -->
<!-- </execution> -->
<!-- </executions> -->
</plugin>
<plugin>
<groupId>io.github.swagger2markup</groupId>
<artifactId>swagger2markup-maven-plugin</artifactId>
<version>1.3.1</version>
<configuration>
<swaggerInput>http://localhost:8080/v2/api-docs</swaggerInput>
<outputDir>src/docs/asciidoc/generated</outputDir>
<config>
<swagger2markup.markupLanguage>ASCIIDOC</swagger2markup.markupLanguage>
</config>
</configuration>
</plugin>
<plugin>
<groupId>org.asciidoctor</groupId>
<artifactId>asciidoctor-maven-plugin</artifactId>
<version>1.5.6</version>
<configuration>
<sourceDirectory>src/docs/asciidoc/generated</sourceDirectory>
<outputDirectory>src/docs/asciidoc/html</outputDirectory>
<backend>html</backend>
<sourceHighlighter>coderay</sourceHighlighter>
<attributes>
<toc>left</toc>
</attributes>
</configuration>
</plugin>
<plugin>
<groupId>com.spotify</groupId>
<artifactId>docker-maven-plugin</artifactId>
<version>1.1.1</version>
<configuration>
<forceTags>true</forceTags>
<pushImage>true</pushImage>
<buildArgs>
<JAR_FILE>${project.build.finalName}.jar</JAR_FILE>
</buildArgs>
<imageName>${docker.repository.url}/${docker.repository.namespace}/${docker.registry.name}/${project.artifactId}:${project.version}</imageName>
<serverId>${docker.repository.serverId}</serverId>
<registryUrl>${docker.repository.url}</registryUrl>
<dockerDirectory>src/main/docker</dockerDirectory>
<resources>
<resource>
<targetPath>/</targetPath>
<directory>${project.build.directory}</directory>
<include>${project.build.finalName}.jar</include>
</resource>
</resources>
</configuration>
</plugin>
</plugins>
</build>
</project>
@@ -0,0 +1,18 @@
package com.adc.da;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.ComponentScan;
@SpringBootApplication
@ServletComponentScan
@ComponentScan("com.adc")
public class AdcDaApplication {
public static void main(String[] args) {
ApplicationContext applicationContext = SpringApplication.run(AdcDaApplication.class, args);
}
}
@@ -0,0 +1,16 @@
package com.adc.da;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
/**
* Springboot打war包的启动口
*/
public class ServletInitializer extends SpringBootServletInitializer {
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
// 注意这里要指向原先用main方法执行的Application启动类
return builder.sources(AdcDaApplication.class);
}
}
@@ -0,0 +1,39 @@
package com.adc.da.main.advice;
import com.adc.da.util.exception.AdcDaBaseException;
import com.adc.da.util.http.ResponseMessage;
import com.adc.da.util.http.ResponseMessageCodeEnum;
import com.adc.da.util.http.Result;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.annotation.Order;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
@ControllerAdvice
@Order(value=3)
public class AdcDaBaseExceptionAdvice {
private static final Logger logger = LoggerFactory.getLogger(AdcDaBaseExceptionAdvice.class);
@ResponseStatus(HttpStatus.OK)
@ExceptionHandler(AdcDaBaseException.class)
@ResponseBody
public ResponseMessage handlerAdcDaBaseException(AdcDaBaseException exception) {
logger.warn(exception.getMessage(), exception);
return Result.error(exception.getErrorCode(), exception.getMessage());
}
@ResponseStatus(HttpStatus.OK)
@ExceptionHandler(Exception.class)
@ResponseBody
public ResponseMessage handlerAdcDaBaseException(Exception exception) {
logger.error(exception.getMessage(), exception);
// TODO 在数据库中记录程序异常,这个地方的异常是未处理的异常,需要管理员查看并进行处理以防重复出现
return Result.error(ResponseMessageCodeEnum.ERROR.getCode(), "程序异常,请重试。如果重复出现请联系管理员处理!");
}
}
@@ -0,0 +1,31 @@
package com.adc.da.main.advice;
import com.adc.da.util.http.ResponseMessage;
import com.adc.da.util.http.Result;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.multipart.MultipartException;
@ControllerAdvice
public class MultipartExceptionAdvice {
private static final Logger logger = LoggerFactory.getLogger(MultipartExceptionAdvice.class);
@Value("${spring.servlet.multipart.max-file-size}")
private String maxFileSize;
@ResponseStatus(HttpStatus.OK)
@ExceptionHandler(MultipartException.class)
@ResponseBody
public ResponseMessage handlerAdcDaBaseException(MultipartException exception) {
logger.warn(exception.getMessage(), exception);
return Result.error("文件大小超过限制(" + maxFileSize.toUpperCase() + ")");
}
}
@@ -0,0 +1,84 @@
package com.adc.da.main.advice;
import com.adc.da.util.http.ResponseMessage;
import com.adc.da.util.http.ResponseMessageCodeEnum;
import com.adc.da.util.http.Result;
import com.adc.da.util.http.ValidError;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.annotation.Order;
import org.springframework.http.HttpStatus;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import javax.validation.ValidationException;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
/**
* 参考:http://javaninja.net/2013/12/getting-spring-mvc-validation-messages-from-a-json-service/
*/
@ControllerAdvice
public class NotValidExceptionAdvice {
private static final Logger logger = LoggerFactory.getLogger(NotValidExceptionAdvice.class);
@ExceptionHandler(MethodArgumentNotValidException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ResponseBody
public ResponseMessage<List<ValidError>> handleMethodArgumentNotValidException(
MethodArgumentNotValidException exception) {
// logger.error(exception.getMessage(), exception);
List<ValidError> validErrorList = new ArrayList<>();
BindingResult result = exception.getBindingResult();
for (FieldError fieldError : result.getFieldErrors()) {
validErrorList.add(new ValidError(fieldError.getField(), fieldError.getDefaultMessage()));
logger.warn("valid error: obj[{}], filed[{}], message[{}]",
fieldError.getObjectName(),
fieldError.getField(),
fieldError.getDefaultMessage());
}
return Result.error(ResponseMessageCodeEnum.VALID_ERROR.getCode(), "", validErrorList);
}
@ExceptionHandler(ConstraintViolationException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ResponseBody
public ResponseMessage<List<ValidError>> handleConstraintViolationException(
ConstraintViolationException exception) {
// logger.error(exception.getMessage(), exception);
List<ValidError> validErrorList = new ArrayList<>();
Set<ConstraintViolation<?>> violationSet = exception.getConstraintViolations();
for (ConstraintViolation violation : violationSet) {
validErrorList.add(new ValidError(violation.getPropertyPath().toString(), violation.getMessage()));
logger.warn("param valid error: obj[{}], filed[{}], message[{}]",
violation.getRootBeanClass(),
violation.getPropertyPath(),
violation.getMessage());
}
return Result.error(ResponseMessageCodeEnum.VALID_ERROR.getCode(), "", validErrorList);
}
@ExceptionHandler(value = ValidationException.class)
public ResponseMessage validationExceptionHandling(ValidationException e) {
ResponseMessage result = Result.error(e.getMessage());
return result;
}
}
@@ -0,0 +1,44 @@
package com.adc.da.main.advice;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authz.UnauthenticatedException;
import org.apache.shiro.authz.UnauthorizedException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.annotation.Order;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import com.adc.da.util.http.ResponseMessage;
import com.adc.da.util.http.ResponseMessageCodeEnum;
import com.adc.da.util.http.Result;
@ControllerAdvice
@Order(value=0)
public class ShiroExceptionAdvice {
private static final Logger logger = LoggerFactory.getLogger(ShiroExceptionAdvice.class);
@ResponseStatus(HttpStatus.UNAUTHORIZED)
@ExceptionHandler({AuthenticationException.class, UnknownAccountException.class,
UnauthenticatedException.class, IncorrectCredentialsException.class})
@ResponseBody
public ResponseMessage unauthorized(Exception exception) {
logger.warn(exception.getMessage(), exception);
logger.info("catch UnknownAccountException");
return Result.error(ResponseMessageCodeEnum.ERROR.getCode(), exception.getMessage());
}
@ResponseStatus(HttpStatus.UNAUTHORIZED)
@ExceptionHandler(UnauthorizedException.class)
@ResponseBody
public ResponseMessage unauthorized1(UnauthorizedException exception) {
logger.warn(exception.getMessage(), exception);
return Result.error(ResponseMessageCodeEnum.ERROR.getCode(), exception.getMessage());
}
}
@@ -0,0 +1,25 @@
package com.adc.da.main.advice;
import com.adc.da.util.http.ResponseMessage;
import com.adc.da.util.http.Result;
import org.springframework.core.annotation.Order;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;
/**
* @Author doudxw
* @Date 2021/4/27 14:13
*/
@RestControllerAdvice
@Order(1)
public class ValidExcetipnAdvice {
@ExceptionHandler(MethodArgumentNotValidException.class)
@ResponseStatus(HttpStatus.OK)
public ResponseMessage valisException(MethodArgumentNotValidException ex){
return Result.error(ex.getBindingResult().getFieldError().getDefaultMessage());
}
}
@@ -0,0 +1,36 @@
package com.adc.da.main.aspect;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import com.adc.da.util.utils.GsonUtil;
/**
* 用于记录调用controller层返回日志
*/
@Aspect
@Component
public class ResponseLogAspect {
private static Logger logger = LoggerFactory.getLogger(ResponseLogAspect.class);
/**
* 匹配controller层的方法
*/
@Pointcut(value = "(execution(* com.adc.da.*.rest.*.*(..)))")
private void controllerPointcut() {
// 切面方法
}
@Around(value = "controllerPointcut()")
public Object process(ProceedingJoinPoint joinPoint) throws Throwable {
Object result = joinPoint.proceed();
logger.info("==================== 调用Controller层返回json值 ====================");
logger.info(GsonUtil.toJson(result));
return result;
}
}
@@ -0,0 +1,63 @@
//package com.adc.da.main.config.DataSource;
//
//import com.baomidou.mybatisplus.core.MybatisConfiguration;
//import com.baomidou.mybatisplus.core.MybatisXMLLanguageDriver;
//import com.baomidou.mybatisplus.core.config.GlobalConfig;
//import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
//import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean;
//import org.apache.ibatis.plugin.Interceptor;
//import org.apache.ibatis.session.SqlSessionFactory;
//import org.apache.ibatis.type.JdbcType;
//import org.mybatis.spring.SqlSessionTemplate;
//import org.mybatis.spring.annotation.MapperScan;
//import org.springframework.beans.factory.annotation.Qualifier;
//import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
//import org.springframework.context.annotation.Bean;
//import org.springframework.context.annotation.Configuration;
//import org.springframework.context.annotation.Primary;
//import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
//import org.springframework.jdbc.datasource.DataSourceTransactionManager;
//
//import javax.sql.DataSource;
//
///**
// * @Author doudxw
// * @Date 2022/1/5 09:19
// * for kylin
// * 连接长安麒麟的数据源
// */
//@Configuration
//@ConditionalOnProperty(prefix = "datatype",name ="change",havingValue ="kylin" )
//@MapperScan(basePackages = "com.adc.da.**.dao.kylin", sqlSessionTemplateRef = "ds1SqlSessionTemplate")
//public class DataSource1 {
//
// //ds1数据源
// @Bean("ds1SqlSessionFactory")
// public SqlSessionFactory ds1SqlSessionFactory(@Qualifier("ds1DataSource") DataSource dataSource) throws Exception {
// MybatisSqlSessionFactoryBean sqlSessionFactory = new MybatisSqlSessionFactoryBean();
// sqlSessionFactory.setDataSource(dataSource);
// MybatisConfiguration configuration = new MybatisConfiguration();
// configuration.setDefaultScriptingLanguage(MybatisXMLLanguageDriver.class);
// configuration.setJdbcTypeForNull(JdbcType.NULL);
// sqlSessionFactory.setConfiguration(configuration);
// sqlSessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver().
// getResources("classpath*:mybatis/mapper/**/kylin/**/*.xml"));
// sqlSessionFactory.setPlugins(new Interceptor[]{
// new PaginationInterceptor()
//// .setFormat(true),
// });
// sqlSessionFactory.setGlobalConfig(new GlobalConfig().setBanner(false));
// return sqlSessionFactory.getObject();
// }
//
// @Bean(name = "ds1TransactionManager")
// public DataSourceTransactionManager ds1TransactionManager(@Qualifier("ds1DataSource") DataSource dataSource) {
// return new DataSourceTransactionManager(dataSource);
// }
//
// @Bean(name = "ds1SqlSessionTemplate")
// public SqlSessionTemplate ds1SqlSessionTemplate(@Qualifier("ds1SqlSessionFactory") SqlSessionFactory sqlSessionFactory) {
// return new SqlSessionTemplate(sqlSessionFactory);
// }
//
//}
@@ -0,0 +1,61 @@
//package com.adc.da.main.config.DataSource;
//
//import com.baomidou.mybatisplus.core.MybatisConfiguration;
//import com.baomidou.mybatisplus.core.MybatisXMLLanguageDriver;
//import com.baomidou.mybatisplus.core.config.GlobalConfig;
//import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
//import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean;
//import org.apache.ibatis.plugin.Interceptor;
//import org.apache.ibatis.session.SqlSessionFactory;
//import org.apache.ibatis.type.JdbcType;
//import org.mybatis.spring.SqlSessionTemplate;
//import org.mybatis.spring.annotation.MapperScan;
//import org.springframework.beans.factory.annotation.Qualifier;
//import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
//import org.springframework.context.annotation.Bean;
//import org.springframework.context.annotation.Configuration;
//import org.springframework.context.annotation.Primary;
//import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
//import org.springframework.jdbc.datasource.DataSourceTransactionManager;
//
//import javax.sql.DataSource;
//
///**
// * @Author doudxw
// * @Date 2022/1/5 09:19
// * for mysql
// */
//@Configuration
//@ConditionalOnProperty(prefix = "datatype",name ="change",havingValue ="kylin" )
//@MapperScan(basePackages ={"com.adc.da.**.dao.mysql","com.adc.da.file.dao"}, sqlSessionTemplateRef = "ds2SqlSessionTemplate")
//public class DataSource2 {
// //ds2数据源
// @Bean("ds2SqlSessionFactory")
// public SqlSessionFactory ds2SqlSessionFactory(@Qualifier("ds2DataSource") DataSource dataSource) throws Exception {
// MybatisSqlSessionFactoryBean sqlSessionFactory = new MybatisSqlSessionFactoryBean();
// sqlSessionFactory.setDataSource(dataSource);
// MybatisConfiguration configuration = new MybatisConfiguration();
// configuration.setDefaultScriptingLanguage(MybatisXMLLanguageDriver.class);
// configuration.setJdbcTypeForNull(JdbcType.NULL);
// sqlSessionFactory.setConfiguration(configuration);
// sqlSessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver().
// getResources("classpath*:mybatis/mapper/**/mysql/**/*.xml"));
// sqlSessionFactory.setPlugins(new Interceptor[]{
// new PaginationInterceptor()
//// .setFormat(true),
// });
// sqlSessionFactory.setGlobalConfig(new GlobalConfig().setBanner(false));
// return sqlSessionFactory.getObject();
// }
//
// @Primary
// @Bean(name = "ds2TransactionManager")
// public DataSourceTransactionManager ds2TransactionManager(@Qualifier("ds2DataSource") DataSource dataSource) {
// return new DataSourceTransactionManager(dataSource);
// }
//
// @Bean(name = "ds2SqlSessionTemplate")
// public SqlSessionTemplate ds2SqlSessionTemplate(@Qualifier("ds2SqlSessionFactory") SqlSessionFactory sqlSessionFactory) {
// return new SqlSessionTemplate(sqlSessionFactory);
// }
//}
@@ -0,0 +1,79 @@
package com.adc.da.main.config.DataSource;
/**
* @Author doudxw
* @Date 2022/1/5 09:26
*/
import com.alibaba.druid.pool.DruidDataSource;
import com.zaxxer.hikari.HikariDataSource;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import javax.sql.DataSource;
import java.sql.DataTruncation;
/**
* 多数据源配置
*/
@Configuration
@ConditionalOnProperty(prefix = "datatype",name ="change",havingValue ="kylin" )
public class DataSourceConfig {
//主数据源配置 ds1数据源
// @Primary
// @Bean(name = "ds1DataSourceProperties")
// @ConfigurationProperties(prefix = "spring.datasource.kylin")
// public DataSourceProperties ds1DataSourceProperties() {
// return new DataSourceProperties();
// }
//主数据源 ds1数据源
// @Primary
// @Bean(name = "ds1DataSource")
// public DataSource ds1DataSource(@Qualifier("ds1DataSourceProperties") DataSourceProperties dataSourceProperties) {
// DataSource dataSource = dataSourceProperties.initializeDataSourceBuilder().build();
//// HikariDataSource hikariDataSource = (HikariDataSource) dataSource;
//// hikariDataSource.setMinimumIdle(200);
//// hikariDataSource.setMaximumPoolSize(500);
// DataSource build = dataSourceProperties.initializeDataSourceBuilder().build();
// DruidDataSource druidDataSource = new DruidDataSource(dataSourceProperties);
// druidDataSource.setInitialSize(500);
// druidDataSource.setMinIdle(500);
// druidDataSource.setMaxActive(500);
// return druidDataSource;
// }
// @Primary
// @Bean(name = "ds1DataSource")
// public DataSource druidDataSource(@Qualifier("ds1DataSourceProperties") DataSourceProperties dataSourceProperties){
// DruidDataSource druidDataSource = new DruidDataSource();
// druidDataSource.setDriverClassName(dataSourceProperties.getDriverClassName());
// druidDataSource.setUrl(dataSourceProperties.getUrl());
// druidDataSource.setUsername(dataSourceProperties.getUsername());
// druidDataSource.setPassword(dataSourceProperties.getPassword());
// druidDataSource.setInitialSize(500);
// druidDataSource.setMinIdle(500);
// druidDataSource.setMaxActive(500);
// return druidDataSource;
// }
//
// //第二个ds2数据源配置
// @Bean(name = "ds2DataSourceProperties")
// @ConfigurationProperties(prefix = "spring.datasource.mysql")
// public DataSourceProperties ds2DataSourceProperties() {
// return new DataSourceProperties();
// }
//
// //第二个ds2数据源
// @Bean("ds2DataSource")
// public DataSource ds2DataSource(@Qualifier("ds2DataSourceProperties") DataSourceProperties dataSourceProperties) {
// return dataSourceProperties.initializeDataSourceBuilder().build();
// }
}
@@ -0,0 +1,43 @@
//package com.adc.da.main.config.DataSource;
//
//import com.alibaba.druid.filter.Filter;
//import com.alibaba.druid.filter.logging.Slf4jLogFilter;
//import com.alibaba.druid.filter.stat.StatFilter;
//import com.alibaba.druid.pool.DruidDataSource;
//import com.alibaba.druid.support.http.StatViewServlet;
//import com.alibaba.druid.support.http.WebStatFilter;
//import com.alibaba.druid.support.spring.stat.DruidStatInterceptor;
//import com.alibaba.druid.wall.WallConfig;
//import com.alibaba.druid.wall.WallFilter;
//import org.bouncycastle.pqc.math.linearalgebra.PolynomialRingGF2;
//import org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator;
//import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
//import org.springframework.boot.context.properties.ConfigurationProperties;
//import org.springframework.boot.web.servlet.FilterRegistrationBean;
//import org.springframework.boot.web.servlet.ServletRegistrationBean;
//import org.springframework.context.EnvironmentAware;
//import org.springframework.context.annotation.Bean;
//import org.springframework.context.annotation.Configuration;
//import org.springframework.core.env.Environment;
//import org.springframework.jdbc.datasource.DataSourceTransactionManager;
//
//import javax.sql.DataSource;
//import java.util.ArrayList;
//import java.util.HashMap;
//import java.util.List;
//import java.util.Map;
//
///**
// * @Author sima
// * @Date 2022/6/9 11:45
// */
////@Configuration
////@ConditionalOnProperty(prefix = "datatype",name ="change",havingValue ="mysql" )
//public class DruidDataSourceConfig {
//// @ConfigurationProperties(prefix = "spring.datasource")
//// @Bean
//// public DataSource druidDataSource(){
//// return new DruidDataSource();
//// }
//}
//
@@ -0,0 +1,24 @@
package com.adc.da.main.config;
import java.util.Arrays;
import java.util.List;
import org.dozer.DozerBeanMapper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* 各个模块的dozer配置文件
*/
@Configuration
public class DozerConfig {
@Bean(name = "org.dozer.Mapper")
public DozerBeanMapper dozer() {
List<String> mappingFiles = Arrays.asList("dozer/dozer-mappings-sys.xml");
DozerBeanMapper dozerBean = new DozerBeanMapper();
dozerBean.setMappingFiles(mappingFiles);
return dozerBean;
}
}
@@ -0,0 +1,39 @@
package com.adc.da.main.config;
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
//import com.baomidou.mybatisplus.extension.plugins.PerformanceInterceptor;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.annotation.EnableTransactionManagement;
/**
* MybatisPlus配置
*/
@Configuration
@MapperScan({"com.adc.da.**.dao","com.adc.**.dao"})
@EnableTransactionManagement
public class MybatisPlusConfig {
/**
* MybatisPlus分页插件
*/
@Bean
public PaginationInterceptor paginationInterceptor() {
return new PaginationInterceptor();
}
/***
* MybatisPlus的性能优化
*/
// @Bean
// public PerformanceInterceptor performanceInterceptor() {
// PerformanceInterceptor performanceInterceptor = new PerformanceInterceptor();
// /* <!-- SQL 执行性能分析,开发环境使用,线上不推荐。 maxTime 指的是 sql 最大执行时长 --> */
// // performanceInterceptor.setMaxTime(1000);
// /* <!--SQL是否格式化 默认false--> */
// performanceInterceptor.setFormat(true);
// return performanceInterceptor;
// }
}
@@ -0,0 +1,24 @@
package com.adc.da.main.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
/**
* @Author doudxw
* @Date 2021/11/11 09:38
*/
@Configuration
public class RedisConfig {
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
RedisTemplate<String, Object> template = new RedisTemplate();
template.setConnectionFactory(factory);
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
template.setDefaultSerializer(jackson2JsonRedisSerializer);
return template;
}
}
@@ -0,0 +1,103 @@
package com.adc.da.main.config;
import com.adc.da.util.filter.CorsFilter;
import com.adc.da.util.filter.CsrfFilter;
import com.adc.da.util.filter.FakeJSessionIdFilter;
import com.adc.da.util.filter.HttpCacheFilter;
import com.adc.da.util.filter.RequestInfoFilter;
import com.adc.da.util.security.filter.TimestampFilter;
import com.adc.da.util.xss.XssFilter;
import com.adc.da.util.security.filter.NonceFilter;
import com.adc.da.util.xssshield.XssShieldFilter;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* Web配置,用于注入过滤器,拦截器等
*/
//@Configuration
public class WebConfig {
// @Bean
// public FilterRegistrationBean urlFilter(){
// FilterRegistrationBean registration = new FilterRegistrationBean();
// registration.setFilter(new UrlFilter());
// registration.addUrlPatterns("/home/pic/html/*");
// registration.setName("urlFilter");
// registration.setOrder(1);
// return registration;
//
// }
/**
* xss过滤器(高标准)
*/
@Bean
public FilterRegistrationBean xssFilter() {
FilterRegistrationBean registration = new FilterRegistrationBean();
registration.setFilter(new XssFilter());
registration.addUrlPatterns("/*");
registration.setName("xssFilter");
registration.setOrder(10);
return registration;
}
@Bean
public FilterRegistrationBean csrfFilter() {
FilterRegistrationBean registration = new FilterRegistrationBean();
registration.setFilter(new CsrfFilter());
registration.addUrlPatterns("/*");
registration.setName("csrfFilter");
registration.setOrder(9);
return registration;
}
@Bean
public FilterRegistrationBean requestInfoFilter() {
FilterRegistrationBean registration = new FilterRegistrationBean();
registration.setFilter(new RequestInfoFilter());
registration.addUrlPatterns("/*");
registration.setName("RequestInfoFilter");
registration.setOrder(8);
return registration;
}
@Bean
public FilterRegistrationBean corsFilter() {
FilterRegistrationBean registration = new FilterRegistrationBean();
registration.setFilter(new CorsFilter());
registration.addUrlPatterns("/*");
registration.setName("corsFilter");
registration.setOrder(7);
return registration;
}
@Bean
public FilterRegistrationBean httpCacheFilter() {
FilterRegistrationBean registration = new FilterRegistrationBean();
registration.setFilter(new HttpCacheFilter());
registration.addUrlPatterns("/*");
registration.setName("httpCacheFilter");
registration.addInitParameter("maxAge", String.valueOf(60 * 60 * 24 * 7));
registration.setOrder(6);
return registration;
}
/**
* 防伪造jsessionid
*/
@Bean
public FilterRegistrationBean fakeJSessionIdFilter() {
FilterRegistrationBean registration = new FilterRegistrationBean();
registration.setFilter(new FakeJSessionIdFilter());
registration.addUrlPatterns("/*");
registration.setName("fakeJSessionIdFilter");
registration.setOrder(5);
return registration;
}
}
@@ -0,0 +1,27 @@
package com.adc.da.main.config;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
/**
* @Author doudxw
* @Date 2021/6/30 14:21
*/
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
@Value("${picPath}")
private String picPath;
@Value("${uploadFile}")
private String uploadFile;
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
// /home/file/**为前端URL访问路径 后面 file:xxxx为本地磁盘映射
registry.addResourceHandler(picPath+"**").addResourceLocations("file://"+uploadFile);
}
}
@@ -0,0 +1,38 @@
package com.adc.da.main.schedule;
/**
* @Author sima
* @Date 2022/7/15 16:32
*/
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
/**
* @Auther: sima
* @Date: 2022/7/15 16:32
* 配置类,解决定时任务无法注入的问题
*/
@Component
public class ApplicationContextUtil implements ApplicationContextAware {
private static ApplicationContext applicationContext;
public static ApplicationContext getApplicationContext() {
return applicationContext;
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
ApplicationContextUtil.applicationContext = applicationContext;
}
public static Object getBean(String beanName) {
return applicationContext.getBean(beanName);
}
}
@@ -0,0 +1,29 @@
//package com.adc.da.main.schedule;
//
//import com.adc.da.price.service.impl.CarQueryServiceImpl;
//import lombok.extern.slf4j.Slf4j;
//import org.springframework.scheduling.annotation.EnableScheduling;
//import org.springframework.scheduling.annotation.Scheduled;
//import org.springframework.stereotype.Component;
//
///**
// * @Author sima
// * @Date 2022/7/15 16:32
// */
//@Component
//@EnableScheduling
//@Slf4j
//public class ScheduleUtil {
//
//
// @Scheduled(cron = "0 0 0 * * ?")
//// @Scheduled(cron = "0 */1 * * * ?")
// public void updateCarQuery() {
// log.debug("开始更新查询表--------------***************--------------");
// CarQueryServiceImpl carQueryService= (CarQueryServiceImpl) ApplicationContextUtil.getBean("carQueryServiceImpl");
// carQueryService.insert();
//// System.out.println(carQueryService);
// log.debug("查询表更新完成--------------***************--------------");
//
// }
//}
@@ -0,0 +1,133 @@
#Development System
#spring.datasource.driverClassName = oracle.jdbc.OracleDriver
#spring.datasource.url = jdbc:oracle:thin:@//60.247.58.117:50011/ADC
##spring.datasource.username = ADC_PLATFORM
##spring.datasource.password = ADC_PLATFORM
#spring.datasource.url = jdbc:oracle:thin:@//192.168.144.136:19290/ADC
#spring.datasource.username = EPR
#spring.datasource.password = EPR
#spring.datasource.url = jdbc:oracle:thin:@//192.168.144.103:19290/ADC
#spring.datasource.username = EPR_TEST
#spring.datasource.password = EPR_TEST
#spring.datasource.driverClassName = com.mysql.jdbc.Driver
#spring.datasource.url = jdbc:mysql://192.168.144.124:3306/cadata2?characterEncoding=utf-8&&zeroDateTimeBehavior=convertToNull
#spring.datasource.username = adc_forecast
#spring.datasource.password = adc_forecast
#kylin数据库 ds1
#spring.datasource.kylin.name=PROJECT_MI
#spring.datasource.kylin.driverClassName=org.apache.kylin.jdbc.Driver
#spring.datasource.kylin.url=jdbc:kylin://10.64.23.8:7070/PROJECT_MI
#spring.datasource.kylin.username=64459
#spring.datasource.kylin.password=ichangan_ps9
##10s
#spring.datasource.kylin.maxWaitTime=10000
#spring.datasource.kylin.poolSize=10
#
##mysql数据库 ds2
#spring.datasource.mysql.driverClassName = com.mysql.jdbc.Driver
#spring.datasource.mysql.url = jdbc:mysql://192.168.144.80:3306/cadata?characterEncoding=utf-8&&zeroDateTimeBehavior=convertToNull
#spring.datasource.mysql.username = root
#spring.datasource.mysql.password = root
spring.datasource.driverClassName = com.mysql.cj.jdbc.Driver
spring.datasource.url = jdbc:mysql://121.36.69.172:3307/report-library?characterEncoding=UTF-8&useUnicode=true&useSSL=false&tinyInt1isBit=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai
spring.datasource.username = root
spring.datasource.password = hzwlsoft.com
#后端端口
server.port=7060
#验证码后台模式,默认为1:1为不开启,2为开启,3为输错 用户名或密码 ${maxLoginErrorCount} 次 才开启
verifyCodeMode=3
#仅当验证码模式 ${verifyCodeMode} 为 3时生效,设置错误登录出现验证码的阈值,默认为3
maxLoginErrorCount=3
#密码Base64加密开关,true为开启,false为关闭
isPassEncrypted=true
#{
#"password": "YWJjMTIz",
#"username": "YWRtaW4x"
#}
#swagger 显示api1为只显示${restPath:/api}前缀的api,0为显示所有api,其他为不显示api
swaggerLevel=0
#uploadFile=/EPR/file/EPR/test/
#
#picPath=/EPR/file/home/pic/
# 本地存储文件的磁盘地址
uploadFile=D:\\work\\idea\\changan\\
# 本地文件访问的url地址
picPath=/api/home/pic/
serverIp=http://127.0.0.1:7060/
#MAIL_SMTP =smtp.163.com
#MAIL_SMTP_PORT=465
#MAIL_USERNAME=cagds@catarc.ac.cn
#MAIL_PASSWORD=Cagds9760
MAIL_SMTP =smtp.163.com
MAIL_SMTP_PORT=465
MAIL_USERNAME=simashihao@163.com
MAIL_PASSWORD=VQBNNQBLDIALAYCV
#MAIL_SMTP =cmp.changan.com
#MAIL_SMTP_PORT=25
MAIL_POP_PORT=110
#MAIL_USERNAME=64459@Any3.com
#MAIL_PASSWORD=65316975Xiaoq
IPANDPORT=http://localhost:7061/
#redis
#Redis服务器地址
spring.redis.host=192.168.144.29
#spring.redis.host=localhost
## Redis服务器连接端口
spring.redis.port=6379
## Redis服务器连接密码(默认为空)
spring.redis.password=123321
## 连接超时时间(毫秒)
spring.redis.timeout=200000ms
## 连接池中的最大空闲连接,默认值是8。
spring.redis.jedis.pool.max-idle=50
##连接池中的最小空闲连接,默认值是0。
spring.redis.jedis.pool.min-idle=10
## 如果赋值为-1,则表示不限制;如果pool已经分配了maxActive个jedis实例,则此时pool的状态为exhausted(耗尽)。
spring.redis.jedis.pool.max-active=2000
## 等待可用连接的最大时间,单位毫秒,默认值为-1,表示永不超时。如果超过等待时间,则直接抛出JedisConnectionException
spring.redis.jedis.pool.max-wait=2000ms
spring.redis.database=6
# ======= 阿里OSS配置 =========
aliyun.OSS.endpoint=https://oss-cn-hangzhou.aliyuncs.com
aliyun.OSS.accessKeyId= LTAI5tBmUfVF6Z8R6sHTdTG7
aliyun.OSS.accessKeySecret= mY6UvWv20Tg2R46ORe6uV5gL6TQloC
aliyun.OSS.bucketName=qqxexamplebucket
aliyun.OSS.fileMaxSize=10 #文件上传最大M数
logging.level.com.adc: debug
# ======= ddm权限接口 集成 =========
ddm-identity=changan_test
ddm-company=9
ddm-ras-public-key=
@@ -0,0 +1,117 @@
spring.profiles.active=dev
###############################################
#公共配置部分
##############################################
# ===============================
# = DATA SOURCE
# ===============================
spring.datasource.type = com.alibaba.druid.pool.DruidDataSource
# 下面为连接池的补充设置,应用到上面所有数据源中
# 初始化大小,最小,最大
spring.datasource.initialSize = 500
spring.datasource.minIdle = 500
spring.datasource.maxActive = 500
# 配置获取连接等待超时的时间
spring.datasource.maxWait = 60000
# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
spring.datasource.timeBetweenEvictionRunsMillis = 30000
# 配置一个连接在池中最小生存的时间,单位是毫秒
spring.datasource.minEvictableIdleTimeMillis = 100000
spring.datasource.validationQuery= 'SELECT 1 FROM DUAL'
spring.datasource.testWhileIdle = true
spring.datasource.testOnBorrow = false
spring.datasource.testOnReturn = false
# 打开PSCache,并且指定每个连接上PSCache的大小
spring.datasource.poolPreparedStatements = true
spring.datasource.maxPoolPreparedStatementPerConnectionSize = 20
# 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙
spring.datasource.filters = stat,wall,log4j
# 通过connectProperties属性来打开mergeSql功能;慢SQL记录
#spring.datasource.connectionProperties = 'druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000'
# 合并多个DruidDataSource的监控数据
#useGlobalDataSourceStat: true
spring.datasource.mergeSql=true
spring.datasource.slowSqlMillis=1
spring.datasource.logSlowSql=true
# ===============================
#默认关闭SpringBootActuator
endpoints.enabled=false
# http-only
server.servlet.session.cookie.http-only=true
# mybatis_config
mybatis-plus.config-locations=classpath:mybatis/mybatis-config.xml
mybatis-plus.mapper-locations=classpath*:mybatis/mapper/**/mysql/**/*.xml
#显示sql
logging.level.com.adc=debug
logging.level.org.hibernate=info
logging.level.org.springframework=info
adminPath=/library/a
restPath=/library/api
portalPath=/library/portalSystem
#是否使用rsa非对称加密(adc-ad-login:2.3.3-SNAPSHOT支持) 使用时,请设置 isPassEncrypted=false
isPassEncrypted=true
useRSALogin=true
#请您执行main模块下test包com.adc.da.rsa.RSATest 的测试方法 生成公钥及私钥,并由公钥前端加密(前端建议使用 jsencrypt工具包),后端配置useRSALogin=true开启加密,并且将生成的私钥配置到RAS_PRI_KEY
RAS_PRI_KEY=MIIBUwIBADANBgkqhkiG9w0BAQEFAASCAT0wggE5AgEAAkEAq1I/fLYOTKgNCwUavqyfixosEXByKMQ9axZDUefPywi+ftXdPI2tJ6x/7uc+CdST0a3/toqxdSRjrsHMwnnGQQIDAQABAkB5ZPBDiCUdwD5tvpIy5dKvGD59pPXfWR5EESRmlyGwNTlJ/fIV1wL7UsRYoFslAEcHLyKY7kX8wIefqw2k9R8hAiEA6mH2xls2BZ6nftz6aA8V6CSrsZ49qO9l6SPirXrxg0UCIQC7H1WXLHEV65PUaMTNvzuLc43xkac9DZX4FpUXDeuIzQIgXghhjiEH4mdNgas8V0U+H72emIsI597r/wYjqj/55xUCIDATfuQWUP+2xQZ/3ICYL25GxCNarsMq6GsTMj74HpnJAiAb6BqTkVklIMsl2lAZbE49fluSm3YLt4eNnVVdzJkpFg==
#{
#"password": "SN/qCzazttK/kzezk+bMo/b/aZP0Mqfpl66hj24p2oayZs3/vDmv7MM9+451I5FTaq2jq/EbOxIjiK2zLAiZ5w==",
#"username": "SC/dfdsf/kzezk+fd/b/fdf/vDmv7MM9+fd/fds=="
#}
#useRSALogin=
#RAS_PRI_KEY=
# file模块上传文件的服务器地址
file.path=/Users/sxh/uploadFiles
# ppt图片保存的路径
file.pptPath=/pptImg
# file模块上传文件大小限制
spring.servlet.multipart.max-request-size=100MB
spring.servlet.multipart.max-file-size=100MB
# 系统日志类别dev:开发模式不拦截方法记日志, custom:客户自定义需要拦截记日志的方法, sys:系统原设需要拦截记日志的方法
sysLogType=dev
#rabbitMQ
spring.rabbitmq.host=192.168.1.219
spring.rabbitmq.port=5672
spring.rabbitmq.username=guest
spring.rabbitmq.password=guest
spring.rabbitmq.publisher-confirms=true
#redis
# Redis服务器地址
spring.redis.host=221.239.111.146
# Redis服务器连接端口
spring.redis.port=15777
# Redis服务器连接密码(默认为空)
spring.redis.password=cvdecs
#线程池
core.pool.size=10
max.pool.size=30
keep.alive.seconds=60
queue.capacity=8
mybatis-plus.configuration.map-underscore-to-camel-case=true
modelpath=/EPR/file/template/eprmodel.docx
wordurl=http://localhost:8333/word/make
#datatype.change=kylin
#datatype.change=mysql
#elastic search
#clusterName=elasticsearch
#clusterNodes=10.10.0.3:9300
@@ -0,0 +1,9 @@
${AnsiColor.RED} _ _
__ _ __| | ___ __| | __ _
/ _` |/ _` |/ __|____ / _` |/ _` |
| (_| | (_| | (_|_____| (_| | (_| |
\__,_|\__,_|\___| \__,_|\__,_|
${AnsiColor.YELLOW}------------------------------------------------
${AnsiColor.YELLOW} :: ${AnsiColor.YELLOW}@数据资源中心
${AnsiColor.YELLOW}------------------------------------------------${AnsiColor.WHITE}
@@ -0,0 +1,32 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE xml>
<ehcache updateCheck="false" name="hibernateCache">
<diskStore path="java.io.tmpdir/jeesite/ehcache/hibernate" />
<!-- DefaultCache setting. -->
<defaultCache maxEntriesLocalHeap="100" eternal="false" timeToIdleSeconds="300" timeToLiveSeconds="600"
overflowToDisk="true" maxEntriesLocalDisk="100000" />
<cache name="com.thinkgem.jeesite.modules.sys.entity.Dict" maxEntriesLocalHeap="100" eternal="false" overflowToDisk="true" maxEntriesLocalDisk="100000" />
<cache name="com.thinkgem.jeesite.modules.sys.entity.Area" maxEntriesLocalHeap="100" eternal="false" overflowToDisk="true" maxEntriesLocalDisk="100000" />
<cache name="com.thinkgem.jeesite.modules.sys.entity.Area.childList" maxEntriesLocalHeap="100" eternal="false" overflowToDisk="true" maxEntriesLocalDisk="100000" />
<cache name="com.thinkgem.jeesite.modules.sys.entity.Area.officeList" maxEntriesLocalHeap="100" eternal="false" overflowToDisk="true" maxEntriesLocalDisk="100000" />
<cache name="com.thinkgem.jeesite.modules.sys.entity.Office" maxEntriesLocalHeap="100" eternal="false" overflowToDisk="true" maxEntriesLocalDisk="100000" />
<cache name="com.thinkgem.jeesite.modules.sys.entity.Office.childList" maxEntriesLocalHeap="100" eternal="false" overflowToDisk="true" maxEntriesLocalDisk="100000" />
<cache name="com.thinkgem.jeesite.modules.sys.entity.Office.userList" maxEntriesLocalHeap="100" eternal="false" overflowToDisk="true" maxEntriesLocalDisk="100000" />
<cache name="com.thinkgem.jeesite.modules.sys.entity.Menu" maxEntriesLocalHeap="100" eternal="false" overflowToDisk="true" maxEntriesLocalDisk="100000" />
<cache name="com.thinkgem.jeesite.modules.sys.entity.Menu.childList" maxEntriesLocalHeap="100" eternal="false" overflowToDisk="true" maxEntriesLocalDisk="100000" />
<cache name="com.thinkgem.jeesite.modules.sys.entity.Menu.roleList" maxEntriesLocalHeap="100" eternal="false" overflowToDisk="true" maxEntriesLocalDisk="100000" />
<cache name="com.thinkgem.jeesite.modules.sys.entity.Role" maxEntriesLocalHeap="100" eternal="false" overflowToDisk="true" maxEntriesLocalDisk="100000" />
<cache name="com.thinkgem.jeesite.modules.sys.entity.Role.menuList" maxEntriesLocalHeap="100" eternal="false" overflowToDisk="true" maxEntriesLocalDisk="100000" />
<cache name="com.thinkgem.jeesite.modules.sys.entity.Role.userList" maxEntriesLocalHeap="100" eternal="false" overflowToDisk="true" maxEntriesLocalDisk="100000" />
<cache name="com.thinkgem.jeesite.modules.sys.entity.User" maxEntriesLocalHeap="100" eternal="false" overflowToDisk="true" maxEntriesLocalDisk="100000" />
<cache name="com.thinkgem.jeesite.modules.sys.entity.User.roleList" maxEntriesLocalHeap="100" eternal="false" overflowToDisk="true" maxEntriesLocalDisk="100000" />
</ehcache>
@@ -0,0 +1,75 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE xml>
<ehcache updateCheck="false" name="hibernateCache">
<!--
<cacheManagerPeerProviderFactory class="net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory"
properties="peerDiscovery=manual, socketTimeoutMillis=2000, rmiUrls=//localhost:40001/hibernateCache" />
<cacheManagerPeerListenerFactory class="net.sf.ehcache.distribution.RMICacheManagerPeerListenerFactory"
properties="hostName=localhost, port=40000, socketTimeoutMillis=2000"/>-->
<cacheManagerPeerProviderFactory class="net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory"
properties="peerDiscovery=automatic,multicastGroupAddress=230.0.0.1, multicastGroupPort=4446" />
<cacheManagerPeerListenerFactory class="net.sf.ehcache.distribution.RMICacheManagerPeerListenerFactory" />
<diskStore path="java.io.tmpdir/jeesite/ehcache/hibernate" />
<!-- DefaultCache setting. -->
<defaultCache maxEntriesLocalHeap="100" eternal="false" timeToIdleSeconds="300" timeToLiveSeconds="600"
overflowToDisk="true" maxEntriesLocalDisk="100000" >
<cacheEventListenerFactory class="net.sf.ehcache.distribution.RMICacheReplicatorFactory"
properties="replicatePuts=false,replicateUpdatesViaCopy=false" />
</defaultCache>
<!-- Special objects setting. -->
<cache name="com.thinkgem.jeesite.modules.sys.entity.Dict" maxEntriesLocalHeap="100" eternal="false" overflowToDisk="true" maxEntriesLocalDisk="100000">
<cacheEventListenerFactory class="net.sf.ehcache.distribution.RMICacheReplicatorFactory" />
</cache>
<cache name="com.thinkgem.jeesite.modules.sys.entity.Area" maxEntriesLocalHeap="100" eternal="false" overflowToDisk="true" maxEntriesLocalDisk="100000">
<cacheEventListenerFactory class="net.sf.ehcache.distribution.RMICacheReplicatorFactory" />
</cache>
<cache name="com.thinkgem.jeesite.modules.sys.entity.Area.childList" maxEntriesLocalHeap="100" eternal="false" overflowToDisk="true" maxEntriesLocalDisk="100000">
<cacheEventListenerFactory class="net.sf.ehcache.distribution.RMICacheReplicatorFactory" />
</cache>
<cache name="com.thinkgem.jeesite.modules.sys.entity.Area.officeList" maxEntriesLocalHeap="100" eternal="false" overflowToDisk="true" maxEntriesLocalDisk="100000">
<cacheEventListenerFactory class="net.sf.ehcache.distribution.RMICacheReplicatorFactory" />
</cache>
<cache name="com.thinkgem.jeesite.modules.sys.entity.Office" maxEntriesLocalHeap="100" eternal="false" overflowToDisk="true" maxEntriesLocalDisk="100000">
<cacheEventListenerFactory class="net.sf.ehcache.distribution.RMICacheReplicatorFactory" />
</cache>
<cache name="com.thinkgem.jeesite.modules.sys.entity.Office.childList" maxEntriesLocalHeap="100" eternal="false" overflowToDisk="true" maxEntriesLocalDisk="100000">
<cacheEventListenerFactory class="net.sf.ehcache.distribution.RMICacheReplicatorFactory" />
</cache>
<cache name="com.thinkgem.jeesite.modules.sys.entity.Office.userList" maxEntriesLocalHeap="100" eternal="false" overflowToDisk="true" maxEntriesLocalDisk="100000">
<cacheEventListenerFactory class="net.sf.ehcache.distribution.RMICacheReplicatorFactory" />
</cache>
<cache name="com.thinkgem.jeesite.modules.sys.entity.Menu" maxEntriesLocalHeap="100" eternal="false" overflowToDisk="true" maxEntriesLocalDisk="100000">
<cacheEventListenerFactory class="net.sf.ehcache.distribution.RMICacheReplicatorFactory" />
</cache>
<cache name="com.thinkgem.jeesite.modules.sys.entity.Menu.childList" maxEntriesLocalHeap="100" eternal="false" overflowToDisk="true" maxEntriesLocalDisk="100000">
<cacheEventListenerFactory class="net.sf.ehcache.distribution.RMICacheReplicatorFactory" />
</cache>
<cache name="com.thinkgem.jeesite.modules.sys.entity.Menu.roleList" maxEntriesLocalHeap="100" eternal="false" overflowToDisk="true" maxEntriesLocalDisk="100000">
<cacheEventListenerFactory class="net.sf.ehcache.distribution.RMICacheReplicatorFactory" />
</cache>
<cache name="com.thinkgem.jeesite.modules.sys.entity.Role" maxEntriesLocalHeap="100" eternal="false" overflowToDisk="true" maxEntriesLocalDisk="100000">
<cacheEventListenerFactory class="net.sf.ehcache.distribution.RMICacheReplicatorFactory" />
</cache>
<cache name="com.thinkgem.jeesite.modules.sys.entity.Role.menuList" maxEntriesLocalHeap="100" eternal="false" overflowToDisk="true" maxEntriesLocalDisk="100000">
<cacheEventListenerFactory class="net.sf.ehcache.distribution.RMICacheReplicatorFactory" />
</cache>
<cache name="com.thinkgem.jeesite.modules.sys.entity.Role.userList" maxEntriesLocalHeap="100" eternal="false" overflowToDisk="true" maxEntriesLocalDisk="100000">
<cacheEventListenerFactory class="net.sf.ehcache.distribution.RMICacheReplicatorFactory" />
</cache>
<cache name="com.thinkgem.jeesite.modules.sys.entity.User" maxEntriesLocalHeap="100" eternal="false" overflowToDisk="true" maxEntriesLocalDisk="100000">
<cacheEventListenerFactory class="net.sf.ehcache.distribution.RMICacheReplicatorFactory" />
</cache>
<cache name="com.thinkgem.jeesite.modules.sys.entity.User.roleList" maxEntriesLocalHeap="100" eternal="false" overflowToDisk="true" maxEntriesLocalDisk="100000">
<cacheEventListenerFactory class="net.sf.ehcache.distribution.RMICacheReplicatorFactory" />
</cache>
</ehcache>
+27
View File
@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE xml>
<ehcache updateCheck="false" name="defaultCache">
<diskStore path="java.io.tmpdir/jeesite/ehcache/default" />
<!-- DefaultCache setting. -->
<defaultCache maxEntriesLocalHeap="100" eternal="false" timeToIdleSeconds="300" timeToLiveSeconds="600"
overflowToDisk="true" maxEntriesLocalDisk="100000" />
<cache name="sysCache" maxElementsInMemory="100" eternal="true" overflowToDisk="true"/>
<cache name="errorCache" maxElementsInMemory="100" timeToIdleSeconds="180" timeToLiveSeconds="300" eternal="false" overflowToDisk="true"/>
<cache name="cmsCache" maxElementsInMemory="100" eternal="true" overflowToDisk="true"/>
<cache name="shiro-activeSessionCache" maxElementsInMemory="100" overflowToDisk="true"
eternal="true" timeToLiveSeconds="0" timeToIdleSeconds="0"
diskPersistent="true" diskExpiryThreadIntervalSeconds="600"/>
<cache name="org.apache.shiro.realm.text.PropertiesRealm-0-accounts"
maxElementsInMemory="100" eternal="true" overflowToDisk="true"/>
<cache name="SimplePageCachingFilter" maxElementsInMemory="100" eternal="false" overflowToDisk="true"
timeToIdleSeconds="120" timeToLiveSeconds="120" memoryStoreEvictionPolicy="LFU"/>
</ehcache>
+54
View File
@@ -0,0 +1,54 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE xml>
<ehcache updateCheck="false" name="defaultCache">
<!--
<cacheManagerPeerProviderFactory class="net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory"
properties="peerDiscovery=manual, socketTimeoutMillis=2000, rmiUrls=//localhost:40001/mainCache" />
<cacheManagerPeerListenerFactory class="net.sf.ehcache.distribution.RMICacheManagerPeerListenerFactory"
properties="hostName=localhost, port=40000, socketTimeoutMillis=2000"/> -->
<cacheManagerPeerProviderFactory class="net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory"
properties="peerDiscovery=automatic,multicastGroupAddress=230.0.0.1, multicastGroupPort=4446" />
<cacheManagerPeerListenerFactory class="net.sf.ehcache.distribution.RMICacheManagerPeerListenerFactory" />
<diskStore path="java.io.tmpdir/jeesite/ehcache/default" />
<!-- DefaultCache setting. -->
<defaultCache maxEntriesLocalHeap="100" eternal="false" timeToIdleSeconds="300" timeToLiveSeconds="600"
overflowToDisk="true" maxEntriesLocalDisk="100000" >
<cacheEventListenerFactory class="net.sf.ehcache.distribution.RMICacheReplicatorFactory"
properties="replicatePuts=false,replicateUpdatesViaCopy=false"/>
</defaultCache>
<!-- Special objects setting. -->
<cache name="sysCache" maxElementsInMemory="100" eternal="true" overflowToDisk="true">
<cacheEventListenerFactory class="net.sf.ehcache.distribution.RMICacheReplicatorFactory"/>
</cache>
<cache name="cmsCache" maxElementsInMemory="100" eternal="true" overflowToDisk="true">
<cacheEventListenerFactory class="net.sf.ehcache.distribution.RMICacheReplicatorFactory"/>
</cache>
<cache name="shiro-activeSessionCache" maxElementsInMemory="100" overflowToDisk="true"
eternal="true" timeToLiveSeconds="0" timeToIdleSeconds="0"
diskPersistent="true" diskExpiryThreadIntervalSeconds="600">
<cacheEventListenerFactory class="net.sf.ehcache.distribution.RMICacheReplicatorFactory"
properties="replicateAsynchronously=true, replicatePuts=true, replicateUpdates=true,
replicateUpdatesViaCopy=false, replicateRemovals=true "/>
</cache>
<cache name="org.apache.shiro.realm.text.PropertiesRealm-0-accounts"
maxElementsInMemory="100" eternal="true" overflowToDisk="true">
<cacheEventListenerFactory class="net.sf.ehcache.distribution.RMICacheReplicatorFactory"
properties="replicateAsynchronously=true, replicatePuts=true, replicateUpdates=true,
replicateUpdatesViaCopy=false, replicateRemovals=true "/>
</cache>
<cache name="SimplePageCachingFilter" maxElementsInMemory="100" eternal="false" overflowToDisk="true"
timeToIdleSeconds="120" timeToLiveSeconds="120" memoryStoreEvictionPolicy="LFU">
<cacheEventListenerFactory class="net.sf.ehcache.distribution.RMICacheReplicatorFactory"
properties="replicateAsynchronously=true, replicatePuts=true, replicateUpdates=true,
replicateUpdatesViaCopy=false, replicateRemovals=true "/>
</cache>
</ehcache>
@@ -0,0 +1,44 @@
#define code path
source_root_package=src/main/java
resources_root_package=src/main/resources
test_root_package=src/test/java
webroot_package=src/app
#define project
core_project=/adc-da-configuration
#client_project=/data-cloud-report/ui
client_project=..
rest_project=/adc-da-configuration
#define base class package
base_class_package=com.adc.da.base
#bussi_package[User defined]
biz_package=com.adc.da
biz_app_package=admin
#ftl resource url
template_path=template
system_encoding=utf-8
#Search Param num [User defined]
table_id=id
search_filed_num=1
#table_prefix=TD_DC_VISUAL_,TD_DC_,dict_,UM_,TD_
table_prefix=TS_,TR_,T,dmk.
#PageType 1: mapper_xml, 2: dao, 3: service, 4: rest, 5: javascript, 6: html
page_gen_type=1,2,3,4
#Not Used
mapper_xml_only=false
backend_only=true
entity_open_type=dialog
entity_save_type=form
@@ -0,0 +1,30 @@
#mysql
#----------------------------- mysql ------------------------------------------
#diver_name=com.mysql.jdbc.Driver
#url=jdbc:mysql://localhost:3306/adc_platform?characterEncoding=utf-8&&zeroDateTimeBehavior=convertToNull
#username=root
#password=root
#database_name=adc_platform
#oracle
#----------------------------- oracle ------------------------------------------
#diver_name=oracle.jdbc.driver.OracleDriver
#url=jdbc:oracle:thin:@60.247.58.117:50011/ADC
#username=ADC_PLATFORM
#password=ADC_PLATFORM
#database_name=adc_platform
diver_name = com.mysql.jdbc.Driver
url = jdbc:mysql://192.168.144.80:3306/cadata?characterEncoding=utf-8&&zeroDateTimeBehavior=convertToNull
username = root
password = root
database_name=cadata
#ldap
#----------------------------- LDAP ------------------------------------------
ldap.connection.url=ldap://localhost:10389
ldap.connection.base=dc=wlt,dc=com
ldap.connection.username=uid=admin,ou=system
ldap.connection.password=12345678
ldap.schema.cn=um
@@ -0,0 +1,177 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<!--*****************************property start*****************************-->
<!-- 设置变量。定义变量后,可以使“${}”来使用变量。 -->
<!-- 项目名称 -->
<property name="PROJECT_NAME" value="adc-da" />
<!-- 定义日志文件的存储地址,勿在 LogBack的配置中使用相对路径 -->
<property name="LOG_HOME" value="../logs" />
<!-- 定义系统日志文件的存储地址,勿在 LogBack的配置中使用相对路径 -->
<property name="LOG_HOME_SYSTEM" value="system" />
<!-- 定义Druid日志文件的存储地址,勿在 LogBack的配置中使用相对路径 -->
<property name="LOG_HOME_DRUID" value="druid" />
<!--*****************************property end*****************************-->
<!--*****************************appender start*****************************-->
<!-- 负责写日志的组件。有两个必要属性name和class。name指定appender名称,class指定appender的全限定名。 -->
<!-- 彩色日志 -->
<!-- 彩色日志依赖的渲染类 -->
<conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter" />
<conversionRule conversionWord="wex" converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter" />
<conversionRule conversionWord="wEx" converterClass="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter" />
<!-- 彩色日志格式 -->
<property name="CONSOLE_LOG_PATTERN" value="${CONSOLE_LOG_PATTERN:-%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/>
<!-- 控制台输出 -->
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<!-- 对日志进行格式化。 -->
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符-->
<Pattern>${CONSOLE_LOG_PATTERN}</Pattern>
<charset>UTF-8</charset>
</encoder>
</appender>
<!-- 系统日志输出:记录所有日志 -->
<!-- RollingFileAppender:滚动记录文件,先将日志记录到指定文件,当符合某个条件时,将日志记录到其他文件。 -->
<appender name="SYSTEM_ALL_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 过滤器,打印指定级别的日志 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<!-- 过滤的日志级别 -->
<level>INFO</level>
<!-- 满足指定级别的日志操作 -->
<onMatch>ACCEPT</onMatch>
<!-- 不满足指定级别的日志操作 -->
<onMismatch>ACCEPT</onMismatch>
</filter>
<!-- rollingPolicy:当发生滚动时,决定 RollingFileAppender 的行为,涉及文件移动和重命名。 -->
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<!--日志文件输出的文件名-->
<FileNamePattern>${LOG_HOME}/${LOG_HOME_SYSTEM}/${PROJECT_NAME}.system_all.%d{yyyy-MM-dd}.%i.log</FileNamePattern>
<!--日志文件保留天数-->
<MaxHistory>7</MaxHistory>
<!--日志文件最大的大小-->
<MaxFileSize>100MB</MaxFileSize>
</rollingPolicy>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符-->
<pattern>[%d{yyyy-MM-dd HH:mm:ss.SSS}] [%thread] [%-5level] %logger{50} - %msg%n</pattern>
<charset>UTF-8</charset>
</encoder>
</appender>
<!-- 系统错误日志输出 -->
<appender name="SYSTEM_ERROR_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 过滤器,只打印ERROR级别的日志 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>ERROR</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<!--日志文件输出的文件名-->
<FileNamePattern>${LOG_HOME}/${LOG_HOME_SYSTEM}/${PROJECT_NAME}.system_error.%d{yyyy-MM-dd}.%i.log</FileNamePattern>
<!--日志文件保留天数-->
<MaxHistory>30</MaxHistory>
<!--日志文件最大的大小-->
<MaxFileSize>100MB</MaxFileSize>
</rollingPolicy>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符-->
<pattern>[%d{yyyy-MM-dd HH:mm:ss.SSS}] [%thread] [%-5level] %logger{50} - %msg%n</pattern>
<charset>UTF-8</charset>
</encoder>
</appender>
<!-- Druid日志输出,用于记录执行INFO级别的慢SQL -->
<appender name="DRUID_SLOWSQL_INFO_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- LevelFilter: 级别过滤器,根据日志级别进行过滤 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>INFO</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<!--日志文件输出的文件名-->
<FileNamePattern>${LOG_HOME}/${LOG_HOME_DRUID}/${PROJECT_NAME}.druid_info.%d{yyyy-MM-dd}.%i.log</FileNamePattern>
<!--日志文件保留天数-->
<MaxHistory>15</MaxHistory>
<!--日志文件最大的大小-->
<MaxFileSize>50MB</MaxFileSize>
</rollingPolicy>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符-->
<pattern>[%d{yyyy-MM-dd HH:mm:ss.SSS}] [%thread] [%-5level] %logger{50} - %msg%n</pattern>
<charset>UTF-8</charset>
</encoder>
</appender>
<!-- Druid打印的日志文件,用于记录执行WARN级别的SQL -->
<appender name="DRUID_SLOWSQL_WARN_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>WARN</level>
</filter>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!--日志文件输出的文件名-->
<FileNamePattern>${LOG_HOME}/${LOG_HOME_DRUID}/${PROJECT_NAME}.druid_warn.%d{yyyy-MM-dd}.%i.log</FileNamePattern>
<!--日志文件保留天数-->
<MaxHistory>30</MaxHistory>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>50MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符-->
<pattern>[%d{yyyy-MM-dd HH:mm:ss.SSS}] [%thread] [%-5level] %logger{50} - %msg%n</pattern>
<charset>UTF-8</charset>
</encoder>
</appender>
<!--*****************************appender end*****************************-->
<!--*****************************logger start*****************************-->
<!-- logger用来设置某一个包或者具体的某一个类的日志打印级别、以及指定<appender> -->
<!-- <logger>仅有一个name属性,一个可选的level和一个可选的additivity属性。 -->
<!-- name:用来指定受此logger约束的某一个包或者具体的某一个类。 -->
<!-- level:用来设置打印级别,大小写无关:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF,还有一个特殊值INHERITED或者同义词NULL,代表强制执行上级的级别。如果未设置此属性,那么当前logger将会继承上级的级别。 -->
<!-- additivity:是否向上级logger传递打印信息。默认是true。 -->
<logger name="com.alibaba.druid" level="INFO" additivity="true">
<appender-ref ref="DRUID_SLOWSQL_INFO_FILE"/>
</logger>
<logger name="com.alibaba.druid" level="warn">
<appender-ref ref="DRUID_SLOWSQL_WARN_FILE"/>
</logger>
<!--*****************************logger end*****************************-->
<!-- 开发环境下的日志配置 -->
<springProfile name="dev">
<root level="INFO">
<appender-ref ref="CONSOLE" />
<appender-ref ref="SYSTEM_ALL_FILE"/>
</root>
</springProfile>
<!-- 生产环境下的日志配置 -->
<springProfile name="prod">
<root level="INFO">
<appender-ref ref="SYSTEM_ALL_FILE"/>
<appender-ref ref="SYSTEM_ERROR_FILE"/>
</root>
</springProfile>
</configuration>
Binary file not shown.

After

Width:  |  Height:  |  Size: 138 KiB

@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!-- 全局参数 -->
<settings>
<setting name="callSettersOnNulls" value="true" />
</settings>
<!-- 配置别名用 -->
<typeAliases>
</typeAliases>
</configuration>
@@ -0,0 +1,297 @@
a#阿
ao#拗口/违拗/拗断/执拗/拗口/拗口风/拗口令/拗曲/拗性/拗折/警拗
ai#艾
bang#膀/磅/蚌
ba#扒
bai#叔伯/百/柏杨/㧳/梵呗/呗佛/呗音/呗唱/呗偈/呗声/呗赞/赞呗
bao#剥皮/薄/暴/堡/曝
bei#呗
beng#蚌埠
bi#复辟/臂/秘鲁/泌阳
bing#屏息/屏弃/屏气/屏除/屏声
bian#扁/便/便宜坊
bo#薄荷/单薄/伯/泊/波/柏/萝卜/孛
bu#卜/柨
can#参
cang#藏/欌
cen#参差
ceng#曾/噌
cha#差/刹那/宝刹/一刹/查/碴/喳喳/喀喳
chai#公差/差役/专差/官差/听差/美差/办差/差事/差使/肥差/当差/钦差/苦差/出差
chan#颤/单于/禅
chang#长/厂
chao#朝/嘲/焯
che#工尺/车
chen#称职/匀称/称心/相称/对称
cheng#称/乘/澄/噌吰/橙 秤/盛满/盛器/盛饭
chu#畜
chui#椎心
chuai#揣
chuan#传
chi#匙/尺/吃
chong#重庆/重重/虫
chou#臭/帱
chuang#经幢
chuo#绰
ci#参差/鳞差/伺候/龟兹
cuan#攒聚/攒动/攒集/攒宫/攒所
cuo#撮儿/撮要/撮合
da#大/嗒
dao#叨/帱载/帱察
dai#大夫
dan#单/弹/掸/澹
dang#铛
de#的/得
di#堤/底/怎的/有的/目的/标的/打的/的确/有的放/的卢/矢之的/言中的/语中的/的士/地/提防/快的/美的
diao#蓝调/调调/音调/论调/格调/调令/低调/笔调/基调/强调/声调/滥调/老调/色调/单调/腔调/跑调/曲调/步调/语调/主调/情调
ding#丁
du#读/都/度
dou#全都/句读
duo#舵/测度/忖度/揣度/猜度
dun#粮囤/盾/顿/沌/敦
e#阿谀/阿胶/阿弥/恶/擜
er#儿
fan#番
feng#冯
fei#婔
fo#佛
fu#仿佛/果脯/罘/莩
fou#否
fiao#覅
ga#咖喱/伽马/嘎/戛纳
gai#盖
gao#告
gang#扛鼎
ge#革/蛤蚧/文蛤/蛤蜊/咯
gei#给
geng#脖颈
gong#女红/共
gu#谷/中鹄/鼓
gui#龟/柜/硅/倭傀/傀异/傀然/傀垒/傀怪/傀卓/傀奇/傀伟/傀民/傀俄/琦傀/奇傀
gua#呱
guan#纶巾/东莞
guang#广
ha#蛤/哈/虾蟆
hai#还/嗨/咳声/咳笑
hao#貉子/貉绒
hang#夯/总行/分行/支行/行业/排行/行情/央行/商行/外行/银行/中行/交行/招行/农行/工行/建行/商行/酒行/麻行/琴行/行业/同行/行列/行货/行会/行家/巷道/引吭/扼吭/批吭/搤吭/高吭/喉吭/咔吭/絶吭/吭嗌/吭咽/吭首
he#和/合/核/鶴/猲
heng#道行/涥
hu#鹄/水浒/嗀/唬
hua#滑/呚/椛
huan#归还/放还/奉还/圜
hui#会/浍河/媈/灳/哕/瑗珲
hong#红/虹
huo#软和/热和/暖和
hun#尡/珲
ji#病革/给养/自给/给水/薪给/给予/供给/稽/缉/藉/奇数/亟/诘屈/荠菜/愱
jia#雪茄/伽/家/价/贾/戛
jian#见/浅浅
jiang#降
jiao#嚼舌/嚼字/嚼蜡/角/剿/饺/脚/蕉/矫/睡觉/侥/校对/校验/校正/校准/审校/校场/校核/校勘/校订/校阅/校样
jie#解/慰藉/蕴藉/诘/媘/煯
jin#矜/劲/禁
jing#颈/景/强劲/劲风/劲旅/劲敌/劲射/苍劲/遒劲/劲草
jiong#炅
ju#咀/居/桔/句/婮
jun#均
juan#棚圈/圈养/猪圈/羊圈
jue#主角/角色/旦角/女角/丑角/角力/名角/配角/嚼/觉/䏐
jun#龟裂/俊
ka#咖/卡/喀
kai#楷
kang#扛
ke#咳/壳
keng#吭
kuai#会计/财会/浍
kui#傀
kuo#括
la#癞痢/腊/蜡
lai#癞疮/癞子/癞蛤/癞皮
lao#积潦/络子/落枕/落价/粩/姥
le#乐/勒/了
lei#勒紧
lo#然咯
lou#佝偻/泄露/露面/露脸/露骨/露底/露馅/露一手/露相/露马脚/露怯
long#里弄/弄堂/泷
li#跞/礼/櫔/栃
liao#了解/了结/明了/了得/末了/未了/了如/潦/撩
liang#靓/俩
lie#挘
lin#崊
ling#霗/令
liu#六/遛
lu#碌/陆/露
luo#络/落/漯/囖/洜/泺
lv#率/绿
lve#鋢/稤
lun#纶
ma#嫲/抹布/抹脸/抹桌子/摩挲
mai#埋
man#埋怨/蔓
mai#脉
mang#氓/芒
mao#冒
me#嚒
men#椚
meng#群氓/盟/癦
mei#没/旀
mo#淹没/没收/出没/沉没/没落/吞没/覆没/没入/埋没/鬼没/隐没/湮没/辱没/脉脉/模/摩/抹
mou#绸缪/牟
mi#秘/泌尿/分泌/谜/檷枸
mian#渑
ming#掵
miu#谬/谬论/纰缪
mu#大模/字模/模板/模样/模具/装模/模子/牟尼/子牟/夷牟/悬牟/相牟/头牟/宾牟/曹牟/岑牟/兜牟/卢牟/弥牟/牟食/牟槊/牟衫/牟光/牟牟/牟甲
na#哪/娜/那
nao#臑
nan#南
ne#哪吒/呢
nei#氞
neus#莻
nong#弄/燶
ni#毛呢/花呢/呢绒/线呢/呢料/呢子/呢喃/溺/檷
niao#尿/鸟/便溺
nian#粘膜/粘度/粘土/粘合剂/粘液/粘稠/粘合/粘着/粘结/粘性/粘附/不粘锅/粘糊/粘虫/粘聚/粘滞/焾/哖
niang#酿
nin#脌
ning#倿/拧
niu#拗/汼
nu#努
nuo#婀娜/袅娜/喏
nv#女
nve#疟/硸
o#喔/筽
ou#膒
pa#扒手/扒窃/扒外/扒分/扒糕/扒灰/扒犁/扒龙/扒搂/扒山虎/扒艇
pai#派/迫击/迫击炮
pao#刨/炮/萢
pan#番禺
pang#胖/膀/磅
pei#蓜
pi#辟/否极/臧否/龙陂/芘
pian#扁舟/便宜/魸
piao#朴姓/饿莩/饥莩/葭莩
pin#穦
ping#屏/苹/冯河
po#湖泊/血泊 /迫/朴刀/坡/陂
pu#一曝十寒/里堡/十里堡/脯/朴/曝晒/瀑/埔
qi#期/其/泣/祇
qiu#龟兹/湭
qi#稽首/缉鞋/栖/奇/漆/齐
qia#卡脖/卡子/关卡/卡壳/哨卡/边卡/发卡/峠
qiao#雀盲/雀子/地壳/甲壳/躯壳
qian#纤/乾/浅
qiang#强/㛨/㩖/䅚/䵁
qie#茄/趔趄/聺/籡
qin#亲/沁
qing#干亲/亲家
qiong#熍
qu#区/趣/爠
quan#圈/券
que#雀/炔
re#声喏/唱喏
rong#嬫
ruo#若/嵶
saeng#栍
sang#槡
sai#塞/嘥
sao#螦
se#堵塞/搪塞/茅塞/闭塞/鼻塞/梗塞/阻塞/淤塞/拥塞/哽塞/色
sha#莎/刹车/急刹/厦/杉木/杉篙
shai#色子
shao#勺/红苕
shan#姓单/单县/杉/敾/禅让/受禅/禅变/禅代/禅诰
shang#衣裳
she#拾级/折本/射/蛇
shen#沙参/野参/参王/人参/红参/丹参/山参/海参/鹿参/什么/身/沈/桑椹/食椹/烂椹/木椹
sheng#野乘/千乘/史乘/省/晟/盛/陹/渑水
shi#钥匙/什/识/似的/食/石/氏/拾/适/瑡
shiwa#瓧
shuai#表率/率性/率直/率真/粗率/率领/轻率/直率/草率/大率/坦率/衰
shuang#泷水/鏯
shu#属/数/术/熟
shui#游说
shuo#数见/说
si#伺/似/思
sou#蓃/摗
su#宿/鯂
sui#尿泡
ta#拓片/拓印/拓本/拓墨/拓写/拓手/拓工/碑拓/疲沓/拖沓/杂沓/沓/塔/鸿塔
tang#汤/镗
tao#陶
tan#反弹/弹性/弹簧/弹力/弹奏/弹跳/弹指/弹劾/弹唱/弹射/弹性体/吹弹/评弹/乱弹琴/弹压/弹指/弹簧/弹冠/弹雀/弹雀/弹丝/弹丸/澹台
te#脦
teng#虅
ti#提/体
tiao#调/苕
ting#町/听
tong#通
tu#迌
tuan#湪
tui#褪
tuo#拓/袥
tun#囤/屯
wei#尾/蔚/圩堤/圩垸/圩田/圩子/赶圩/歌圩
weng#攚
wu#无/可恶/交恶/好恶/厌恶/憎恶/嫌恶/痛恶/深恶/兀
wan#藤蔓/枝蔓/根蔓/蔓草/瓜蔓/蔓儿/莞/万/百万/皖
wang#亡
wai#崴
xia#虾/吓/夏/厦门/厦大/唬杀
xi#栖/系/蹊/洗/溪/戏/焁/铣/褶衣/褶裤
xiao#校/切削/削面/刀削/刮削
xian#纤细/光纤/纤巧/纤柔/纤小/纤维/纤瘦/纤纤/化纤/纤秀/棉纤/纤尘/铣铁/金铣
xiang#投降/巷
xie#解数/出血/采血/换血/血糊/尿血/淤血/放血/血晕/血淋/便血/吐血/咯血/叶韵/蝎/蝎子/邪/猲猲
xin#嬜/邤
xiu#铜臭/乳臭/成宿/星宿/璓
xin#馨/信/鸿信
xing#深省/省视/内省/不省人事/省悟/省察/行/荥
xiong#匂
xu#牧畜/畜产/畜牧/畜养/并畜/畜锐/吁/圩/浒
xuan#箮
xue#削/血/樰
xun#荨/寻
ya#琊
yao#钥/耀/曜/佋侥/侥觎/侥僺/侥利/侥傒/侥觊/侥会/侥滥/侥望/侥求/侥竞/侥薄/侥躐/侥取/侥奇/侥忝/侥速/侥冀/侥冒/疟子
yan#咽/殷红/朱殷/腌/烟/曕
ye#液/抽咽/哽咽/咽炎/呜咽/幽咽/悲咽/叶/葉/璍/潱/拽步/拽扶/拽扎
yi#自艾/遗/屹/嬄/噫
yin#殷/栶
ying#荥经/緓/灜
yo#杭育
yong#涌/硧
you#牗
yu#余/呼吁/吁请/吁求/育/熨帖/熨烫/於
yuan#员/茒/圜丘
yun#熨
yue#约/乐音/器乐/乐律/乐章/音乐/乐理/民乐/乐队/声乐/奏乐/弦乐/乐坛/管乐/配乐/乐曲/乐谱/锁钥/密钥/乐团/乐器/嬳/咽哕/唾哕/发哕/干哕/哕吐/哕饭/哕呕/哕息/哕厥/哕噫/哕逆/哕咽/哕骂/哕心/哕喈/口哕/呕哕
za#绑扎/结扎/包扎/捆扎/咱家
zan#攒/咱
zang#宝藏/藏历/藏文/藏语/藏青/藏族/藏医/藏药/藏蓝/西藏
zai#牛仔/龟仔/龙仔/鼻仔/羊仔/仔仔/麻仔/麵包仔/麦旺仔/鸿仔/煲仔/福仔/畠
zao#栆
ze#择
zeng#曾国藩/曾孙/曾祖父/曾祖/曾祖母/曾孙女/曾巩/囎/缯
zong#综/繌
zha#扎/柞狭/柞薪/柞子/柞鄂/柞叶/柞撒/槱柞/一柞/五柞宫/五柞/雠柞/芟柞/蜡祭/喳
zhai#宅/夈/择席/择菜
zhan#粘
zhang#列车长/行长/村长/镇长/乡长/区长/县长/市长/省长/会长/班长/排长/连长/营长/团长/旅长/师长/军长/委员长/局长/厅长/所长/部长/组长/生长/长大/长高/长个/
zhao#朝朝/明朝/朝晖/朝夕/朝思/今朝/朝气/朝三/朝秦/朝霞/鹰爪/龙爪/魔爪/爪牙/着急/着迷/着火/怎么着/正着/着凉/一着/犯不着/着数/这么着/犯得着/着慌/着忙/数得着/龙爪槐/嘲哳/嘲惹
zhe#折/着/褶
zhen#殝/椹
zhi#标识/吱/殖/枝/方祇/后祇/皇祇/黄祇/皇地祇/金祇/祇树/月氏
zhong#重/种
zhou#粥
zhu#属意/著/駯
zhua#爪子
zhuai#拽
zhuan#芈月传/外传/传记/自传/正传/小传/评传/传略/别传
zhui#椎/隹
zhuo#执著/着装/着落/着意/着力/附着/着笔/胶着/着实/衣着/着眼/着想/着重/穿着/执着/着墨/着实/沉着/着陆/着想/着色/焯见/焯烁/辉焯
zhuang#幢房/一幢/幢楼/庒
zi#仔/兹
zu#足
zuo#柞/穝

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