1
0
mirror of https://gitee.com/incloudcode/yexuejc-springboot.git synced 2025-11-20 12:09:45 +08:00

27 Commits

Author SHA1 Message Date
9ebaf69ecc 添加计划 2023-09-19 13:57:20 +08:00
9ce56206f5 2.x 合并到master(方便后续分支) 2023-09-19 13:44:07 +08:00
15498dafcc 2.1.3[原功能的最后一个版本] 2023-09-19 11:26:17 +08:00
4dc52444ce Merge pull request #6 from yexuejc/dependabot/maven/org.postgresql-postgresql-42.4.3
Bump postgresql from 42.4.1 to 42.4.3
2023-04-15 10:16:54 +08:00
dependabot[bot]
76e4b858e9 Bump postgresql from 42.4.1 to 42.4.3
Bumps [postgresql](https://github.com/pgjdbc/pgjdbc) from 42.4.1 to 42.4.3.
- [Release notes](https://github.com/pgjdbc/pgjdbc/releases)
- [Changelog](https://github.com/pgjdbc/pgjdbc/blob/master/CHANGELOG.md)
- [Commits](https://github.com/pgjdbc/pgjdbc/compare/REL42.4.1...REL42.4.3)

---
updated-dependencies:
- dependency-name: org.postgresql:postgresql
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-11-23 22:25:40 +00:00
4c9520de70 Merge pull request #1 from yexuejc/dependabot/maven/org.mybatis-mybatis-3.5.6
Bump mybatis from 3.4.6 to 3.5.6
2022-09-08 10:06:44 +09:00
55c64e59d4 Merge pull request #4 from yexuejc/dependabot/maven/com.alibaba-fastjson-1.2.83
Bump fastjson from 1.2.49 to 1.2.83
2022-09-08 10:06:31 +09:00
53437a57e2 Merge pull request #5 from yexuejc/dependabot/maven/org.postgresql-postgresql-42.4.1
Bump postgresql from 42.2.4 to 42.4.1
2022-09-08 10:06:18 +09:00
dependabot[bot]
0dc6b8aa6d Bump postgresql from 42.2.4 to 42.4.1
Bumps [postgresql](https://github.com/pgjdbc/pgjdbc) from 42.2.4 to 42.4.1.
- [Release notes](https://github.com/pgjdbc/pgjdbc/releases)
- [Changelog](https://github.com/pgjdbc/pgjdbc/blob/master/CHANGELOG.md)
- [Commits](https://github.com/pgjdbc/pgjdbc/compare/REL42.2.4...REL42.4.1)

---
updated-dependencies:
- dependency-name: org.postgresql:postgresql
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-09-08 00:29:23 +00:00
dependabot[bot]
c23db40776 Bump fastjson from 1.2.49 to 1.2.83
Bumps [fastjson](https://github.com/alibaba/fastjson) from 1.2.49 to 1.2.83.
- [Release notes](https://github.com/alibaba/fastjson/releases)
- [Commits](https://github.com/alibaba/fastjson/compare/1.2.49...1.2.83)

---
updated-dependencies:
- dependency-name: com.alibaba:fastjson
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-17 01:57:59 +00:00
dependabot[bot]
ab074953db Bump mybatis from 3.4.6 to 3.5.6
Bumps [mybatis](https://github.com/mybatis/mybatis-3) from 3.4.6 to 3.5.6.
- [Release notes](https://github.com/mybatis/mybatis-3/releases)
- [Commits](https://github.com/mybatis/mybatis-3/compare/mybatis-3.4.6...mybatis-3.5.6)

Signed-off-by: dependabot[bot] <support@github.com>
2021-04-22 17:47:58 +00:00
maxiaofeng
b8cba48792 版本2.1.2 更新base1.4.0 更新仓库地址 https://nexus.yexuejc.club/ -> https://nexus.yexuejc.top/ 2020-05-18 12:23:07 +08:00
f3b23730d6 更新说明文档 版本升级 2019-11-01 13:35:25 +08:00
85362e6537 2.1.1 redis 配置修改,增加开关,更兼容 2019-11-01 13:33:10 +08:00
73b767786f 2.1.0 更新redis配置 2019-11-01 13:04:41 +08:00
4cdc2b631c 更新master 2019-07-27 11:46:56 +08:00
8e86b352ac 更新配置 2019-07-27 11:29:49 +08:00
8e39507e18 更新测试代码 2019-07-27 11:26:48 +08:00
32f5528047 增加示例代码 2019-07-27 11:17:04 +08:00
b93672f52f 功能插件装配开关 2019-07-27 09:27:32 +08:00
83a20b010b 2.0.6 升级依赖 2019-04-02 22:07:27 +08:00
0e1fd35a85 2.0.6 升级依赖 2019-04-02 21:09:18 +08:00
09f2138327 Merge remote-tracking branch 'origin/master'
# Conflicts:
#	README.md
2018-12-03 10:56:11 +08:00
01b94cbdd2 Merge branch '1.x'
# Conflicts:
#	README.md
2018-12-03 10:55:47 +08:00
2b82d8205d 更新 MENU.md 2018-12-01 12:34:46 +08:00
0cd3709838 Merge branch '1.x'
# Conflicts:
#	README.md
2018-12-01 12:32:41 +08:00
d4ec02db64 更新文档 2018-11-20 20:48:42 +08:00
61 changed files with 3332 additions and 165 deletions

197
1.x-update.md Normal file
View File

@@ -0,0 +1,197 @@
yexuejc-springboot 更新内容
-------------------
#### version 1.2.2
**time2019-11-1 13:11:44** <br/>
**branch** master <br/>
**关联工程:** <br/>
```
springboot-base:1.3.9
spring-boot-starter-parent:1.5.16.RELEASE
```
**update** <br/>
1. redis 配置修改,增加开关,更兼容
#### version 1.2.1
**time2019-7-27 09:39:24** <br/>
**branch** master <br/>
**关联工程:** <br/>
```
springboot-base:1.3.9
spring-boot-starter-parent:1.5.16.RELEASE
```
**update** <br/>
1. 所有自动装配增加开关,默认不装配。装配方式请参考[本项目自动装配开关](doc/plugin/AutoConfigure.md)
#
#### version 1.2.0
**time2018-12-1 12:19:06** <br/>
**branch** master <br/>
**关联工程:** <br/>
```
springboot-base:1.2.4
spring-boot-starter-parent:1.5.16.RELEASE
```
**update** <br/>
1. security多方登录第一个稳定版<br/>
支持账号登录、短信登录、第三方授权openid登录<br/>
功能链接[security重构-多方登录](doc/SECURITY.md)
---
#### version 1.1.0
**time2018-9-23 12:49:36** <br/>
**branch** master <br/>
**关联工程:** <br/>
```
springboot-base:1.1.9
spring-boot-starter-parent:1.5.15.RELEASE
```
**update** <br/>
1. 升级依赖
2. 增加SSL证书忽略默认关闭
3. 本版本更新工具依赖[https://github.com/yexuejc/yexuejc-base.git](https://github.com/yexuejc/yexuejc-base.git)不向下兼容
---
#### version 1.0.15
**time2018-9-3 19:29:39** <br/>
**branch** master <br/>
**关联工程:** <br/>
```
springboot-base:1.1.8
spring-boot-starter-parent:1.5.15.RELEASE
```
**update** <br/>
1. 升级依赖
---
#### version 1.0.14
**time2018-8-25 14:31:05** <br/>
**branch** master <br/>
**关联工程:** <br/>
```
springboot-base:1.1.7
spring-boot-starter-parent:1.5.15.RELEASE
```
**update** <br/>
1. 升级依赖
2. 优化拦截规则:增加通配符 /**
---
#### version 1.0.13
**time2018-8-17 11:41:18** <br/>
**branch** master <br/>
**关联工程:** <br/>
```
springboot-base:1.1.7
```
**update** <br/>
1. 升级base
---
#### version 1.0.12
**time2018-6-19 22:18:03** <br/>
**branch** master <br/>
**关联工程:** <br/>
```
springboot-base:1.1.6
```
**update** <br/>
1. maven仓库更新
---
#
#### version 1.0.11
**time2018-6-19 22:18:03** <br/>
**branch** master <br/>
**update** <br/>
1. 更新springboot-base:1.1.5依赖
---
#### version 1.0.10
**time2018年6月14日22:31:18** <br/>
**branch** master <br/>
**update** <br/>
1. 更新springboot-base:1.1.4依赖
2. 统一编码UTF-8
---
#### version 1.0.9
**time2018年6月2日12:17:18** <br/>
**branch** master <br/>
**update** <br/>
1. 更新base依赖
---
#### version 1.0.8
**time** 2018-5-4 09:54:18<br/>
**branch** master <br/>
**update** <br/>
1. 修复依赖
2. 使用加密:配置密钥方式/配置密钥方式 二选一
```
#加密开关
yexuejc.http.encrypt.encrypt=true
yexuejc.http.encrypt.decrypt=true
#配置密钥方式
yexuejc.http.encrypt.private-key=私钥
#配置证书方式
yexuejc.http.encrypt.private-key-path=/lgfishing.keystore 路径
yexuejc.http.encrypt.private-alias=别名
yexuejc.http.encrypt.private-pwd=密码
```
---
##### version 1.0.7
**time** 2018-5-4 09:54:18<br/>
**branch** master <br/>
**update** <br/>
>1. 新增加密证书配置
>2. RSA迁移到[yexuejc-base:1.1.1](https://github.com/yexuejc/yexuejc-base)工程
---
##### version 1.0.6 ~~1.0.5~~
**【change:2018-5-15 09:24:37】** 1.0.5 jitpack打包失败升级版本1.0.6<br/>
**time** 2018-5-4 09:54:18<br/>
**branch** master <br/>
**update** <br/>
> [使用加密解密](doc/PARAMS_RSA_DECRYPT_ENCRYPT.md)
>
>1.增加json入参解密、出参加密
---
##### version 1.0.4
**time** 2018-5-4 09:54:18<br/>
**branch** master <br/>
**update** <br/>
>1.更新springboot至1.5.12.RELEASE
---
#### version 1.0.3
**time** 2018-4-9 15:24:13<br/>
**branch** master <br/>
**update** <br/>
>1.变更包名
---
#### version 1.0.2
**time** 2018-4-1 17:00:15<br/>
**env** prod <br/>
**update** <br/>
>1.修复工具包ApiVO
---
#### version 0.0.2
**time** 2018-1-31 13:48:34<br/>
**env** ivt <br/>
**update** <br/>
>1.集成日志【security】
---
##### version 0.0.1
**time** 2018-1-31 12:16:10<br/>
**env** ivt <br/>
**update** <br/>
>1.第一次上传,集成通用环境
---

View File

@@ -1,5 +1,71 @@
yexuejc-springboot 更新内容
-------------------
#### version 2.1.3
**time2023-9-19 11:15:33** <br/>
**branch** 2.x <br/>
**关联工程:** <br/>
```
springboot-base:1.5.0-jre8
spring-boot-starter-parent:2.7.15
```
**update** <br/>
1. 全面更新依赖时隔3年多该项目又活了
2. 保证原功能正常的最后一个版本
3. 该版本基于JDK1.8
---
#### version 2.1.2
**time2020-5-18 12:18:14** <br/>
**branch** master <br/>
**关联工程:** <br/>
```
springboot-base:1.4.0
spring-boot-starter-parent:1.5.16.RELEASE
```
**update** <br/>
1. 更新依赖
2. 更新仓库地址 https://nexus.yexuejc.club/ 为 https://nexus.yexuejc.top/
---
#### version 2.1.1
**time2019-11-1 13:32:07** <br/>
**branch** master <br/>
**关联工程:** <br/>
```
springboot-base:1.3.9
spring-boot-starter-parent:2.0.5.RELEASE
```
**update** <br/>
1. redis 配置修改,增加开关,更兼容
#### version 2.1.0
**time2019-7-24 18:30:49** <br/>
**branch** master <br/>
**关联工程:** <br/>
```
springboot-base:1.3.9
spring-boot-starter-parent:2.0.5.RELEASE
```
**update** <br/>
1. 所有自动装配增加开关,默认不装配。装配方式请参考[本项目自动装配开关](doc/plugin/AutoConfigure.md)
#
#### version 2.0.6
**time2019年4月2日21:08:453** <br/>
**branch** master <br/>
**关联工程:** <br/>
```
springboot-base:1.3.9
spring-boot-starter-parent:2.0.5.RELEASE
```
**update** <br/>
1. 升级依赖
2. 出入参加密 ParamsRequestBodyAdvice/ParamsResponseBodyAdvice 增加开关(默认关)
#
#### version 2.0.5
**time2018-12-1 12:27:10** <br/>

View File

@@ -1,10 +1,12 @@
# yexuejc-springboot
### 说明
>本分支基于 springboot 2.x 开发版本号也将保持2.x
>1.x分支继续基于 springboot 1.x开发
> 基于springboot版本分别维护1.x(对应springboot1.5.16.RELEASE) 2.x(对应springboot2.0.5.RELEASE) 分支 <br>
> master不再提供源代码源代码请到具体分支中查看
#### 项目介绍
基于springboot maven 封装可继承基础工程
内含parent和base工程可分开使用<br/>
@@ -12,10 +14,13 @@ parent版本封装<br/>
base:功能封装
#### 最新版本
>yexuejc.springboot.version=2.0.5 <br>
>yexuejc.base.version=1.2.4
* 1.x yexuejc.springboot.version=1.2.2 <br>
* 2.x yexuejc.springboot.version=2.1.3 <br>
* yexuejc.base.version=1.5.0-jre8
pom.xml
```
<!--parent 引用-->
<parent>
@@ -34,22 +39,22 @@ pom.xml
<!--推荐使用-->
<!--https://gitee.com/incloudcode/yexuejc-base.git-->
<dependency>
<groupId>com.yexuejc.base</groupId>
<groupId>top.yexuejc</groupId>
<artifactId>yexuejc-base</artifactId>
<version>${yexuejc.base.version}</version>
</dependency>
</dependencies>
<repositories>
<repository>
<id>yexuejc-nexus-public</id>
<name>yexuejc-nexus-public</name>
<url>https://nexus.yexuejc.club/repository/maven-public/</url>
<id>yexuejc-maven</id>
<name>yexuejc maven</name>
<url>https://nexus.yexuejc.top/repository/maven-public/</url>
</repository>
</repositories>
```
#### 目录
<table>
<tr>
<td>\src\main\java</td>
@@ -101,9 +106,24 @@ pom.xml
</tr>
</table>
#### 版本更新
[更新记录](UPDATE.md)
持续集成中...
<br/>
集成到自己项目前请先阅读文档,或者先运行示例工程
更新记录: [1.x](1.x-update.md)、[2.x](2.x-update.md)
<br/>
[相关功能使用指南](doc/MENU.md)
### 计划
- [ ] 升级jdk版本到openjdk-11
- [ ] 优化原有框架
- [ ] 请求日志优化(适配多方日志框架)
- [ ] 请求拦截器优化
- [ ] 增加本地缓存支持ehcache3
- [ ] 多种数据库支持H2,Mysql,PostgreSQL
- [ ] 多种数据库框架支持jpa,mybatis
- [ ] 全局异常优化
- [ ] 多语言支持

View File

@@ -1,7 +1,7 @@
功能目录
------------------------
### 第三方集成
### 第三方集成 -> [第三方集成具体使用](plugin/AutoConfigure.md)
#
* [redis 集成](REDIS.md)
* [Aliyun MNS 消息队列](MNS.md)
@@ -13,3 +13,11 @@
单独使用例子工程:[https://github.com/yexuejc/springboot-security-login-simple](https://github.com/yexuejc/springboot-security-login-simple)
* [1.0.6新增 针对API请求安全解决方案](PARAMS_RSA_DECRYPT_ENCRYPT.md)<br/>
* [1.0.6新增 加密功能](PARAMS_RSA_DECRYPT_ENCRYPT.md)
### 运行错误
1. jdk版本问题请切换jdk为1.8版或者jvm增加启动参数`--add-opens java.base/java.util=ALL-UNNAMED`
```
Cannot load configuration class: com.example.demo.DemoApplication
Unable to make protected final java.lang.Class java.lang.ClassLoader.defineClass(java.lang.String,byte[],int,int,java.security.ProtectionDomain) throws java.lang.ClassFormatError accessible: module java.base does not "opens java.lang" to unnamed module @5af3afd9
```

View File

@@ -1,22 +1,22 @@
#生成私钥
keytool -genkey -alias lgfishing -keyalg RSA -keystore lgfishing2.keystore -keysize 1024 -validity 36500
keytool -genkey -alias test -keyalg RSA -keystore test.keystore -keysize 1024 -validity 36500
```
输入密钥库口令:
再次输入新口令:
您的名字与姓氏是什么?
[Unknown]: heikengdiaoyu.com
[Unknown]: 1107047387@qq.com
您的组织单位名称是什么?
[Unknown]: 深圳金大米网络科技有限公司-老G钓鱼
[Unknown]: yexuejc
您的组织名称是什么?
[Unknown]: 成都极致思维网络科技有限公司-老G钓鱼
[Unknown]: 成都极致思维网络科技有限公司
您所在的城市或区域名称是什么?
[Unknown]: 成都
您所在的省/市/自治区名称是什么?
[Unknown]: 四川
该单位的双字母国家/地区代码是什么?
[Unknown]: CN
CN=heikengdiaoyu.com, OU=深圳金大米网络科技有限公司-老G钓鱼, O=成都极致思维网络科技有限公司-老G钓鱼, L=成都, ST=四川, C=CN是否正确?
CN=1107047387@qq.com, OU=yexuejc, O=成都极致思维网络科技有限公司, L=成都, ST=四川, C=CN是否正确?
[否]: 是
```
#生成公钥
keytool -export -alias lgfishing -keystore lgfishing2.keystore -storepass lgfishing2018 -rfc -file lgfishing2.cer
keytool -export -alias test -keystore test.keystore -storepass test2018 -rfc -file test2018.cer

View File

@@ -0,0 +1,95 @@
本项目自动装配开关
---------------------
## 说明
本项目从2.1.0开始所有自动装配的功能增加开关控制,默认插件功能关闭.
开启需要在使用项目`application.properties`中增加`yexuejc.autoconfigure.mns.enable=true`类似的配置每一个插件功能key不一样
### 插件功能
注:使用阿里系的功能请引入阿里基础包
```
<!-- 阿里云基础SDK -->
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-core</artifactId>
<optional>true</optional>
</dependency>
```
#### 阿里云MNS功能
> 类:[MnsAutoConfiguration](../../yexuejc-springboot-base/src/main/java/com/yexuejc/springboot/base/autoconfigure/MnsAutoConfiguration.java)
> <br/> 功能开关:`yexuejc.autoconfigure.mns.enable=true`
> <br/> 依赖:`MNSClient.class`
> <br/> pom 引入
> ```
> <!-- 阿里云消息服务MNS相关SDK -->
> <dependency>
> <groupId>com.aliyun.mns</groupId>
> <artifactId>aliyun-sdk-mns</artifactId>
> <classifier>jar-with-dependencies</classifier>
> <optional>true</optional>
> </dependency>
> ```
>application.properties 配置
>```
> yexuejc.alibaba.mns.access-key-id=自己到阿里云申请access-key
> yexuejc.alibaba.mns.access-key-secret=自己到阿里云申请access-key-secret
> yexuejc.alibaba.mns.endpoint=自己阿里云的endpoint
> yexuejc.alibaba.mns.queue-name-prefix=mns前缀
>```
#### redis 多database 配置
> 类:[MutiRedisAutoConfiguration](../../yexuejc-springboot-base/src/main/java/com/yexuejc/springboot/base/autoconfigure/MutiRedisAutoConfiguration.java)
> <br/> 功能开关:`yexuejc.autoconfigure.redis.enable=true`
> <br/> 依赖:`JedisConnection.class`, `RedisOperations.class`, `Jedis.class`
> <br/> pom 引入
> ```
> <!-- 使用Redis -->
> <dependency>
> <groupId>org.springframework.data</groupId>
> <artifactId>spring-data-redis</artifactId>
> <optional>true</optional>
> </dependency>
> <dependency>
> <groupId>redis.clients</groupId>
> <artifactId>jedis</artifactId>
> <optional>true</optional>
> </dependency>
> ```
>application.properties 配置
><br/> 默认db0k开启 1-15需要使用哪个`yexuejc.redis.dbx=true`
>```
> yexuejc.redis.db1=true
> spring.redis.jedis.pool.max-active=100
> spring.redis.jedis.pool.max-idle=10
> spring.redis.jedis.pool.min-idle=3
> spring.redis.host=地址
> spring.redis.password=密码
> spring.redis.port=端口
>```
#### 阿里 OSS 功能
> 类:[OssAutoConfiguration](../../yexuejc-springboot-base/src/main/java/com/yexuejc/springboot/base/autoconfigure/OssAutoConfiguration.java)
> <br/> 功能开关:`yexuejc.autoconfigure.oss.enable=true`
> <br/> 依赖:`OSSClient`
> <br/> pom 引入
> ```
> <!-- 阿里云OSS相关SDK -->
> <dependency>
> <groupId>com.aliyun.oss</groupId>
> <artifactId>aliyun-sdk-oss</artifactId>
> <optional>true</optional>
> </dependency>
> ```
>application.properties 配置
>```
> yexuejc.alibaba.oss.endpoint=自己去阿里申请的endpoint
> yexuejc.alibaba.oss.access-key-secret=自己到阿里云申请access-key-secret
> yexuejc.alibaba.oss.access-key-id=自己到阿里云申请access-key
> yexuejc.alibaba.oss.bucket=自己去阿里申请的bucket
>```
#### WebMvc 相关配置
> 类:[WebAutoConfiguration](../../yexuejc-springboot-base/src/main/java/com/yexuejc/springboot/base/autoconfigure/WebAutoConfiguration.java)
> <br/> 功能开关:`yexuejc.autoconfigure.webmvc.enable=true`
> 本类开启后的具体使用说明参见[WebMvc相关配置](WebAutoConfiguration.md)

View File

@@ -0,0 +1,2 @@
WebMvc相关配置 [WebAutoConfiguration](../../yexuejc-springboot-base/src/main/java/com/yexuejc/springboot/base/autoconfigure/WebAutoConfiguration.java)
------------------------------------

118
pom.xml
View File

@@ -5,7 +5,7 @@
<groupId>com.yexuejc.springboot</groupId>
<artifactId>yexuejc-springboot-parent</artifactId>
<version>2.0.5</version>
<version>2.1.3</version>
<packaging>pom</packaging>
<name>${project.artifactId}</name>
@@ -15,64 +15,68 @@
<!-- spring boot父级,包含了统一版本管理,统一插件管理等 -->
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.5.RELEASE</version>
<!-- <relativePath/> lookup parent from repository -->
<version>2.7.15</version>
<!--<relativePath/>-->
<!--lookup parent from repository-->
</parent>
<modules>
<module>yexuejc-springboot-base</module>
</modules>
<properties>
<yexuejc.base.version>1.2.4</yexuejc.base.version>
<repos.yexuejc.url>https://nexus.yexuejc.club/repository/</repos.yexuejc.url>
<repos.aliyun.url>http://maven.aliyun.com/nexus/content/groups/public</repos.aliyun.url>
<repos.jitpack.url>https://jitpack.io</repos.jitpack.url>
<maven.compiler.verbose>true</maven.compiler.verbose>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<validation-api.version>2.0.1.Final</validation-api.version>
<springfox-swagger2.version>2.9.2</springfox-swagger2.version>
<mybatis-spring-boot-starter.version>1.3.2</mybatis-spring-boot-starter.version>
<mybatis.version>3.4.6</mybatis.version>
<maven.compiler.target>${java.version}</maven.compiler.target>
<maven.compiler.source>${java.version}</maven.compiler.source>
<maven.compiler.verbose>true</maven.compiler.verbose>
<jjwt.version>0.9.1</jjwt.version>
<yexuejc.base.version>1.5.0-jre8</yexuejc.base.version>
<yexuejc-springboot.version>${project.version}</yexuejc-springboot.version>
<validation-api.version>2.0.1.Final</validation-api.version>
<springfox-swagger2.version>2.10.5</springfox-swagger2.version>
<mybatis-spring-boot-starter.version>2.3.1</mybatis-spring-boot-starter.version>
<mybatis.version>3.5.13</mybatis.version>
<jjwt.version>0.11.5</jjwt.version>
<fastjson.version>1.2.49</fastjson.version>
<commons-codec.version>1.11</commons-codec.version>
<commons-codec.version>1.15</commons-codec.version>
<!-- 阿里云相关 -->
<aliyun-java-sdk-core.version>4.1.1</aliyun-java-sdk-core.version>
<aliyun-java-sdk-sts.version>3.0.0</aliyun-java-sdk-sts.version>
<aliyun-sdk-oss.version>3.1.0</aliyun-sdk-oss.version>
<aliyun-java-sdk-dysmsapi.version>1.1.0</aliyun-java-sdk-dysmsapi.version>
<aliyun-sdk-mns.version>1.1.8</aliyun-sdk-mns.version>
<aliyun-java-sdk-core.version>4.6.4</aliyun-java-sdk-core.version>
<aliyun-java-sdk-sts.version>3.1.1</aliyun-java-sdk-sts.version>
<aliyun-sdk-oss.version>3.17.1</aliyun-sdk-oss.version>
<aliyun-java-sdk-dysmsapi.version>2.2.1</aliyun-java-sdk-dysmsapi.version>
<aliyun-sdk-mns.version>1.1.9.2</aliyun-sdk-mns.version>
<!-- 支付宝相关 -->
<alipay-sdk-java.version>3.3.49.ALL</alipay-sdk-java.version>
<alipay-sdk-java.version>4.38.76.ALL</alipay-sdk-java.version>
<!-- 微信相关 -->
<WXPay-SDK-Java.version>0.0.4</WXPay-SDK-Java.version>
<postgresql.version>42.2.4</postgresql.version>
<postgresql.version>42.6.0</postgresql.version>
<!--thymeleaf 相关-->
<thymeleaf.version>3.1.2.RELEASE</thymeleaf.version>
<thymeleaf-layout-dialect.version>3.3.0</thymeleaf-layout-dialect.version>
<thymeleaf-extras-springsecurity4.version>3.0.5.RELEASE</thymeleaf-extras-springsecurity4.version>
<thymeleaf.version>3.0.9.RELEASE</thymeleaf.version>
<thymeleaf-layout-dialect.version>2.3.0</thymeleaf-layout-dialect.version>
<thymeleaf-extras-springsecurity4.version>3.0.2.RELEASE</thymeleaf-extras-springsecurity4.version>
<reflectasm.version>1.09</reflectasm.version>
<!--dubbo-->
<dubbo-spring-boot-starter.version>0.2.0</dubbo-spring-boot-starter.version>
<mybatis-plus.version>3.0.3</mybatis-plus.version>
<reflectasm.version>1.11.9</reflectasm.version>
<mybatis-plus.version>3.5.3.2</mybatis-plus.version>
</properties>
<!-- 声明包版本 继承项目自引入 -->
<dependencyManagement>
<dependencies>
<!--基础包-->
<!--<dependency>-->
<!--<groupId>com.github.yexuejc</groupId>-->
<!--<artifactId>yexuejc-base</artifactId>-->
<!--<version>${yexuejc.base.version}</version>-->
<!--</dependency>-->
<dependency>
<groupId>com.yexuejc.base</groupId>
<groupId>top.yexuejc</groupId>
<artifactId>yexuejc-base</artifactId>
<version>${yexuejc.base.version}</version>
</dependency>
<dependency>
<groupId>com.yexuejc.springboot</groupId>
<artifactId>yexuejc-springboot-base</artifactId>
<version>${yexuejc-springboot.version}</version>
</dependency>
<!-- 编码包 说明http://blog.csdn.net/jianggujin/article/details/51149133 -->
<dependency>
<groupId>commons-codec</groupId>
@@ -82,15 +86,9 @@
<!-- JJWT -->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<artifactId>jjwt-api</artifactId>
<version>${jjwt.version}</version>
</dependency>
<!-- fastjson -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>${fastjson.version}</version>
</dependency>
<!-- MVC数据校验框架 -->
<dependency>
@@ -187,11 +185,6 @@
<artifactId>reflectasm</artifactId>
<version>${reflectasm.version}</version>
</dependency>
<dependency>
<groupId>com.alibaba.boot</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
<version>${dubbo-spring-boot-starter.version}</version>
</dependency>
<!-- springboot mybatis-plus-->
<dependency>
<groupId>com.baomidou</groupId>
@@ -273,38 +266,17 @@
</plugins>
</pluginManagement>
</build>
<repositories>
<repository>
<id>yexuejc-nexus-public</id>
<name>yexuejc-nexus-public</name>
<url>${repos.yexuejc.url}maven-public/</url>
</repository>
<repository>
<id>aliyun-nexus-public</id>
<name>aliyun-nexus-public</name>
<url>${repos.aliyun.url}</url>
</repository>
<repository>
<id>jitpack.io</id>
<url>${repos.jitpack.url}</url>
</repository>
</repositories>
<!-- 中间件jar包发布目标 -->
<distributionManagement>
<repository>
<id>releases</id>
<name>nexus-release</name>
<url>${repos.yexuejc.url}maven-releases/</url>
<url>https://nexus.yexuejc.top/repository/maven-releases/</url>
</repository>
<snapshotRepository>
<id>snapshots</id>
<name>nexus-snapshots</name>
<url>${repos.yexuejc.url}maven-snapshots/</url>
<url>https://nexus.yexuejc.top/repository/maven-snapshots/</url>
</snapshotRepository>
</distributionManagement>
<modules>
<module>yexuejc-springboot-base</module>
</modules>
</project>

View File

@@ -9,27 +9,19 @@
<parent>
<groupId>com.yexuejc.springboot</groupId>
<artifactId>yexuejc-springboot-parent</artifactId>
<version>2.0.5</version>
<version>2.1.3</version>
<!-- 本地打包:使用相对关联路径 -->
<!--<relativePath>../../yexuejc</relativePath>-->
<!--<relativePath>../</relativePath>-->
</parent>
<name>${project.artifactId}</name>
<!--<properties>-->
<!--<main.basedir>${basedir}/..</main.basedir>-->
<!--</properties>-->
<dependencies>
<!--基础包-->
<dependency>
<groupId>com.yexuejc.base</groupId>
<groupId>top.yexuejc</groupId>
<artifactId>yexuejc-base</artifactId>
</dependency>
<!--<dependency>-->
<!--<groupId>com.github.yexuejc</groupId>-->
<!--<artifactId>yexuejc-base</artifactId>-->
<!--</dependency>-->
<!-- 使用springMVC -->
<dependency>
@@ -65,7 +57,7 @@
<!-- JJWT -->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<artifactId>jjwt-api</artifactId>
<optional>true</optional>
</dependency>
<!-- 使用Redis -->

View File

@@ -1,13 +1,13 @@
package com.yexuejc.springboot.base.autoconfigure;
import com.aliyun.mns.client.MNSClient;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.aliyun.mns.client.MNSClient;
/**
* 阿里云消息服务MNS相关配置
*
@@ -20,6 +20,7 @@ import com.aliyun.mns.client.MNSClient;
@Configuration
@ConditionalOnClass(MNSClient.class)
@EnableConfigurationProperties(MnsProperties.class)
@ConditionalOnProperty(name = "yexuejc.autoconfigure.mns.enable", matchIfMissing = false)
public class MnsAutoConfiguration {
private final MnsProperties properties;

View File

@@ -37,6 +37,7 @@ import java.net.UnknownHostException;
@ConditionalOnClass({JedisConnection.class, RedisOperations.class, Jedis.class})
@EnableConfigurationProperties(RedisProperties.class)
@Order(1)
@ConditionalOnProperty(name = "yexuejc.autoconfigure.redis.enable", matchIfMissing = false)
public class MutiRedisAutoConfiguration {
public static final String BEAN_REDIS_FACTORY0 = "redisConnectionFactory";
public static final String BEAN_REDIS_TEMPLATE0 = "redisTemplate";
@@ -72,6 +73,7 @@ public class MutiRedisAutoConfiguration {
@Configuration
@ConditionalOnClass(GenericObjectPool.class)
@ConditionalOnProperty(name = "yexuejc.autoconfigure.redis.enable", matchIfMissing = false)
protected static class RedisConnectionConfiguration {
private final RedisProperties properties;
@@ -162,6 +164,7 @@ public class MutiRedisAutoConfiguration {
* Standard Redis configuration.
*/
@Configuration
@ConditionalOnProperty(name = "yexuejc.autoconfigure.redis.enable", matchIfMissing = false)
protected static class RedisConfiguration {
@Primary

View File

@@ -4,6 +4,7 @@ import com.aliyun.oss.ClientConfiguration;
import com.aliyun.oss.OSSClient;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@@ -20,6 +21,7 @@ import org.springframework.context.annotation.Configuration;
@Configuration
@ConditionalOnClass({OSSClient.class})
@EnableConfigurationProperties(OssProperties.class)
@ConditionalOnProperty(name = "yexuejc.autoconfigure.oss.enable", matchIfMissing = false)
public class OssAutoConfiguration {
private final OssProperties properties;

View File

@@ -17,6 +17,7 @@ import com.yexuejc.springboot.base.filter.ValidationFilterProperties;
import com.yexuejc.springboot.base.interceptor.LogInterceptor;
import com.yexuejc.springboot.base.util.LogUtil;
import com.yexuejc.springboot.base.util.SSLUtil;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
@@ -52,6 +53,7 @@ import java.util.List;
@Configuration
@ConditionalOnWebApplication
@EnableConfigurationProperties(ValidationFilterProperties.class)
@ConditionalOnProperty(name = "yexuejc.autoconfigure.webmvc.enable", matchIfMissing = false)
public class WebAutoConfiguration extends WebMvcConfigurerAdapter {
@@ -61,6 +63,7 @@ public class WebAutoConfiguration extends WebMvcConfigurerAdapter {
/******************************************编码部分*****************************************************/
@Bean
@ConditionalOnMissingBean
public HttpMessageConverter<String> responseBodyConverter() {
StringHttpMessageConverter converter = new StringHttpMessageConverter(
Charset.forName("UTF-8"));
@@ -68,6 +71,7 @@ public class WebAutoConfiguration extends WebMvcConfigurerAdapter {
}
@Bean
@ConditionalOnMissingBean
public MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter() {
Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder();
builder.serializationInclusion(JsonInclude.Include.NON_NULL);
@@ -120,6 +124,7 @@ public class WebAutoConfiguration extends WebMvcConfigurerAdapter {
* @return
*/
@Bean
@ConditionalOnMissingBean
public MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter(ObjectMapper objectMapper) {
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
objectMapper.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true);
@@ -138,6 +143,7 @@ public class WebAutoConfiguration extends WebMvcConfigurerAdapter {
* @return
*/
@Bean
@ConditionalOnMissingBean
@ConditionalOnProperty(name = "yexuejc.web.validation-filter.enable", matchIfMissing = true)
public FilterRegistrationBean validationFilter() {
FilterRegistrationBean registration = new FilterRegistrationBean();
@@ -148,11 +154,12 @@ public class WebAutoConfiguration extends WebMvcConfigurerAdapter {
return registration;
}
@Bean
/**
* 是否开启HTTPSSSL请求证书验证忽略默认false
*/
@ConditionalOnProperty(name = "yexuejc.enable.ssl-ignore", matchIfMissing = false)
@ConditionalOnProperty(name = "yexuejc.ssl-ignore.enable", matchIfMissing = false)
@Bean
@ConditionalOnMissingBean
public SSLUtil getSslUtil() {
return new SSLUtil();
}
@@ -161,6 +168,7 @@ public class WebAutoConfiguration extends WebMvcConfigurerAdapter {
* 全局异常处理
*/
@ControllerAdvice
@ConditionalOnProperty(name = "yexuejc.global.exception.enable", matchIfMissing = true)
static class GlobalExceptionHandler {
private static final String ERROR_MSG = "系统错误,请联系管理员";
@@ -185,3 +193,5 @@ public class WebAutoConfiguration extends WebMvcConfigurerAdapter {
}
}

View File

@@ -9,6 +9,7 @@ import com.yexuejc.springboot.base.exception.GatewayException;
import com.yexuejc.springboot.base.util.LogUtil;
import org.apache.commons.io.IOUtils;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.core.MethodParameter;
import org.springframework.http.HttpHeaders;
@@ -35,6 +36,7 @@ import java.security.interfaces.RSAPrivateKey;
@ControllerAdvice
@ConditionalOnClass({RequestBodyAdvice.class, HttpHeaders.class, HttpInputMessage.class, HttpMessageConverter.class})
@EnableConfigurationProperties(RsaProperties.class)
@ConditionalOnProperty(value = "yexuejc.filter.req.enable", matchIfMissing = false)
public class ParamsRequestBodyAdvice implements RequestBodyAdvice {
private final RsaProperties properties;
@@ -49,12 +51,25 @@ public class ParamsRequestBodyAdvice implements RequestBodyAdvice {
}
@Override
public Object handleEmptyBody(Object body, HttpInputMessage inputMessage, MethodParameter parameter, Type targetType, Class<? extends HttpMessageConverter<?>> converterType) {
public Object handleEmptyBody(Object body, HttpInputMessage inputMessage, MethodParameter parameter, Type targetType, Class<?
extends HttpMessageConverter<?>> converterType) {
return body;
}
/**
* 使用入参加密
* 自定义入参的解密方式只需要重写 beforeBodyRead 方法即可
*
* @param inputMessage
* @param parameter
* @param targetType
* @param converterType
* @return
* @throws IOException
*/
@Override
public HttpInputMessage beforeBodyRead(HttpInputMessage inputMessage, MethodParameter parameter, Type targetType, Class<? extends HttpMessageConverter<?>> converterType) throws IOException {
public HttpInputMessage beforeBodyRead(HttpInputMessage inputMessage, MethodParameter parameter, Type targetType, Class<?
extends HttpMessageConverter<?>> converterType) throws IOException {
if (properties.isDecrypt()) {
ParamsPO paramsPO = JsonUtil.json2Obj(IOUtils.toString(inputMessage.getBody(), "UTF-8"), ParamsPO.class);
//RSA解密
@@ -63,7 +78,8 @@ public class ParamsRequestBodyAdvice implements RequestBodyAdvice {
RSAPrivateKey rsaPrivateKey = null;
if (StrUtil.isEmpty(properties.getPrivateKey())) {
rsaPrivateKey = RSA2.getPrivateKey(
this.getClass().getResource(properties.getPrivateKeyPath()).getFile().toString(),
// this.getClass().getResource(properties.getPrivateKeyPath()).getFile().toString(),
this.getClass().getResourceAsStream(properties.getPrivateKeyPath()),
properties.getPrivateAlias(),
properties.getPrivatePwd());
} else {
@@ -92,7 +108,8 @@ public class ParamsRequestBodyAdvice implements RequestBodyAdvice {
}
@Override
public Object afterBodyRead(Object body, HttpInputMessage inputMessage, MethodParameter parameter, Type targetType, Class<? extends HttpMessageConverter<?>> converterType) {
public Object afterBodyRead(Object body, HttpInputMessage inputMessage, MethodParameter parameter, Type targetType, Class<?
extends HttpMessageConverter<?>> converterType) {
return body;
}

View File

@@ -7,6 +7,7 @@ import com.yexuejc.base.util.JsonUtil;
import com.yexuejc.base.util.StrUtil;
import com.yexuejc.springboot.base.util.LogUtil;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
@@ -32,6 +33,7 @@ import java.util.Map;
@ControllerAdvice
@ConditionalOnClass({ResponseBodyAdvice.class, ServerHttpRequest.class, ServerHttpResponse.class, MediaType.class})
@EnableConfigurationProperties(RsaProperties.class)
@ConditionalOnProperty(value = "yexuejc.filter.resp.enable", matchIfMissing = false)
public class ParamsResponseBodyAdvice implements ResponseBodyAdvice {
private final RsaProperties properties;
@@ -47,7 +49,8 @@ public class ParamsResponseBodyAdvice implements ResponseBodyAdvice {
}
@Override
public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {
public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class selectedConverterType,
ServerHttpRequest request, ServerHttpResponse response) {
if (returnType.getMethod().isAnnotationPresent(SerializedField.class)) {
//获取注解配置的包含和去除字段
SerializedField serializedField = returnType.getMethodAnnotation(SerializedField.class);
@@ -74,7 +77,8 @@ public class ParamsResponseBodyAdvice implements ResponseBodyAdvice {
RSAPrivateKey rsaPrivateKey = null;
if (StrUtil.isEmpty(properties.getPrivateKey())) {
rsaPrivateKey = RSA2.getPrivateKey(
this.getClass().getResource(properties.getPrivateKeyPath()).getFile().toString(),
// this.getClass().getResource(properties.getPrivateKeyPath()).getFile().toString(),
this.getClass().getResourceAsStream(properties.getPrivateKeyPath()),
properties.getPrivateAlias(),
properties.getPrivatePwd());
} else {

View File

@@ -6,6 +6,7 @@ import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.extension.activerecord.Model;
import com.yexuejc.base.util.JsonUtil;
import com.yexuejc.springboot.base.mapper.handler.JsonTypeHandler;
import com.yexuejc.springboot.base.security.inte.User;
import java.io.Serializable;
@@ -27,7 +28,7 @@ public class Consumer extends Model<Consumer> implements User {
/**
* 用户id
*/
@TableId(value = "consumer_id", type = IdType.UUID)
@TableId(value = "consumer_id", type = IdType.ASSIGN_UUID)
private String consumerId;
/**
* 手机号
@@ -92,7 +93,7 @@ public class Consumer extends Model<Consumer> implements User {
/**
* 角色、权限
*/
@TableField(value = "roles", el = "roles,typeHandler=com.yexuejc.guansc.core.mybatis.handler.JsonTypeHandler")
@TableField(value = "roles", typeHandler = JsonTypeHandler.class)
private List<String> roles;
/**
* 支付密码
@@ -157,19 +158,16 @@ public class Consumer extends Model<Consumer> implements User {
return this;
}
public Consumer setEnable(boolean enable) {
this.enable = enable;
return this;
}
public Consumer setNonExpire(boolean nonExpire) {
this.nonExpire = nonExpire;
return this;
}
public Consumer setNonLock(boolean nonLock) {
this.nonLock = nonLock;
return this;
@@ -276,7 +274,7 @@ public class Consumer extends Model<Consumer> implements User {
}
@Override
protected Serializable pkVal() {
public Serializable pkVal() {
return this.consumerId;
}
}

View File

@@ -7,11 +7,9 @@ import com.yexuejc.base.util.JsonUtil;
import com.yexuejc.base.util.StrUtil;
import com.yexuejc.springboot.base.ApplicationRun;
import com.yexuejc.springboot.base.filter.RsaProperties;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import java.io.IOException;
import java.security.KeyStoreException;
@@ -19,14 +17,12 @@ import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
import java.security.spec.InvalidKeySpecException;
import java.util.Base64;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import static org.assertj.core.api.Assertions.assertThat;
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = ApplicationRun.class)
public class ApplicationTest {
@Autowired
@@ -76,10 +72,8 @@ public class ApplicationTest {
// String strData = "HgTMgxEEFSr6zRLvZQ3U5CAKjJqwKf0lfruZTi32iWObkbJA5mHuOTKU4rXYkej4UsPfArYUA45GfxatwFoB4Q";
String strData = "K9Zyg82WDvIApFmXTxPwjQw_VA041jfBcxMIP6jpMM6xWe1XajGf3__7DqSLrS9MwCra9cYkidcjVJAKZn9cmQ";
String mapData = "cEPfMp7-rim76XFdbNDSIzDRXyHySpz0VOZP6HC8U-JPl-ZxNZKp6ethEQWWITcuUPzIhp4fHiGKNsHA7F6OxCxibpMLj5-ZsgJJvcczw8Liens5kYgciRF1UziR3LFy6vybN9H1CJnqXaddbl3t_41P-_1l5Ev7YYa8woWp7ulaRPeTCDjohEpmx2Vi6aPSrm3hjjmitkD9gb0O6vFDNnclyNhFepKV3oh93tNv50sEQQ_QSBUXSHUtCnhTiBX8VsRX3h58F2tie7bG8VSk-6KFuXI07OiqFZSNpcwDOuq-GfMlEfPL3pX-gYhoOORPNClRlQHwyfHXBJly3gRtNVpVksHWQjr1xutWgYfwRjQPHBHNZwfx4E0XoCTuz9qH1CzFmmz68i63GzCM286zJ-J26MkiTDO1zH4jhglo38tnzz9HLeDcbbCuJg1jzkvpFiWamM-6odWhtCg65BS1tJJVWg023kWygZMu5Ebrm5WBbbatN87_K5zn211tFpKwRq2oVjO_AfJRY90WlQGEIHnzZNz_cf8mAjlmilHDuNdjYlj3axTUqLfgLDVaIkasREnjMI7oe8oAtG2ju2aq-xSAQZ_U-7-rsyBpoy0jnwRmlyUxhXgIX0zrfBQNXEjzPtg-iJ14R5qz1iOAJL7NtQQeuYngGTj6msDlKGEd_MQTLAFDbpiVPwWX00jLT1Ll3_zhivpPCUAmC8Yz58khkqrqi4FdIxJTDkxd0PFOBH8DYicF7ls4UdOHT24mAKDwUF_TfZ32oiiKSzCD9MJB8GEXjzx7tDFok-HsdOjI6ZnSUJCOTj3wne2E6_a8Gq2_vp5CWyW12wthJbH79aa7JVfy5cx-cZmNid7oCe54KYclz1tdUgLPCQ1ajsEevbRJ_NBkTmY2wAmUpHODeocDaYt_2AwAU2DLiv2uZuaVszNSUy593Zrzxq5AaY-oWbEeD24SyEWJObJtz5knYzr4NxjZShcjx9ezwiwkRZMtLZpA_cCPFAK1nOrN8zHCOZquS17CCSLDySLvGbxNqYeBa_lGSq8cQuQo8yybd1WkuLKUjUiJecmH2XcZNTPCtdRe0eLlRtk5928AQGsQugwSig";
// String listData = "X65trOhRSpeaN-2qP0zhdYi2jeJDcrTz2JHkc6UFG17xAho-VO0fkD0cA8wxoxcqyTaulOiSzaidZ2VeIvKjuinlKT2r23kdMJxjJodOZojssxgGSxm5gnry2tq5X8dbP7n-jodvAvLE9Gtq7AaBQ36ZQBQ2RcFB3TiHKHGin0gfn6T6A80orYD7i-Bdc0rh_pBEdLwGt1wWY_C8QuxeBmMWh0jmLVfpa3ZZOXVc9I7wIxzc1taQ7f-8Om9SNfXc";
String listData = "Sf_FO8YC9EUNTeM0n9EVuDzwvLz3DcxOuG4-5UZ9486lLHAx7IOuAhPgVHpQGsQiqJ7Y3fTaWFr6rRFPL12rVg";
@@ -107,7 +101,6 @@ public class ApplicationTest {
)
).isEqualTo("f721e7b0d5415302f5fe7dc5beb2938a");
//list
assertThat(
StrUtil.toMD5(
@@ -120,7 +113,6 @@ public class ApplicationTest {
}
/**
* 证书操作
*
@@ -142,15 +134,13 @@ public class ApplicationTest {
// String dataStr = "{\"ret\":\"0\",\"expireTime\":\"2015/10/28 23:59:59\",\"rettxt\":\"OK\",\"token\":\"69296128A59798E2D423D3B1A9F766F4\"}";
String dataStr = "{\"foodsCode\":\"49\",\"latlng\":\"22.5,114.0\",\"pageIndex\":1,\"pageSize\":10}";
/***************************************************************************************************************************************************************************************************************************************/
//客户端公钥加密
// String publicEncryptResult = RSA.publicEncrypt(dataStr, RSA2.getPublicKey(publicKey));
// System.out.println(publicEncryptResult);
// System.out.println(StrUtil.toMD5(dataStr));
String publicEncryptResult="KHAtNzGkT/Mn7d/Ei6aoZ8KCA04mYJi5b/sxt/Jgzq76jNi0O/EMACDsipgQuwZTJrrys5xOPyy4\n1Gf8LMEldZE3GeY3i92A5jnH7IeWnLojYhNaKdIuLuf4l5uJmFgpzxhoxqSkp2JJ5Vbt8j5Hy4ov\n7tfxPDBwnT6FSfDqGLU\u003d\n";
String publicEncryptResult = "KHAtNzGkT/Mn7d/Ei6aoZ8KCA04mYJi5b/sxt/Jgzq76jNi0O/EMACDsipgQuwZTJrrys5xOPyy4\n1Gf8LMEldZE3GeY3i92A5jnH7IeWnLojYhNaKdIuLuf4l5uJmFgpzxhoxqSkp2JJ5Vbt8j5Hy4ov\n7tfxPDBwnT6FSfDqGLU\u003d\n";
//服务器私钥解密
String privateDecryptResult = RSA.privateDecrypt(publicEncryptResult, RSA2.getPrivateKey(privateKey, privateAlias, privatePwd));
@@ -168,9 +158,9 @@ public class ApplicationTest {
}
/**
* key加解密
*
* @throws NoSuchAlgorithmException
* @throws InvalidKeySpecException
*/
@@ -179,7 +169,6 @@ public class ApplicationTest {
String publicKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCX9uSsfJeIDIPzxCtwwFh5vrIKar69i3DPUTDEiKPRdtmADa8Ls6KAsPVpzgtQYoYVpYBoMbBtp0cGRoQULO83NWIAhmsU2cvd0nmGlB2xPRz+uGYW1rsYyCM8RSvfAwCVNsJD10A9voLhRQuYHPIDmay1sBA/casvEvYwMqDZtQIDAQAB";
System.out.println(publicKey.length());
// String privateKey = "MIIBVAIBADANBgkqhkiG9w0BAQEFAASCAT4wggE6AgEAAkEAiSo5blJ9-QJ0_QElcy5AaRTq-3oO4lJ8PvIOIt-Xr5SUFODVj3DUbiy6_0bxQYO3NiYHlXPb37UVV3jjlXJsXwIDAQABAkBE0WOJH2hGs93gRl_0vwLf9ffDfkTTdlER_73p70aad3QZRslEkinQH7G5aE_DgBm5m72TCeH-PD2FZ2lwtavBAiEAvnRown5Lpqbl0tN_OUxr_e1u9d_-8dNL_JEETO7BZCECIQC4XtY-18j0bVVLxaXPjKQ00D59yntwObihDNyRK0nAfwIgHPHEGgrnpGQo-Wl7JFIg925mNqfcLxRVsAS6CpcefQECIQCUsLdsmy6QIhTmNRJSXoSXq1KatE_05DhIekzwLs8eFQIgfMawMiu52ZxBI5_pZ7ancQZ6Dsxl45utFqJShzV1pio";
//// String publicKey = "MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAIkqOW5SffkCdP0BJXMuQGkU6vt6DuJSfD7yDiLfl6-UlBTg1Y9w1G4suv9G8UGDtzYmB5Vz29-1FVd445VybF8CAwEAAQ";
// String publicKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCX9uSsfJeIDIPzxCtwwFh5vrIKar69i3DPUTDEiKPRdtmADa8Ls6KAsPVpzgtQYoYVpYBoMbBtp0cGRoQULO83NWIAhmsU2cvd0nmGlB2xPRz+uGYW1rsYyCM8RSvfAwCVNsJD10A9voLhRQuYHPIDmay1sBA/casvEvYwMqDZtQIDAQAB";

View File

@@ -1,7 +1,5 @@
package com.yexuejc.springboot.base.test;
import sun.misc.BASE64Encoder;
import java.io.*;
import java.security.KeyStore;
import java.security.PrivateKey;
@@ -9,8 +7,11 @@ import java.security.PublicKey;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.util.Base64;
/**
* 生成公钥工具; http://bijian1013.iteye.com/blog/2339874
*
* @ClassName: KeyStoreHelper
* @Description:
* @author: maxf
@@ -33,7 +34,7 @@ public class KeyStoreHelper {
byte[] publicKeyBytes = publicKey.getEncoded();
// byte[] privateKeyBytes = privateKey.getEncoded();
String publicKeyBase64 = new BASE64Encoder().encode(publicKeyBytes);
String publicKeyBase64 = Base64.getEncoder().encodeToString(publicKeyBytes);
// String privateKeyBase64 = new BASE64Encoder().encode(privateKeyBytes);
System.out.println("publicKeyBase64.length():" + publicKeyBase64.length());

View File

@@ -4,11 +4,9 @@ import com.aliyun.mns.model.Message;
import com.yexuejc.base.util.JsonUtil;
import com.yexuejc.base.util.StrUtil;
import com.yexuejc.springboot.base.autoconfigure.MnsFacade;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import java.util.HashMap;
import java.util.Map;
@@ -20,7 +18,6 @@ import java.util.Map;
* @Description
* @date 2018/11/1 14:25
*/
@RunWith(SpringRunner.class)
@SpringBootTest
public class MnsTest {

View File

@@ -6,11 +6,9 @@ import com.yexuejc.base.util.StrUtil;
import com.yexuejc.springboot.base.autoconfigure.OssFacade;
import com.yexuejc.springboot.base.exception.ImageException;
import com.yexuejc.springboot.base.util.LogUtil;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import java.io.ByteArrayInputStream;
import java.io.IOException;
@@ -23,7 +21,6 @@ import java.io.InputStream;
* @Description
* @date 2018/11/1 14:58
*/
@RunWith(SpringRunner.class)
@SpringBootTest
public class OssTest {
@Autowired
@@ -32,11 +29,11 @@ public class OssTest {
/**
* 上传图片到oss
* <p>
* 这里是模拟微信登录时获取到微信头像地址缓存到base64然后上传到OSS
* 这里是模拟微信登录时获取到微信头像地址缓存到base64然后上传到OSS
* </p>
*/
@Test
public void put(){
public void put() {
putOss4Head(null, "https://avatar.csdn.net/7/8/1/3_wulex.jpg");
}

View File

@@ -3,8 +3,7 @@ package com.yexuejc.springboot.base.test;
import com.yexuejc.base.util.JsonUtil;
import com.yexuejc.base.util.StrUtil;
import com.yexuejc.springboot.base.autoconfigure.MutiRedisAutoConfiguration;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.test.context.SpringBootTest;
@@ -24,7 +23,6 @@ import java.util.concurrent.TimeUnit;
* @Description
* @date 2018/11/1 11:16
*/
@RunWith(SpringRunner.class)
@SpringBootTest
public class RedisTest {
/**

View File

@@ -5,28 +5,46 @@ spring.application.name=@pom.artifactId@
logging.level.root=info
logging.path=/logs/yexuejc-springboot-parent
#========================================================================================================================
#========================================================================================================================
#核心
#开启功能 redis webmvc
yexuejc.autoconfigure.redis.enable=true
#webmvc 包含以下功能
yexuejc.autoconfigure.webmvc.enable=true
#全局异常处理
yexuejc.ssl-ignore.enable=true
#开启HTTPSSSL请求证书验证忽略
yexuejc.global.exception.enable=true
#开启校验过滤器目前校验HTTP Header是否符合规范
yexuejc.web.validation-filter.enable=true
# 拦截类型请求路径0忽略模式默认拦截全部1拦截模式默认一个都不拦截
#yexuejc.http.filter=0
yexuejc.http.filter.type=1
#忽略路径示例放开swagger
#yexuejc.http.filter.ignored=/,/swagger/**,/error,/v2/api-docs,/webjars/**
#========================================================================================================================
#========================================================================================================================
yexuejc.http.encrypt.encrypt=true
yexuejc.http.encrypt.decrypt=true
#<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Կ<EFBFBD><EFBFBD>ʽ
#配置密钥方式
#yexuejc.http.encrypt.private-key=MIIBVAIBADANBgkqhkiG9w0BAQEFAASCAT4wggE6AgEAAkEAiSo5blJ9-QJ0_QElcy5AaRTq-3oO4lJ8PvIOIt-Xr5SUFODVj3DUbiy6_0bxQYO3NiYHlXPb37UVV3jjlXJsXwIDAQABAkBE0WOJH2hGs93gRl_0vwLf9ffDfkTTdlER_73p70aad3QZRslEkinQH7G5aE_DgBm5m72TCeH-PD2FZ2lwtavBAiEAvnRown5Lpqbl0tN_OUxr_e1u9d_-8dNL_JEETO7BZCECIQC4XtY-18j0bVVLxaXPjKQ00D59yntwObihDNyRK0nAfwIgHPHEGgrnpGQo-Wl7JFIg925mNqfcLxRVsAS6CpcefQECIQCUsLdsmy6QIhTmNRJSXoSXq1KatE_05DhIekzwLs8eFQIgfMawMiu52ZxBI5_pZ7ancQZ6Dsxl45utFqJShzV1pio
#yexuejc.http.encrypt.public-key=MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAIkqOW5SffkCdP0BJXMuQGkU6vt6DuJSfD7yDiLfl6-UlBTg1Y9w1G4suv9G8UGDtzYmB5Vz29-1FVd445VybF8CAwEAAQ
#<EFBFBD><EFBFBD><EFBFBD><EFBFBD>֤<EFBFBD>ʽ
#配置证书方式
yexuejc.http.encrypt.private-key-path=/lgfishing.keystore
yexuejc.http.encrypt.private-alias=lgfishing
yexuejc.http.encrypt.private-pwd=lgfishing2018
#<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
#编码
spring.http.encoding.force=true
spring.http.encoding.charset=UTF-8
spring.http.encoding.enabled=true
server.tomcat.uri-encoding=UTF-8
#<EFBFBD>Ƿ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>HTTPS<EFBFBD><EFBFBD>SSL<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>֤<EFBFBD><EFBFBD><EFBFBD><EFBFBD>֤<EFBFBD><EFBFBD><EFBFBD>ԣ<EFBFBD>Ĭ<EFBFBD><EFBFBD>false
#是否开启HTTPSSSL)请求证书验证忽略:默认false
yexuejc.enable.ssl-ignore=true
@@ -48,16 +66,16 @@ yexuejc.alibaba.oss.bucket=guansichou
#========================================================================================================================
# security<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
# security相关
#reids
#<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD><EFBFBD>redis<EFBFBD><EFBFBD>db0Ĭ<EFBFBD>Ͽ<EFBFBD><EFBFBD><EFBFBD>
#开启指定redisdb0默认开启
yexuejc.redis.db1=true
spring.redis.jedis.pool.max-active=100
spring.redis.jedis.pool.max-idle=10
spring.redis.jedis.pool.min-idle=3
spring.redis.host=121.42.165.89
spring.redis.password=
spring.redis.port=16379
spring.redis.host=192.168.0.107
spring.redis.password=yexuejc2022
spring.redis.port=6379
#db
@@ -75,19 +93,19 @@ spring.datasource.data=classpath:db/data.sql
#========================================================================================================================
#mybatis-plus
mybatis-plus.mapper-locations=classpath*:mapper/*.xml
#ʵ<EFBFBD><EFBFBD>ɨ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>package<EFBFBD>ö<EFBFBD><EFBFBD>Ż<EFBFBD><EFBFBD>߷ֺŷָ<EFBFBD>
#实体扫描多个package用逗号或者分号分隔
mybatis-plus.type-aliases-package=com.yexuejc.springboot.base.security.domain
#<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>0:"<22><><EFBFBD>ݿ<EFBFBD>ID<49><44><EFBFBD><EFBFBD>", 1:"<22>û<EFBFBD><C3BB><EFBFBD><EFBFBD><EFBFBD>ID",2:"<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊδ<CEAA><CEB4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>", 3:"ȫ<EFBFBD><EFBFBD>ΨһID UUID",4:ȫ<EFBFBD><EFBFBD>ΨһID (UUID),5:<EFBFBD>ַ<EFBFBD><EFBFBD><EFBFBD>ȫ<EFBFBD><EFBFBD>ΨһID (idWorker <EFBFBD><EFBFBD><EFBFBD>ַ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʾ);
#主键类型0:"数据库ID自增", 1:"用户输入ID",2:"该类型为未设置主键类型", 3:"全局唯一ID UUID",4:全局唯一ID (UUID),5:字符串全局唯一ID (idWorker 的字符串表示);
mybatis-plus.global-config.db-config.id-type=uuid
mybatis-plus.global-config.db-config.db-type=POSTGRE_SQL
#<EFBFBD>ֶβ<EFBFBD><EFBFBD><EFBFBD> 0:"<22><><EFBFBD><EFBFBD><EFBFBD>ж<EFBFBD>",1:"<EFBFBD><EFBFBD> NULL <EFBFBD>ж<EFBFBD>"),2:"<EFBFBD>ǿ<EFBFBD><EFBFBD>ж<EFBFBD>"
#字段策略 0:"忽略判断",1:" NULL 判断"),2:"非空判断"
mybatis-plus.global-config.db-config.field-strategy=not_empty
#<EFBFBD>շ<EFBFBD><EFBFBD>»<EFBFBD><EFBFBD><EFBFBD>ת<EFBFBD><EFBFBD>
#驼峰下划线转换
mybatis-plus.global-config.db-config.column-underline=true
#<EFBFBD>߼<EFBFBD>ɾ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ã<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>3<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ã<EFBFBD>
#逻辑删除配置下面3个配置
mybatis-plus.global-config.db-config.logic-delete-value=true
mybatis-plus.global-config.db-config.logic-not-delete-value=false
#<EFBFBD><EFBFBD><EFBFBD>÷<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݿ<EFBFBD>(column<6D>»<EFBFBD><C2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>&&<26><><EFBFBD><EFBFBD>javaʵ<61><CAB5><EFBFBD><EFBFBD><EFBFBD>շ<EFBFBD><D5B7><EFBFBD><EFBFBD><EFBFBD>)<29><><EFBFBD>Զ<EFBFBD>ƥ<EFBFBD><C6A5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>as<61><73>û<EFBFBD><C3BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>SQL<51><4C>Ҫдas<61><73> select user_id as userId<EFBFBD><EFBFBD>
#配置返回数据库(column下划线命名&&返回java实体是驼峰命名)自动匹配无需as没开启这个SQL需要写as select user_id as userId
mybatis-plus.configuration.map-underscore-to-camel-case=true
mybatis-plus.configuration.cache-enabled=false
#========================================================================================================================

View File

@@ -0,0 +1,16 @@
<?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>
<groupId>com.yexuejc.springboot</groupId>
<version>1.0.0</version>
<artifactId>yexuejc-springboot-example</artifactId>
<packaging>pom</packaging>
<name>yexuejc-springboot-example</name>
<modules>
<module>yexuejc-springboot-simple</module>
<module>springboot-security-login-simple</module>
</modules>
</project>

View File

@@ -0,0 +1,27 @@
/target/
!.mvn/wrapper/maven-wrapper.jar
### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
### NetBeans ###
/nbproject/private/
/build/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
.mvn/wrapper/maven-wrapper.properties
.mvn/wrapper/maven-wrapper.jar

View File

@@ -0,0 +1,245 @@
https://github.com/yexuejc/yexuejc-springboot 多方登录模块使用例子
---------------------------------------------------------------
#### 先上[效果图](Securtity效果图.md)
> **引入依赖 pom.xml**
```mxml
<dependency>
<groupId>com.yexuejc.springboot</groupId>
<artifactId>yexuejc-springboot-base</artifactId>
<version>最新版</version>
</dependency>
```
#### 所有核心文件都在 com.yexuejc.springboot.base.security 包下
#### 现附上系统实现逻辑图
![多方登录系统实现逻辑图](sl/多方登录设计.jpg)
1.com.yexuejc.springboot.base.security.SecurityConfig
<br/>
**Security 核心本文件并未启动Security需继承然后继承类上加上@EnableWebSecurity注解就启动Security了。**
* 实现loadUserByUsername()方法;自定义逻辑处理登录账号,返回登录账号相关信息
* 实现loginHodler()方法自定义处理登录成功filter.setAuthenticationSuccessHandler()和失败filter.setAuthenticationFailureHandler()的处理
* 继承configure(HttpSecurity http) 完善更多security过滤配置
* 例子[com.yexuejc.springboot.base.security.MySecurityConfig](../yexuejc-springboot-base/src/test/java/com/yexuejc/springboot/base/security/MySecurityConfig.java)
#### 注: 代码中抛出的相关异常拦截在filter.setAuthenticationFailureHandler()中处理,参考[MySecurityConfig](../yexuejc-springboot-base/src/test/java/com/yexuejc/springboot/base/security/MySecurityConfig.java)
```
filter.setAuthenticationFailureHandler((request, response, exception) -> {
response.setContentType("application/json;charset=UTF-8");
response.setStatus(HttpStatus.UNAUTHORIZED.value());
Resps resps = new Resps();
if (exception instanceof DisabledException) {
resps.setErr(RespsConsts.CODE_FAIL, new String[]{BizConsts.BASE_IS_LOCK_MSG});
} else if (exception instanceof AccountExpiredException) {
resps.setErr(RespsConsts.CODE_FAIL, new String[]{BizConsts.BASE_IS_EXPIRE_MSG});
} else if (exception instanceof CredentialsExpiredException) {
resps.setErr(BizConsts.BASE_LOGIN_IS_EXPIRE_CODE, new String[]{BizConsts.BASE_LOGIN_IS_EXPIRE_MSG});
} else if (exception instanceof LockedException) {
resps.setErr(RespsConsts.CODE_FAIL, new String[]{BizConsts.BASE_IS_LOCKED_MSG});
} else if (exception instanceof AuthenticationCredentialsNotFoundException) {
resps.setErr(RespsConsts.CODE_FAIL, new String[]{BizConsts.BASE_CREDENTIALS_NOT_FOUND_MSG});
} else if (exception instanceof ThirdPartyAuthorizationException) {
resps.setErr(RespsConsts.CODE_FAIL, new String[]{exception.getMessage()});
} else if (exception instanceof BadCredentialsException) {
resps.setErr(RespsConsts.CODE_FAIL, new String[]{BizConsts.BASE_PWD_IS_ERR_MSG});
} else if (exception instanceof UsernameNotFoundException) {
resps.setErr(RespsConsts.CODE_FAIL, new String[]{BizConsts.BASE_ACCOUNT_NOT_FOUND_MSG});
} else if (exception instanceof UserNotAuthoriayException) {
resps.setErr(RespsConsts.CODE_FAIL, new String[]{exception.getMessage()});
} else {
resps.setErr(RespsConsts.CODE_FAIL, new String[]{BizConsts.BASE_SYS_ERR_MSG});
}
response.getWriter().write(JsonUtil.obj2Json(resps));
response.getWriter().close();
});
```
2.com.yexuejc.springboot.base.security.UserDetailsManager
<br/>
**获取登录用户信息**
* 需要实现com.yexuejc.springboot.base.security.inte.UserService
* 例子[com.yexuejc.springboot.base.security.UserServiceImpl](../yexuejc-springboot-base/src/test/java/com/yexuejc/springboot/base/security/UserServiceImpl.java)
3.com.yexuejc.springboot.base.security.LoginToken
<br/>
**登录成功封装至JWT的登录用户信息**
4.com.yexuejc.springboot.base.security.ConsumerUser
<br/>
**登录成功封装至redis的登录用户信息**
5.com.yexuejc.springboot.base.security.ConsumerToken
<br/>
**登录请求时(/login)用户登录参数信息**
6.com.yexuejc.springboot.base.security.ConsumerSecurityContextRepository
<br/>
**登录校验token正确性返回登录用户从redis中获取**
7.com.yexuejc.springboot.base.security.ConsumerAuthenticationProvider
<br/>
**登录时账号校验原为密码校验重写之后增加校验短信验证码第三方openid**
8.com.yexuejc.springboot.base.security.ConsumerAuthenticationProcessingFilter
<br/>
**重写登录拦截,集成多种登录方式到/login**
<h2>使用example</h2>
1. 下载本项目至本地找到yexuejc/yexuejc-springboot/yexuejc-springboot-base/src/test/java/com/yexuejc/springboot/base/ApplicationRun.java
至接run
2. 测试环境配置如下(测试运行环境都在test下面)<br/>
2.1 pom.xml<br/>
* mybatis-plus数据库框架
* HikariCP数据库连接池
* 本地数据库H2
* JJWT作为登录凭证token
* redis 存储登录用户信息
> 关于这些相关框架、工具不做详解,有兴趣可以去学习,这些都可以用你自己熟悉的替换
com.yexuejc.springboot版本请依赖最新版本
```
<parent>
<groupId>com.yexuejc.springboot</groupId>
<artifactId>yexuejc-springboot-parent</artifactId>
<version>2.0.3</version>
</parent>
<properties>
<yexuejc.base.version>1.2.1</yexuejc.base.version>
</properties>
<dependencies>
<!--base 引用-->
<dependency>
<groupId>com.yexuejc.springboot</groupId>
<artifactId>yexuejc-springboot-base</artifactId>
<version>${parent.version}</version>
</dependency>
<!--https://gitee.com/incloudcode/yexuejc-base.git-->
<dependency>
<groupId>com.yexuejc.base</groupId>
<artifactId>yexuejc-base</artifactId>
<version>${yexuejc.base.version}</version>
</dependency>
<!-- 使用springMVC -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Spring Security -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<!-- JJWT -->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<optional>true</optional>
</dependency>
<!-- 使用Redis -->
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</dependency>
<!-- HikariCP数据库连接池JDK1.8 -->
<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
</dependency>
<!-- springboot mybatis-plus-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
</dependency>
<!-- 内存数据库h2-->
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<repositories>
<repository>
<id>yexuejc-nexus-public</id>
<name>yexuejc-nexus-public</name>
<url>https://nexus.yexuejc.club/repository/maven-public/</url>
</repository>
</repositories>
```
2.2 对应的application.properties<br/>
* redis 0库存储登录用户信息1库存储短信验证码
* H2数据库 创建数据库表 consumer(用户表) [schema.sql](../yexuejc-springboot-base/src/test/resources/db/schema.sql)
增加一条用户数据[data.sql](../yexuejc-springboot-base/src/test/resources/db/data.sql)
<br/>启动项目后会自动运行这两个脚本自此H2数据库中就会有一条用户数据测试时可以用来登录
<br/>PS:项目运行成功后可以访问 http://localhost:8888/h2-console 登录到数据库
* mybatis-plus 详情[http://mp.baomidou.com/](http://mp.baomidou.com/)
```
#========================================================================================================================
# security相关
#reids
#开启指定redis库db0默认开启
yexuejc.redis.db1=true
spring.redis.jedis.pool.max-active=100
spring.redis.jedis.pool.max-idle=10
spring.redis.jedis.pool.min-idle=3
spring.redis.host=121.42.165.89
spring.redis.password=
spring.redis.port=16379
#db
spring.h2.console.path=/h2-console
spring.h2.console.enabled=true
spring.h2.console.settings.web-allow-others=true
spring.datasource.username=sa
spring.datasource.password=123456
spring.datasource.url=jdbc:h2:mem:test;MODE=PostgreSQL
spring.datasource.driver-class-name=org.h2.Driver
spring.datasource.schema=classpath:db/schema.sql
spring.datasource.data=classpath:db/data.sql
#========================================================================================================================
#mybatis-plus
mybatis-plus.mapper-locations=classpath*:mapper/*.xml
#实体扫描多个package用逗号或者分号分隔
mybatis-plus.type-aliases-package=com.yexuejc.springboot.base.security.domain
#主键类型0:"数据库ID自增", 1:"用户输入ID",2:"该类型为未设置主键类型", 3:"全局唯一ID UUID",4:全局唯一ID (UUID),5:字符串全局唯一ID (idWorker 的字符串表示);
mybatis-plus.global-config.db-config.id-type=uuid
mybatis-plus.global-config.db-config.db-type=POSTGRE_SQL
#字段策略 0:"忽略判断",1:"非 NULL 判断"),2:"非空判断"
mybatis-plus.global-config.db-config.field-strategy=not_empty
#驼峰下划线转换
mybatis-plus.global-config.db-config.column-underline=true
#逻辑删除配置下面3个配置
mybatis-plus.global-config.db-config.logic-delete-value=true
mybatis-plus.global-config.db-config.logic-not-delete-value=false
#配置返回数据库(column下划线命名&&返回java实体是驼峰命名)自动匹配无需as没开启这个SQL需要写as select user_id as userId
mybatis-plus.configuration.map-underscore-to-camel-case=true
mybatis-plus.configuration.cache-enabled=false
#========================================================================================================================
```
> 附图
![security1.png](security1.png)
<br>
![security2.png](security2.png)
<br>
![security3.png](security3.png)

View File

@@ -0,0 +1,24 @@
Security 多方登录封装使用效果图
---------------
### 账号登录
密码错误
![](sl/sl_02.png)
正确
![](sl/sl_01.png)
### 短信登录
发送短信
![](sl/sl_ss.png)
短信错误
![](sl/sl_err.jpg)
短信过期
![](sl/sl_gq.png)
正确
![](sl/sl_10.png)
### 第三方登录
第一次登录,需要绑定手机号
![](sl/sl_t3.png)
绑定过手机号的第三方账号登录(绑定相关业务需要自己实现)
![](sl/sl_t4.png)

View File

@@ -0,0 +1,286 @@
#!/bin/sh
# ----------------------------------------------------------------------------
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
# ----------------------------------------------------------------------------
# ----------------------------------------------------------------------------
# Maven2 Start Up Batch script
#
# Required ENV vars:
# ------------------
# JAVA_HOME - location of a JDK home dir
#
# Optional ENV vars
# -----------------
# M2_HOME - location of maven2's installed home dir
# MAVEN_OPTS - parameters passed to the Java VM when running Maven
# e.g. to debug Maven itself, use
# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
# MAVEN_SKIP_RC - flag to disable loading of mavenrc files
# ----------------------------------------------------------------------------
if [ -z "$MAVEN_SKIP_RC" ] ; then
if [ -f /etc/mavenrc ] ; then
. /etc/mavenrc
fi
if [ -f "$HOME/.mavenrc" ] ; then
. "$HOME/.mavenrc"
fi
fi
# OS specific support. $var _must_ be set to either true or false.
cygwin=false;
darwin=false;
mingw=false
case "`uname`" in
CYGWIN*) cygwin=true ;;
MINGW*) mingw=true;;
Darwin*) darwin=true
# Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home
# See https://developer.apple.com/library/mac/qa/qa1170/_index.html
if [ -z "$JAVA_HOME" ]; then
if [ -x "/usr/libexec/java_home" ]; then
export JAVA_HOME="`/usr/libexec/java_home`"
else
export JAVA_HOME="/Library/Java/Home"
fi
fi
;;
esac
if [ -z "$JAVA_HOME" ] ; then
if [ -r /etc/gentoo-release ] ; then
JAVA_HOME=`java-config --jre-home`
fi
fi
if [ -z "$M2_HOME" ] ; then
## resolve links - $0 may be a link to maven's home
PRG="$0"
# need this for relative symlinks
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG="`dirname "$PRG"`/$link"
fi
done
saveddir=`pwd`
M2_HOME=`dirname "$PRG"`/..
# make it fully qualified
M2_HOME=`cd "$M2_HOME" && pwd`
cd "$saveddir"
# echo Using m2 at $M2_HOME
fi
# For Cygwin, ensure paths are in UNIX format before anything is touched
if $cygwin ; then
[ -n "$M2_HOME" ] &&
M2_HOME=`cygpath --unix "$M2_HOME"`
[ -n "$JAVA_HOME" ] &&
JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
[ -n "$CLASSPATH" ] &&
CLASSPATH=`cygpath --path --unix "$CLASSPATH"`
fi
# For Mingw, ensure paths are in UNIX format before anything is touched
if $mingw ; then
[ -n "$M2_HOME" ] &&
M2_HOME="`(cd "$M2_HOME"; pwd)`"
[ -n "$JAVA_HOME" ] &&
JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`"
# TODO classpath?
fi
if [ -z "$JAVA_HOME" ]; then
javaExecutable="`which javac`"
if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then
# readlink(1) is not available as standard on Solaris 10.
readLink=`which readlink`
if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then
if $darwin ; then
javaHome="`dirname \"$javaExecutable\"`"
javaExecutable="`cd \"$javaHome\" && pwd -P`/javac"
else
javaExecutable="`readlink -f \"$javaExecutable\"`"
fi
javaHome="`dirname \"$javaExecutable\"`"
javaHome=`expr "$javaHome" : '\(.*\)/bin'`
JAVA_HOME="$javaHome"
export JAVA_HOME
fi
fi
fi
if [ -z "$JAVACMD" ] ; then
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
else
JAVACMD="`which java`"
fi
fi
if [ ! -x "$JAVACMD" ] ; then
echo "Error: JAVA_HOME is not defined correctly." >&2
echo " We cannot execute $JAVACMD" >&2
exit 1
fi
if [ -z "$JAVA_HOME" ] ; then
echo "Warning: JAVA_HOME environment variable is not set."
fi
CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher
# traverses directory structure from process work directory to filesystem root
# first directory with .mvn subdirectory is considered project base directory
find_maven_basedir() {
if [ -z "$1" ]
then
echo "Path not specified to find_maven_basedir"
return 1
fi
basedir="$1"
wdir="$1"
while [ "$wdir" != '/' ] ; do
if [ -d "$wdir"/.mvn ] ; then
basedir=$wdir
break
fi
# workaround for JBEAP-8937 (on Solaris 10/Sparc)
if [ -d "${wdir}" ]; then
wdir=`cd "$wdir/.."; pwd`
fi
# end of workaround
done
echo "${basedir}"
}
# concatenates all lines of a file
concat_lines() {
if [ -f "$1" ]; then
echo "$(tr -s '\n' ' ' < "$1")"
fi
}
BASE_DIR=`find_maven_basedir "$(pwd)"`
if [ -z "$BASE_DIR" ]; then
exit 1;
fi
##########################################################################################
# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
# This allows using the maven wrapper in projects that prohibit checking in binary data.
##########################################################################################
if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then
if [ "$MVNW_VERBOSE" = true ]; then
echo "Found .mvn/wrapper/maven-wrapper.jar"
fi
else
if [ "$MVNW_VERBOSE" = true ]; then
echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..."
fi
jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.4.2/maven-wrapper-0.4.2.jar"
while IFS="=" read key value; do
case "$key" in (wrapperUrl) jarUrl="$value"; break ;;
esac
done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties"
if [ "$MVNW_VERBOSE" = true ]; then
echo "Downloading from: $jarUrl"
fi
wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar"
if command -v wget > /dev/null; then
if [ "$MVNW_VERBOSE" = true ]; then
echo "Found wget ... using wget"
fi
wget "$jarUrl" -O "$wrapperJarPath"
elif command -v curl > /dev/null; then
if [ "$MVNW_VERBOSE" = true ]; then
echo "Found curl ... using curl"
fi
curl -o "$wrapperJarPath" "$jarUrl"
else
if [ "$MVNW_VERBOSE" = true ]; then
echo "Falling back to using Java to download"
fi
javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java"
if [ -e "$javaClass" ]; then
if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
if [ "$MVNW_VERBOSE" = true ]; then
echo " - Compiling MavenWrapperDownloader.java ..."
fi
# Compiling the Java class
("$JAVA_HOME/bin/javac" "$javaClass")
fi
if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
# Running the downloader
if [ "$MVNW_VERBOSE" = true ]; then
echo " - Running MavenWrapperDownloader.java ..."
fi
("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR")
fi
fi
fi
fi
##########################################################################################
# End of extension
##########################################################################################
export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}
if [ "$MVNW_VERBOSE" = true ]; then
echo $MAVEN_PROJECTBASEDIR
fi
MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS"
# For Cygwin, switch paths to Windows format before running java
if $cygwin; then
[ -n "$M2_HOME" ] &&
M2_HOME=`cygpath --path --windows "$M2_HOME"`
[ -n "$JAVA_HOME" ] &&
JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"`
[ -n "$CLASSPATH" ] &&
CLASSPATH=`cygpath --path --windows "$CLASSPATH"`
[ -n "$MAVEN_PROJECTBASEDIR" ] &&
MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"`
fi
WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
exec "$JAVACMD" \
$MAVEN_OPTS \
-classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \
"-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@"

View File

@@ -0,0 +1,161 @@
@REM ----------------------------------------------------------------------------
@REM Licensed to the Apache Software Foundation (ASF) under one
@REM or more contributor license agreements. See the NOTICE file
@REM distributed with this work for additional information
@REM regarding copyright ownership. The ASF licenses this file
@REM to you under the Apache License, Version 2.0 (the
@REM "License"); you may not use this file except in compliance
@REM with the License. You may obtain a copy of the License at
@REM
@REM http://www.apache.org/licenses/LICENSE-2.0
@REM
@REM Unless required by applicable law or agreed to in writing,
@REM software distributed under the License is distributed on an
@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
@REM KIND, either express or implied. See the License for the
@REM specific language governing permissions and limitations
@REM under the License.
@REM ----------------------------------------------------------------------------
@REM ----------------------------------------------------------------------------
@REM Maven2 Start Up Batch script
@REM
@REM Required ENV vars:
@REM JAVA_HOME - location of a JDK home dir
@REM
@REM Optional ENV vars
@REM M2_HOME - location of maven2's installed home dir
@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending
@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
@REM e.g. to debug Maven itself, use
@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
@REM ----------------------------------------------------------------------------
@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
@echo off
@REM set title of command window
title %0
@REM enable echoing my setting MAVEN_BATCH_ECHO to 'on'
@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO%
@REM set %HOME% to equivalent of $HOME
if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
@REM Execute a user defined script before this one
if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
@REM check for pre script, once with legacy .bat ending and once with .cmd ending
if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat"
if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd"
:skipRcPre
@setlocal
set ERROR_CODE=0
@REM To isolate internal variables from possible post scripts, we use another setlocal
@setlocal
@REM ==== START VALIDATION ====
if not "%JAVA_HOME%" == "" goto OkJHome
echo.
echo Error: JAVA_HOME not found in your environment. >&2
echo Please set the JAVA_HOME variable in your environment to match the >&2
echo location of your Java installation. >&2
echo.
goto error
:OkJHome
if exist "%JAVA_HOME%\bin\java.exe" goto init
echo.
echo Error: JAVA_HOME is set to an invalid directory. >&2
echo JAVA_HOME = "%JAVA_HOME%" >&2
echo Please set the JAVA_HOME variable in your environment to match the >&2
echo location of your Java installation. >&2
echo.
goto error
@REM ==== END VALIDATION ====
:init
@REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
@REM Fallback to current working directory if not found.
set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
set EXEC_DIR=%CD%
set WDIR=%EXEC_DIR%
:findBaseDir
IF EXIST "%WDIR%"\.mvn goto baseDirFound
cd ..
IF "%WDIR%"=="%CD%" goto baseDirNotFound
set WDIR=%CD%
goto findBaseDir
:baseDirFound
set MAVEN_PROJECTBASEDIR=%WDIR%
cd "%EXEC_DIR%"
goto endDetectBaseDir
:baseDirNotFound
set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
cd "%EXEC_DIR%"
:endDetectBaseDir
IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
@setlocal EnableExtensions EnableDelayedExpansion
for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
:endReadAdditionalConfig
SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar"
set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.4.2/maven-wrapper-0.4.2.jar"
FOR /F "tokens=1,2 delims==" %%A IN (%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties) DO (
IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B
)
@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
@REM This allows using the maven wrapper in projects that prohibit checking in binary data.
if exist %WRAPPER_JAR% (
echo Found %WRAPPER_JAR%
) else (
echo Couldn't find %WRAPPER_JAR%, downloading it ...
echo Downloading from: %DOWNLOAD_URL%
powershell -Command "(New-Object Net.WebClient).DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"
echo Finished downloading %WRAPPER_JAR%
)
@REM End of extension
%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %*
if ERRORLEVEL 1 goto error
goto end
:error
set ERROR_CODE=1
:end
@endlocal & set ERROR_CODE=%ERROR_CODE%
if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost
@REM check for post script, once with legacy .bat ending and once with .cmd ending
if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat"
if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd"
:skipRcPost
@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
if "%MAVEN_BATCH_PAUSE%" == "on" pause
if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE%
exit /B %ERROR_CODE%

View File

@@ -0,0 +1,95 @@
<?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>
<groupId>com.yexuejc.springboot</groupId>
<artifactId>springboot-security-login-simple</artifactId>
<version>0.0.1</version>
<packaging>jar</packaging>
<name>springboot-security-login-simple</name>
<description>
https://gitee.com/incloudcode/yexuejc-springboot使用例子
</description>
<properties>
<yexuejc-springboot.version>${parent.version}</yexuejc-springboot.version>
</properties>
<parent>
<groupId>com.yexuejc.springboot</groupId>
<artifactId>yexuejc-springboot-parent</artifactId>
<version>2.1.3</version>
</parent>
<dependencies>
<!--base 引用-->
<dependency>
<groupId>com.yexuejc.springboot</groupId>
<artifactId>yexuejc-springboot-base</artifactId>
<version>${parent.version}</version>
</dependency>
<!--https://gitee.com/incloudcode/yexuejc-base.git-->
<dependency>
<groupId>top.yexuejc</groupId>
<artifactId>yexuejc-base</artifactId>
</dependency>
<!-- 使用springMVC -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Spring Security -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<!-- JJWT -->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-api</artifactId>
<optional>true</optional>
</dependency>
<!-- 使用Redis -->
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</dependency>
<!-- HikariCP数据库连接池JDK1.8 -->
<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
</dependency>
<!-- springboot mybatis-plus-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
</dependency>
<!-- 内存数据库h2-->
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 63 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 70 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 69 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 240 KiB

View File

@@ -0,0 +1,12 @@
package com.example.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}

View File

@@ -0,0 +1,39 @@
package com.example.demo.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import com.example.demo.security.domain.Consumer;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
/**
* <p>
* Mapper 接口
* </p>
*
* @author yexuejc
* @since 2018-05-27
*/
@Mapper
public interface ConsumerMapper extends BaseMapper<Consumer> {
/**
* <p>
* 插入一条记录
* </p>
*
* @param entity 实体对象
* @return int
*/
@Override
int insert(Consumer entity);
/**
* 修改权限
*
* @param entity
* @return
*/
Integer updateRoles(@Param(Constants.ENTITY) Consumer entity);
}

View File

@@ -0,0 +1,53 @@
package com.example.demo.mapper.handler;
import com.yexuejc.base.util.JsonUtil;
import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.MappedTypes;
import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
/**
* 数据库查询转换 -> JSON
*/
@MappedTypes({Object.class})
public class JsonTypeHandler extends BaseTypeHandler<Object> {
@Override
public void setNonNullParameter(PreparedStatement ps, int i, Object parameter, JdbcType jdbcType)
throws SQLException {
if (parameter == null) {
ps.setString(i, null);
} else {
ps.setString(i, JsonUtil.obj2Json(parameter));
}
}
@Override
public Object getNullableResult(ResultSet rs, String columnName) throws SQLException {
if (rs.getString(columnName) == null) {
return null;
}
return JsonUtil.json2Obj(rs.getString(columnName), Object.class);
}
@Override
public Object getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
if (rs.getString(columnIndex) == null) {
return null;
}
return JsonUtil.json2Obj(rs.getString(columnIndex), Object.class);
}
@Override
public Object getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
if (cs.getString(columnIndex) == null) {
return null;
}
return JsonUtil.json2Obj(cs.getString(columnIndex), Object.class);
}
}

View File

@@ -0,0 +1,224 @@
package com.example.demo.security;
import com.yexuejc.base.constant.RespsConsts;
import com.yexuejc.base.http.Resps;
import com.yexuejc.base.util.JsonUtil;
import com.yexuejc.base.util.JwtUtil;
import com.yexuejc.base.util.RegexUtil;
import com.yexuejc.base.util.StrUtil;
import com.yexuejc.springboot.base.autoconfigure.MutiRedisAutoConfiguration;
import com.yexuejc.springboot.base.constant.BizConsts;
import com.yexuejc.springboot.base.exception.ThirdPartyAuthorizationException;
import com.yexuejc.springboot.base.exception.UserNotAuthoriayException;
import com.yexuejc.springboot.base.security.ConsumerAuthenticationProcessingFilter;
import com.yexuejc.springboot.base.security.ConsumerUser;
import com.yexuejc.springboot.base.security.LoginToken;
import com.yexuejc.springboot.base.security.SecurityConfig;
import com.yexuejc.springboot.base.security.inte.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.HttpStatus;
import org.springframework.security.authentication.*;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.web.context.SecurityContextRepository;
import java.util.*;
import java.util.concurrent.TimeUnit;
/**
* @author maxf
* @version 1.0
* @ClassName SecurityConfig
* @Description
* @date 2018/11/8 17:30
*/
@EnableWebSecurity(debug = false)
public class MySecurityConfig extends SecurityConfig {
@Autowired
@Qualifier("userserviceimpl")
UserService userService;
@Override
protected UserService getUserService() {
return userService;
}
@Autowired
@Qualifier(MutiRedisAutoConfiguration.BEAN_REDIS_TEMPLATE0)
private RedisTemplate<Object, Object> redisTemplate0;
@Override
protected RedisTemplate<Object, Object> getRedisDB() {
return redisTemplate0;
}
//自定义==================================================================
@Override
protected AuthenticationProvider createConsumerAuthenticationProvider(UserDetailsService userDetailsService) {
return super.createConsumerAuthenticationProvider(userDetailsService);
}
@Override
protected ConsumerAuthenticationProcessingFilter createConsumerAuthenticationProcessingFilter(AuthenticationManager authenticationManager) {
return super.createConsumerAuthenticationProcessingFilter(authenticationManager);
}
@Override
protected SecurityContextRepository createConsumerSecurityContextRepository() {
return super.createConsumerSecurityContextRepository();
}
@Override
protected UserDetailsService createUserDetailsManager() {
return super.createUserDetailsManager();
}
//自定义==================================================================
/**
* 保存登录信息至redis
*
* @param redisTemplate0 redis 链接
* @param user 登录用户
* @param roles 角色信息
* @param token 登录token
* @param isPast 是否设置过期
*/
private void saveLoginUser(RedisTemplate<Object, Object> redisTemplate0, ConsumerUser user, List<String> roles, String token,
boolean isPast) {
Map<String, Object> m = new HashMap<>(4);
m.put("username", user.getUsername());
m.put("token", token);
m.put("roles", roles);
m.put("id", user.getId());
m.put("logType", user.getLogType());
m.put("logTime", user.getLogTime());
redisTemplate0.opsForHash().putAll(BizConsts.CONSUMER_LOGIN_REDIS + "." + user.getUsername(), m);
if (isPast) {
//对于没有绑定手机号的token10分钟后过期
redisTemplate0.expire(BizConsts.CONSUMER_LOGIN_REDIS + "." + user.getUsername(), 10, TimeUnit.MINUTES);
}
}
/**
* <pre>
* 处理登录
* 成功: filter.setAuthenticationSuccessHandler()
* 失败: filter.setAuthenticationFailureHandler()
* </pre>
*
* @param filter
*/
@Override
protected void loginHodler(ConsumerAuthenticationProcessingFilter filter) {
filter.setAuthenticationSuccessHandler((request, response, authentication) -> {
String token = JwtUtil.instace().compact(new LoginToken(authentication.getName()));
ConsumerUser user = (ConsumerUser) authentication.getPrincipal();
Collection<? extends GrantedAuthority> authorities = authentication.getAuthorities();
List<String> roles = new ArrayList<>();
if (authorities != null && authorities.size() > 0) {
for (GrantedAuthority g : authorities) {
roles.add(g.getAuthority());
}
}
Map<String, Object> map = new HashMap<>(2);
map.put("token", token);
map.put("bindMobile", false);
if (StrUtil.isEmpty(user.getUsername()) || !RegexUtil.regex(user.getUsername(), RegexUtil.REGEX_MOBILE)) {
map.put("bindMobile", true);
}
saveLoginUser(redisTemplate0, user, roles, token, (Boolean) map.get("bindMobile"));
response.setContentType("application/json;charset=UTF-8");
response.getWriter().write(JsonUtil.obj2Json(Resps.success().setSucc(map)));
response.getWriter().close();
});
filter.setAuthenticationFailureHandler((request, response, exception) -> {
response.setContentType("application/json;charset=UTF-8");
response.setStatus(HttpStatus.UNAUTHORIZED.value());
Resps resps = new Resps();
if (exception instanceof DisabledException) {
resps.setErr(RespsConsts.CODE_FAIL, new String[]{BizConsts.BASE_IS_LOCK_MSG});
} else if (exception instanceof AccountExpiredException) {
resps.setErr(RespsConsts.CODE_FAIL, new String[]{BizConsts.BASE_IS_EXPIRE_MSG});
} else if (exception instanceof CredentialsExpiredException) {
resps.setErr(BizConsts.BASE_LOGIN_IS_EXPIRE_CODE, new String[]{BizConsts.BASE_LOGIN_IS_EXPIRE_MSG});
} else if (exception instanceof LockedException) {
resps.setErr(RespsConsts.CODE_FAIL, new String[]{BizConsts.BASE_IS_LOCKED_MSG});
} else if (exception instanceof AuthenticationCredentialsNotFoundException) {
resps.setErr(RespsConsts.CODE_FAIL, new String[]{BizConsts.BASE_CREDENTIALS_NOT_FOUND_MSG});
} else if (exception instanceof ThirdPartyAuthorizationException) {
resps.setErr(RespsConsts.CODE_FAIL, new String[]{exception.getMessage()});
} else if (exception instanceof BadCredentialsException) {
resps.setErr(RespsConsts.CODE_FAIL, new String[]{BizConsts.BASE_PWD_IS_ERR_MSG});
} else if (exception instanceof UsernameNotFoundException) {
resps.setErr(RespsConsts.CODE_FAIL, new String[]{BizConsts.BASE_ACCOUNT_NOT_FOUND_MSG});
} else if (exception instanceof UserNotAuthoriayException) {
resps.setErr(RespsConsts.CODE_FAIL, new String[]{exception.getMessage()});
} else {
resps.setErr(RespsConsts.CODE_FAIL, new String[]{BizConsts.BASE_SYS_ERR_MSG});
}
response.getWriter().write(JsonUtil.obj2Json(resps));
response.getWriter().close();
});
}
@Override
protected void configure(HttpSecurity http) throws Exception {
super.configure(http);
http.headers().frameOptions().disable();
/**
* 权限控制
* ->无权限
*/
http.authorizeRequests().antMatchers(
"/", "/index"
).permitAll();
/**
* 权限控制
* ->登录可访问
*/
http.authorizeRequests().antMatchers(
"/consumer/**", "/sms/bind/**").authenticated();
// 登出处理。
http.logout().logoutSuccessHandler((request, response, authentication) -> {
redisTemplate0.delete(BizConsts.CONSUMER_LOGIN_REDIS + "." + authentication.getName());
response.setContentType("application/json;charset=UTF-8");
response.getWriter().write(JsonUtil.obj2Json(Resps.success()));
response.getWriter().close();
});
// 未登录,却访问需要登录的接口时的处理
http.exceptionHandling().authenticationEntryPoint((request, response, authException) -> {
response.setContentType("application/json;charset=UTF-8");
response.setStatus(401);
response.getWriter().write(
JsonUtil.obj2Json(
Resps.error(RespsConsts.CODE_FAIL, new String[]{BizConsts.BASE_NOT_LOGIN_MSG})
)
);
response.getWriter().close();
});
// 已登录,但当前用户没有访问的某个接口的权限时的处理
http.exceptionHandling().accessDeniedHandler((request, response, accessDeniedException) -> {
response.setContentType("application/json;charset=UTF-8");
response.setStatus(401);
response.getWriter().write(
JsonUtil.obj2Json(
Resps.error(RespsConsts.CODE_FAIL, new String[]{BizConsts.BASE_NOT_ROLE_MSG})
)
);
response.getWriter().close();
});
}
}

View File

@@ -0,0 +1,279 @@
package com.example.demo.security.domain;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.extension.activerecord.Model;
import com.example.demo.mapper.handler.JsonTypeHandler;
import com.yexuejc.base.util.JsonUtil;
import com.yexuejc.springboot.base.security.inte.User;
import java.io.Serializable;
import java.util.List;
/**
* <p>
* <p>
* </p>
*
* @author yexuejc
* @since 2018-05-27
*/
@TableName(resultMap = "BaseResultMap")
public class Consumer extends Model<Consumer> implements User {
private static final long serialVersionUID = 1L;
/**
* 用户id
*/
@TableId(value = "consumer_id", type = IdType.ASSIGN_UUID)
private String consumerId;
/**
* 手机号
*/
@TableField("mobile")
private String mobile;
/**
* 密码md5
*/
@TableField("pwd")
private String pwd;
/**
* 账号是否启用
*/
@TableField("is_enable")
private boolean enable;
/**
* 账号是否没有过期
*/
@TableField("is_non_expire")
private boolean nonExpire;
/**
* 账号是否没有被锁定
*/
@TableField("is_non_lock")
private boolean nonLock;
/**
* 微信id
*/
@TableField("wechat_id")
private String wechatId;
/**
* qq id
*/
@TableField("qq_id")
private String qqId;
/**
* 微博id
*/
@TableField("weibo_id")
private String weiboId;
/**
* 昵称
*/
@TableField("nickname")
private String nickname;
/**
* 用户头像
*/
@TableField("head")
private String head;
/**
* 用户邮箱
*/
@TableField("email")
private String email;
/**
* 用户姓别 '男',‘女’
*/
@TableField("sex")
private String sex;
/**
* 角色、权限
*/
@TableField(value = "roles", typeHandler = JsonTypeHandler.class)
private List<String> roles;
/**
* 支付密码
*/
@TableField("pay_pwd")
private String payPwd;
/**
* 注册方式
*/
@TableField("reg_type")
private String regType;
/**
* 第三方源头像路径
*/
@TableField("source_head")
private String sourceHead;
@Override
public String toString() {
return JsonUtil.obj2Json(this);
}
public String getConsumerId() {
return consumerId;
}
public Consumer setConsumerId(String consumerId) {
this.consumerId = consumerId;
return this;
}
public String getMobile() {
return mobile;
}
public Consumer setMobile(String mobile) {
this.mobile = mobile;
return this;
}
public String getPwd() {
return pwd;
}
@Override
public boolean getEnable() {
return this.enable;
}
@Override
public boolean getNonExpire() {
return this.nonExpire;
}
@Override
public boolean getNonLock() {
return this.nonLock;
}
public Consumer setPwd(String pwd) {
this.pwd = pwd;
return this;
}
public Consumer setEnable(boolean enable) {
this.enable = enable;
return this;
}
public Consumer setNonExpire(boolean nonExpire) {
this.nonExpire = nonExpire;
return this;
}
public Consumer setNonLock(boolean nonLock) {
this.nonLock = nonLock;
return this;
}
public String getWechatId() {
return wechatId;
}
public Consumer setWechatId(String wechatId) {
this.wechatId = wechatId;
return this;
}
public String getQqId() {
return qqId;
}
public Consumer setQqId(String qqId) {
this.qqId = qqId;
return this;
}
public String getWeiboId() {
return weiboId;
}
public Consumer setWeiboId(String weiboId) {
this.weiboId = weiboId;
return this;
}
public String getNickname() {
return nickname;
}
public Consumer setNickname(String nickname) {
this.nickname = nickname;
return this;
}
public String getHead() {
return head;
}
public Consumer setHead(String head) {
this.head = head;
return this;
}
public String getEmail() {
return email;
}
public Consumer setEmail(String email) {
this.email = email;
return this;
}
public String getSex() {
return sex;
}
public Consumer setSex(String sex) {
this.sex = sex;
return this;
}
public List<String> getRoles() {
return roles;
}
public Consumer setRoles(List<String> roles) {
this.roles = roles;
return this;
}
public String getPayPwd() {
return payPwd;
}
public Consumer setPayPwd(String payPwd) {
this.payPwd = payPwd;
return this;
}
public String getRegType() {
return regType;
}
public Consumer setRegType(String regType) {
this.regType = regType;
return this;
}
public String getSourceHead() {
return sourceHead;
}
public Consumer setSourceHead(String sourceHead) {
this.sourceHead = sourceHead;
return this;
}
@Override
public Serializable pkVal() {
return this.consumerId;
}
}

View File

@@ -0,0 +1,383 @@
package com.example.demo.security.service;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.example.demo.mapper.ConsumerMapper;
import com.example.demo.security.domain.Consumer;
import com.yexuejc.base.constant.RespsConsts;
import com.yexuejc.base.pojo.ApiVO;
import com.yexuejc.base.util.StrUtil;
import com.yexuejc.springboot.base.autoconfigure.MutiRedisAutoConfiguration;
import com.yexuejc.springboot.base.constant.BizConsts;
import com.yexuejc.springboot.base.constant.DictRegTypeConsts;
import com.yexuejc.springboot.base.constant.LogTypeConsts;
import com.yexuejc.springboot.base.exception.ThirdPartyAuthorizationException;
import com.yexuejc.springboot.base.security.ConsumerToken;
import com.yexuejc.springboot.base.security.ConsumerUser;
import com.yexuejc.springboot.base.security.inte.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
/**
* 数据库操作DB
*
* @author maxf
* @version 1.0
* @ClassName UserServiceImpl
* @Description
* @date 2018/11/8 17:31
*/
@Service("userserviceimpl")
public class UserServiceImpl implements UserService {
@Autowired
ConsumerMapper consumerMapper;
@Autowired
@Qualifier(MutiRedisAutoConfiguration.BEAN_REDIS_TEMPLATE1)
private RedisTemplate<Object, Object> redisTemplate;
/**
* 根据用户名到数据库查询用户
*
* @param username 登录账号
* @return
*/
@Override
public Object getConsumerByUserName(String username) {
if (StrUtil.isEmpty(username)) {
throw new UsernameNotFoundException("username为空一般是第三方登录来的直接抛出UsernameNotFoundException就是");
}
QueryWrapper queryWrapper = new QueryWrapper();
queryWrapper.eq("mobile", username);
Consumer consumer = consumerMapper.selectOne(queryWrapper);
if (null == consumer) {
/**
* 1.抛出UsernameNotFoundException这个异常如果是第三方登录会走 {@link #checkOpenId(ConsumerToken)}
* 2.抛出其他Exception可以自己到{@link MySecurityConfig#loginHodler(ConsumerAuthenticationProcessingFilter)}
* 里面的filter.setAuthenticationFailureHandler()中做特殊处理
*/
throw new UsernameNotFoundException("没有该账号相关信息");
}
//h2不支持json人为处理角色
ArrayList roles = new ArrayList<>();
roles.add("ROLE_CONSUMER");
consumer.setRoles(roles);
//1.consumer为User的实现类
// return consumer;
//2. 自己创建ConsumerUser直接返回
List<GrantedAuthority> authorities = new ArrayList<>();
for (String role : consumer.getRoles()) {
authorities.add(new SimpleGrantedAuthority(role));
}
ConsumerUser consumerUser = new ConsumerUser(consumer.getMobile(), consumer.getPwd(),
consumer.getEnable(), consumer.getNonExpire(), true, consumer.getNonLock(),
authorities, consumer.getConsumerId(), null, System.currentTimeMillis());
return consumerUser;
}
/**
* 到自己的reids里面校验短信验证码
*
* @param smsType {@linkplain BizConsts.CONSUMER_LOGIN_SMS} 业务id reids使用
* @param mobile 登录账号
* @param code 短信验证码
* @return
*/
@Override
public ApiVO checkSmsCode2Redis(String smsType, String mobile, String code) {
redisTemplate.afterPropertiesSet();
String rCode = (String) redisTemplate.opsForHash().get(smsType + "." + mobile, "code");
Integer validatedNums = (Integer) redisTemplate.opsForHash().get(smsType + "." + mobile, "validatedNums");
if (validatedNums == null) {
return new ApiVO(ApiVO.STATUS.F, RespsConsts.CODE_FAIL, "验证码过期,请重新获取");
} else if (validatedNums > 5) {
redisTemplate.delete(smsType + "." + mobile);
return new ApiVO(ApiVO.STATUS.F, RespsConsts.CODE_FAIL, "验证码过期,请重新获取");
}
if (code.equals(rCode)) {
redisTemplate.delete(smsType + "." + mobile);
return new ApiVO(ApiVO.STATUS.S);
} else {
validatedNums++;
redisTemplate.opsForHash().put(smsType + "." + mobile, "validatedNums", validatedNums);
return new ApiVO(ApiVO.STATUS.F, RespsConsts.CODE_FAIL, "验证码不正确");
}
}
/**
* 第三方登录
* 校验openid 根据自己业务做判断
*
* @param consumerToken 登录信息
* @return
*/
@Override
public Object checkOpenId(ConsumerToken consumerToken) {
ApiVO apiVO = new ApiVO(ApiVO.STATUS.F, "没有找到用户信息");
switch (consumerToken.getLogtype()) {
case LogTypeConsts.QQ:
apiVO = checkOpenid4QQ(consumerToken, true);
break;
case LogTypeConsts.WECHAT:
apiVO = checkOpenid4Wechat(consumerToken, true);
break;
case LogTypeConsts.WEIBO:
apiVO = checkOpenid4Weibo(consumerToken, true);
break;
default:
break;
}
if (apiVO.isFail()) {
/**
* 未查到:
* 1.返回null会走数据库没有这个openid[第三方账号]信息)新增流程 {@link #addConsumer(ConsumerToken)}
* 2.也可以自己创建一个带有特殊标识的ConsumerUser然后在 {@link MySecurityConfig#loginHodler(ConsumerAuthenticationProcessingFilter)}
* 里面的filter.setAuthenticationSuccessHandler()中做特殊处理 ps:假装登录成功 :)
*/
return null;
}
//h2不支持json人为处理角色
ArrayList roles = new ArrayList<>();
roles.add("ROLE_CONSUMER");
apiVO.getObject1(Consumer.class).setRoles(roles);
//根据openid到数据库查到consumer返回
return apiVO.getObject1(Consumer.class);
}
/**
* {@link #checkOpenId(ConsumerToken)} 返回null会走该方法
* 没有账号时处理自己的业务,此处必须返回 构造出的登录用户,否则会抛出{@link ThirdPartyAuthorizationException 第三方授权异常}
* <br/>
*
* @param consumerToken 登录信息
* @return
*/
@Override
public Object addConsumer(ConsumerToken consumerToken) {
Consumer consumer = new Consumer();
consumer.setConsumerId(StrUtil.genUUID());
consumer.setMobile(StrUtil.isNotEmpty(consumerToken.getUsername()) ? consumerToken.getUsername() : consumerToken.getOpenid());
consumer.setPwd(StrUtil.toMD5("123456"));
consumer.setEnable(true);
consumer.setNonExpire(true);
consumer.setNonLock(true);
List<String> roles = new ArrayList<>();
roles.add("ROLE_CONSUMER");
consumer.setRoles(roles);
switch (consumerToken.getLogtype()) {
case LogTypeConsts.SMS:
ApiVO apiVO = checkSmsCode2Redis(BizConsts.CONSUMER_LOGIN_SMS, consumerToken.getUsername(),
consumerToken.getSmscode());
if (apiVO.isFail()) {
throw new ThirdPartyAuthorizationException("短信验证码错误");
}
consumer.setNickname(consumerToken.getUsername());
consumer.setHead("/head/def.png");
consumer.setRegType(DictRegTypeConsts.DICT_MOBILE);
break;
case LogTypeConsts.QQ:
consumer.setQqId(consumerToken.getOpenid());
consumer.setNickname(consumerToken.getNickname());
setHeader(consumerToken, consumer, false);
setSex(consumerToken, consumer);
consumer.setRegType(DictRegTypeConsts.DICT_QQ);
break;
case LogTypeConsts.WECHAT:
consumer.setWechatId(consumerToken.getOpenid());
consumer.setNickname(consumerToken.getNickname());
setHeader(consumerToken, consumer, false);
setSex(consumerToken, consumer);
consumer.setRegType(DictRegTypeConsts.DICT_WECHAT);
break;
case LogTypeConsts.WEIBO:
consumer.setWeiboId(consumerToken.getOpenid());
consumer.setNickname(consumerToken.getNickname());
setHeader(consumerToken, consumer, false);
setSex(consumerToken, consumer);
consumer.setRegType(DictRegTypeConsts.DICT_WEIBO);
break;
default:
throw new ThirdPartyAuthorizationException("暂不支持该第三方授权");
}
Integer result = consumerMapper.insert(consumer);
if (result < 1) {
/**
* 会抛出{@link ThirdPartyAuthorizationException 第三方授权异常}
*/
return null;
}
return consumer;
}
/**
* 第三方登录 QQ登录
*
* @param consumerToken 登录信息
* @param b
* @return
*/
public ApiVO checkOpenid4QQ(ConsumerToken consumerToken, boolean b) {
Consumer consumer = getConsumerByQQOpenid(consumerToken.getOpenid());
if (consumer == null) {
return new ApiVO(ApiVO.STATUS.F, "获取用户信息失败");
}
if (b && DictRegTypeConsts.DICT_QQ.equals(consumer.getRegType())) {
//如果是qq注册的登录的同时更新用户信息
updateConsumer(consumer, consumerToken);
}
return new ApiVO(ApiVO.STATUS.S).setObject1(consumer);
}
/**
* 第三方登录 微信登录
*
* @param consumerToken 登录信息
* @param b
* @return
*/
public ApiVO checkOpenid4Wechat(ConsumerToken consumerToken, boolean b) {
Consumer consumer = getConsumerByWechatOpenid(consumerToken.getOpenid());
if (consumer == null) {
return new ApiVO(ApiVO.STATUS.F, "获取用户信息失败");
}
if (b && DictRegTypeConsts.DICT_WECHAT.equals(consumer.getRegType())) {
//如果是微信注册的,登录的同时更新用户信息
updateConsumer(consumer, consumerToken);
}
return new ApiVO(ApiVO.STATUS.S).setObject1(consumer);
}
/**
* 第三方登录 微博登录
*
* @param consumerToken 登录信息
* @param b
* @return
*/
public ApiVO checkOpenid4Weibo(ConsumerToken consumerToken, boolean b) {
Consumer consumer = getConsumerByWeiboOpenid(consumerToken.getOpenid());
if (consumer == null) {
return new ApiVO(ApiVO.STATUS.F, "获取用户信息失败");
}
if (b && DictRegTypeConsts.DICT_WEIBO.equals(consumer.getRegType())) {
//如果是微博注册的,登录的同时更新用户信息
updateConsumer(consumer, consumerToken);
}
return new ApiVO(ApiVO.STATUS.S).setObject1(consumer);
}
public Consumer getConsumerByQQOpenid(String openid) {
QueryWrapper queryWrapper = new QueryWrapper<>();
queryWrapper.eq("qq_id", openid);
Consumer consumer = consumerMapper.selectOne(queryWrapper);
return consumer;
}
public Consumer getConsumerByWechatOpenid(String openid) {
QueryWrapper queryWrapper = new QueryWrapper<>();
queryWrapper.eq("wechat_id", openid);
Consumer consumer = consumerMapper.selectOne(queryWrapper);
return consumer;
}
public Consumer getConsumerByWeiboOpenid(String openid) {
QueryWrapper queryWrapper = new QueryWrapper<>();
queryWrapper.eq("weibo_id", openid);
Consumer consumer = consumerMapper.selectOne(queryWrapper);
return consumer;
}
/**
* 更新基本信息
*
* @param consumer
* @param consumerToken
*/
private void updateConsumer(Consumer consumer, ConsumerToken consumerToken) {
boolean b1, b2, b3;
b1 = b2 = b3 = true;
if (StrUtil.isNotEmpty(consumerToken.getNickname())) {
if (consumerToken.getNickname().equals(consumer.getNickname())) {
b1 = false;
}
consumer.setNickname(consumerToken.getNickname());
}
b2 = setHeader(consumerToken, consumer, true);
b3 = setSex(consumerToken, consumer);
if (!b1 && !b2 && !b3) {
return;
}
LambdaUpdateWrapper<Consumer> queryWrapper = new UpdateWrapper<>(new Consumer()).lambda();
try {
queryWrapper.set(Consumer::getNickname, consumer.getNickname())
.set(Consumer::getHead, consumer.getHead())
.set(Consumer::getSex, consumer.getSex())
.eq(Consumer::getConsumerId, consumer.getConsumerId());
consumerMapper.update(new Consumer(), queryWrapper);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 设置头像->上传网络图片到OSS
*
* @param consumerToken
* @param consumer
* @param isUpdate
*/
private boolean setHeader(ConsumerToken consumerToken, Consumer consumer, boolean isUpdate) {
if (StrUtil.isNotEmpty(consumerToken.getHead())) {
if (isUpdate) {
if (consumerToken.getHead().equals(consumer.getSourceHead())) {
//未改变头像
return false;
}
} else {
consumer.setSourceHead(consumerToken.getHead());
}
//应该上传至OSS后返回OSS地址
consumer.setHead(consumerToken.getHead());
// try {
// consumer.setHead(putOss4Head(null, consumerToken.getHead()));
// } catch (ImageException e) {
// return false;
// }
}
return true;
}
/**
* 设置性别
*
* @param consumerToken
* @param consumer
*/
private boolean setSex(ConsumerToken consumerToken, Consumer consumer) {
if (StrUtil.isNotEmpty(consumerToken.getSex())) {
if ("1".equals(consumerToken.getSex()) && !"".equals(consumer.getSex())) {
consumer.setSex("");
return true;
} else if ("2".equals(consumerToken.getSex()) && !"".equals(consumer.getSex())) {
consumer.setSex("");
return true;
}
}
return false;
}
}

View File

@@ -0,0 +1,83 @@
package com.example.demo.web;
import com.yexuejc.base.http.Resps;
import com.yexuejc.base.pojo.ApiVO;
import com.yexuejc.base.util.RegexUtil;
import com.yexuejc.base.util.StrUtil;
import com.yexuejc.springboot.base.autoconfigure.MutiRedisAutoConfiguration;
import com.yexuejc.springboot.base.constant.BizConsts;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
/**
* <pre>
* Security 登录注册相关controller
* 主要实现
* 1.短信登录发送验证码
* 2.第三方登录绑定手机号(以及绑定手机号发送验证码)
* </pre>
*
* @author maxf
* @version 1.0
* @ClassName SecurityCtrl
* @Description
* @date 2018/11/9 10:52
*/
@RestController
public class SecurityCtrl {
@Autowired
@Qualifier(MutiRedisAutoConfiguration.BEAN_REDIS_TEMPLATE1)
RedisTemplate<Object, Object> redisTemplate;
/**
* 登录发送短信
*
* @param mobile
* @return
*/
@RequestMapping(value = "/login/{mobile}", method = RequestMethod.POST)
public Resps login(@PathVariable String mobile) {
if (!RegexUtil.regex(mobile, RegexUtil.REGEX_MOBILE)) {
return Resps.fail("手机号不正确");
}
ApiVO apiVO = sendSmsCode(BizConsts.CONSUMER_LOGIN_SMS, mobile);
if (apiVO.isFail()) {
return Resps.fail(apiVO.getMsg());
}
return Resps.success(apiVO.getMsg());
}
private ApiVO sendSmsCode(String smsType, String mobile) {
String smsId = StrUtil.genUUID(30);
String code = StrUtil.genNum().substring(2, 8);
//自己接入短信发送
boolean result = true;
if (result) {
//成功
//存reids
Map<String, Object> map = new HashMap<>();
map.put("smsId", smsId);
map.put("code", code);
map.put("trade_id", "短信返回id");
map.put("validatedNums", 0);
redisTemplate.afterPropertiesSet();
redisTemplate.opsForHash().putAll(smsType + "." + mobile, map);
// 过期时间5分钟
redisTemplate.expire(smsType + "." + mobile, 5 * 60, TimeUnit.SECONDS);
return new ApiVO(ApiVO.STATUS.S, "短信发送成功");
} else {
return new ApiVO(ApiVO.STATUS.F, "短信发送失败");
}
}
}

View File

@@ -0,0 +1,66 @@
server.port=8545
logging.level.root=info
#========================================================================================================================
#========================================================================================================================
#核心
#开启功能 redis webmvc
yexuejc.autoconfigure.redis.enable=true
#webmvc 包含以下功能
yexuejc.autoconfigure.webmvc.enable=true
#全局异常处理
yexuejc.ssl-ignore.enable=true
#开启HTTPSSSL请求证书验证忽略
yexuejc.global.exception.enable=true
#开启校验过滤器目前校验HTTP Header是否符合规范
yexuejc.web.validation-filter.enable=true
# 拦截类型请求路径0忽略模式默认拦截全部1拦截模式默认一个都不拦截
yexuejc.http.filter=0
#忽略路径示例放开swagger
yexuejc.http.filter.ignored=/,/swagger/**,/error,/v2/api-docs,/webjars/**
#========================================================================================================================
#========================================================================================================================
#========================================================================================================================
# security相关
#reids
#开启指定redis库db0默认开启
yexuejc.redis.db1=true
spring.redis.jedis.pool.max-active=100
spring.redis.jedis.pool.max-idle=10
spring.redis.jedis.pool.min-idle=3
spring.redis.host=192.168.0.107
spring.redis.password=yexuejc2022
spring.redis.port=6379
#db
spring.h2.console.path=/h2-console
spring.h2.console.enabled=true
spring.h2.console.settings.web-allow-others=true
spring.datasource.username=sa
spring.datasource.password=123456
spring.datasource.url=jdbc:h2:mem:test;MODE=PostgreSQL
spring.datasource.driver-class-name=org.h2.Driver
spring.datasource.schema=classpath:db/schema.sql
spring.datasource.data=classpath:db/data.sql
#========================================================================================================================
#mybatis-plus
mybatis-plus.mapper-locations=classpath*:mapper/*.xml
#实体扫描多个package用逗号或者分号分隔
mybatis-plus.type-aliases-package=com.yexuejc.springboot.base.security.domain
#主键类型0:"数据库ID自增", 1:"用户输入ID",2:"该类型为未设置主键类型", 3:"全局唯一ID UUID",4:全局唯一ID (UUID),5:字符串全局唯一ID (idWorker 的字符串表示);
mybatis-plus.global-config.db-config.id-type=uuid
mybatis-plus.global-config.db-config.db-type=POSTGRE_SQL
#字段策略 0:"忽略判断",1:"非 NULL 判断"),2:"非空判断"
mybatis-plus.global-config.db-config.field-strategy=not_empty
#驼峰下划线转换
mybatis-plus.global-config.db-config.column-underline=true
#逻辑删除配置下面3个配置
mybatis-plus.global-config.db-config.logic-delete-value=true
mybatis-plus.global-config.db-config.logic-not-delete-value=false
#配置返回数据库(column下划线命名&&返回java实体是驼峰命名)自动匹配无需as没开启这个SQL需要写as select user_id as userId
mybatis-plus.configuration.map-underscore-to-camel-case=true
mybatis-plus.configuration.cache-enabled=false
#========================================================================================================================

View File

@@ -0,0 +1,34 @@
INSERT INTO consumer (consumer_id,
mobile,
pwd,
is_enable,
is_non_expire,
is_non_lock,
wechat_id,
qq_id,
weibo_id,
nickname,
head,
email,
sex,
roles,
pay_pwd,
reg_type,
source_head)
VALUES ('119d8c62b8b04154a073b3f6c3d9e14f',
'18202837563',
'e10adc3949ba59abbe56e057f20f883e',
't',
't',
't',
'ogIXq0HrDq3kS6MAHqMI1RUqBrGw',
NULL,
NULL,
'18202837563',
'head/6dc93e2e0809426ca8a9e6ede30b0b50.JPEG',
NULL,
'',
'[ROLE_CONSUMER, ROLE_LAYER]',
NULL,
'S',
'https://wx.qlogo.cn/mmopen/vi_32/MftzC3yHluDbjZ9c3sYEibUuXNkC3pha8E6pibZO3Wh0Zop0bqHLcltjmrENc4R8Xm6oJECQGibAxZot1v9PR1hsw/132');

View File

@@ -0,0 +1,42 @@
CREATE TABLE consumer (
consumer_id varchar(32) NOT NULL DEFAULT NULL::character varying,
mobile varchar(50) NOT NULL DEFAULT NULL::character varying,
pwd varchar(32) DEFAULT NULL::character varying,
is_enable bool DEFAULT true,
is_non_expire bool DEFAULT true,
is_non_lock bool DEFAULT true,
wechat_id varchar(50) DEFAULT NULL::character varying,
qq_id varchar(50) DEFAULT NULL::character varying,
weibo_id varchar(50) DEFAULT NULL::character varying,
nickname varchar(50) DEFAULT NULL::character varying,
head varchar(255) DEFAULT NULL::character varying,
email varchar(32) DEFAULT NULL::character varying,
sex varchar(1) DEFAULT NULL::character varying,
roles varchar(255),
pay_pwd varchar(32) DEFAULT NULL::character varying,
reg_type varchar(10) ,
source_head varchar(255)
)
;
COMMENT ON COLUMN consumer.consumer_id IS '用户id';
COMMENT ON COLUMN consumer.mobile IS '手机号';
COMMENT ON COLUMN consumer.pwd IS '密码md5';
COMMENT ON COLUMN consumer.is_enable IS '账号是否启用';
COMMENT ON COLUMN consumer.is_non_expire IS '账号是否没有过期';
COMMENT ON COLUMN consumer.is_non_lock IS '账号是否没有被锁定';
COMMENT ON COLUMN consumer.wechat_id IS '微信id';
COMMENT ON COLUMN consumer.qq_id IS 'qq id';
COMMENT ON COLUMN consumer.weibo_id IS '微博id';
COMMENT ON COLUMN consumer.nickname IS '昵称';
COMMENT ON COLUMN consumer.head IS '用户头像';
COMMENT ON COLUMN consumer.email IS '用户邮箱';
COMMENT ON COLUMN consumer.sex IS '用户姓别 '''',‘女’';
COMMENT ON COLUMN consumer.roles IS '角色、权限';
COMMENT ON COLUMN consumer.pay_pwd IS '支付密码';
COMMENT ON COLUMN consumer.reg_type IS '注册方式';
COMMENT ON COLUMN consumer.source_head IS '第三方源头像路径';
-- ----------------------------
-- Primary Key structure for table consumer
-- ----------------------------
ALTER TABLE consumer ADD CONSTRAINT consumer_pkey PRIMARY KEY (consumer_id);

View File

@@ -0,0 +1,82 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.demo.mapper.ConsumerMapper">
<!-- 通用查询映射结果 -->
<resultMap id="BaseResultMap" type="com.example.demo.security.domain.Consumer">
<id column="consumer_id" property="consumerId"/>
<result column="mobile" property="mobile"/>
<result column="pwd" property="pwd"/>
<result column="is_enable" property="enable"/>
<result column="is_non_expire" property="nonExpire"/>
<result column="is_non_lock" property="nonLock"/>
<result column="wechat_id" property="wechatId"/>
<result column="qq_id" property="qqId"/>
<result column="weibo_id" property="weiboId"/>
<result column="nickname" property="nickname"/>
<result column="head" property="head"/>
<result column="email" property="email"/>
<result column="sex" property="sex"/>
<result column="roles" property="roles"
typeHandler="com.example.demo.mapper.handler.JsonTypeHandler"/>
<result column="pay_pwd" property="payPwd"/>
<result column="reg_type" property="regType"/>
<result column="source_head" property="sourceHead"/>
</resultMap>
<insert id="insert">
INSERT INTO consumer (consumer_id,
mobile,
pwd,
is_enable,
is_non_expire,
is_non_lock,
wechat_id,
qq_id,
weibo_id,
nickname,
head,
email,
sex,
roles,
pay_pwd,
reg_type,
source_head)
VALUES (#{consumerId},
#{mobile},
#{pwd},
#{enable},
#{nonExpire},
#{nonLock},
#{wechatId},
#{qqId},
#{weiboId},
#{nickname},
#{head},
#{email},
#{sex},
#{roles,typeHandler=com.example.demo.mapper.handler.JsonTypeHandler},
#{payPwd},
#{regType},
#{sourceHead});
</insert>
<select id="selectOne" resultMap="BaseResultMap">
select * from consumer
<where>${ew.sqlSegment}</where>
</select>
<update id="updateRoles">
update consumer
<set>
<if test='et.roles!=null'>
roles = #{et.roles,typeHandler=com.example.demo.mapper.handler.JsonTypeHandler},
</if>
mdfy_time=now(),
mdfy_by=#{et.mdfyBy}
</set>
where
consumer_id=#{et.consumerId}
</update>
</mapper>

View File

@@ -0,0 +1,13 @@
package com.example.demo;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
public class DemoApplicationTests {
@Test
public void contextLoads() {
}
}

View File

@@ -0,0 +1,31 @@
HELP.md
target/
!.mvn/wrapper/maven-wrapper.jar
!**/src/main/**
!**/src/test/**
### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
build/
### VS Code ###
.vscode/

View File

@@ -0,0 +1,63 @@
# yexuejc-springboot-simple
### 说明
>本工程是yexuejc-springboot的使用示例新接入请参考本工程
#### 什么都不用
<details>
<summary>直接新建一个springboot工程 pom.xml 配置</summary>
```
<?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.yexuejc.springboot</groupId>
<artifactId>yexuejc-springboot-parent</artifactId>
<version>1.2.1</version>
</parent>
<groupId>top.yexuejc</groupId>
<artifactId>yexuejc-springboot-simple</artifactId>
<version>0.0.1</version>
<name>yexuejc-springboot-simple</name>
<description>测试工程</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>com.yexuejc.springboot</groupId>
<artifactId>yexuejc-springboot-base</artifactId>
<version>1.2.1</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
```
</details>
#### 使用多端登录
参考[使用多端登录](../springboot-security-login-simple/README.md)

View File

@@ -0,0 +1,286 @@
#!/bin/sh
# ----------------------------------------------------------------------------
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
# ----------------------------------------------------------------------------
# ----------------------------------------------------------------------------
# Maven2 Start Up Batch script
#
# Required ENV vars:
# ------------------
# JAVA_HOME - location of a JDK home dir
#
# Optional ENV vars
# -----------------
# M2_HOME - location of maven2's installed home dir
# MAVEN_OPTS - parameters passed to the Java VM when running Maven
# e.g. to debug Maven itself, use
# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
# MAVEN_SKIP_RC - flag to disable loading of mavenrc files
# ----------------------------------------------------------------------------
if [ -z "$MAVEN_SKIP_RC" ] ; then
if [ -f /etc/mavenrc ] ; then
. /etc/mavenrc
fi
if [ -f "$HOME/.mavenrc" ] ; then
. "$HOME/.mavenrc"
fi
fi
# OS specific support. $var _must_ be set to either true or false.
cygwin=false;
darwin=false;
mingw=false
case "`uname`" in
CYGWIN*) cygwin=true ;;
MINGW*) mingw=true;;
Darwin*) darwin=true
# Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home
# See https://developer.apple.com/library/mac/qa/qa1170/_index.html
if [ -z "$JAVA_HOME" ]; then
if [ -x "/usr/libexec/java_home" ]; then
export JAVA_HOME="`/usr/libexec/java_home`"
else
export JAVA_HOME="/Library/Java/Home"
fi
fi
;;
esac
if [ -z "$JAVA_HOME" ] ; then
if [ -r /etc/gentoo-release ] ; then
JAVA_HOME=`java-config --jre-home`
fi
fi
if [ -z "$M2_HOME" ] ; then
## resolve links - $0 may be a link to maven's home
PRG="$0"
# need this for relative symlinks
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG="`dirname "$PRG"`/$link"
fi
done
saveddir=`pwd`
M2_HOME=`dirname "$PRG"`/..
# make it fully qualified
M2_HOME=`cd "$M2_HOME" && pwd`
cd "$saveddir"
# echo Using m2 at $M2_HOME
fi
# For Cygwin, ensure paths are in UNIX format before anything is touched
if $cygwin ; then
[ -n "$M2_HOME" ] &&
M2_HOME=`cygpath --unix "$M2_HOME"`
[ -n "$JAVA_HOME" ] &&
JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
[ -n "$CLASSPATH" ] &&
CLASSPATH=`cygpath --path --unix "$CLASSPATH"`
fi
# For Mingw, ensure paths are in UNIX format before anything is touched
if $mingw ; then
[ -n "$M2_HOME" ] &&
M2_HOME="`(cd "$M2_HOME"; pwd)`"
[ -n "$JAVA_HOME" ] &&
JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`"
# TODO classpath?
fi
if [ -z "$JAVA_HOME" ]; then
javaExecutable="`which javac`"
if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then
# readlink(1) is not available as standard on Solaris 10.
readLink=`which readlink`
if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then
if $darwin ; then
javaHome="`dirname \"$javaExecutable\"`"
javaExecutable="`cd \"$javaHome\" && pwd -P`/javac"
else
javaExecutable="`readlink -f \"$javaExecutable\"`"
fi
javaHome="`dirname \"$javaExecutable\"`"
javaHome=`expr "$javaHome" : '\(.*\)/bin'`
JAVA_HOME="$javaHome"
export JAVA_HOME
fi
fi
fi
if [ -z "$JAVACMD" ] ; then
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
else
JAVACMD="`which java`"
fi
fi
if [ ! -x "$JAVACMD" ] ; then
echo "Error: JAVA_HOME is not defined correctly." >&2
echo " We cannot execute $JAVACMD" >&2
exit 1
fi
if [ -z "$JAVA_HOME" ] ; then
echo "Warning: JAVA_HOME environment variable is not set."
fi
CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher
# traverses directory structure from process work directory to filesystem root
# first directory with .mvn subdirectory is considered project base directory
find_maven_basedir() {
if [ -z "$1" ]
then
echo "Path not specified to find_maven_basedir"
return 1
fi
basedir="$1"
wdir="$1"
while [ "$wdir" != '/' ] ; do
if [ -d "$wdir"/.mvn ] ; then
basedir=$wdir
break
fi
# workaround for JBEAP-8937 (on Solaris 10/Sparc)
if [ -d "${wdir}" ]; then
wdir=`cd "$wdir/.."; pwd`
fi
# end of workaround
done
echo "${basedir}"
}
# concatenates all lines of a file
concat_lines() {
if [ -f "$1" ]; then
echo "$(tr -s '\n' ' ' < "$1")"
fi
}
BASE_DIR=`find_maven_basedir "$(pwd)"`
if [ -z "$BASE_DIR" ]; then
exit 1;
fi
##########################################################################################
# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
# This allows using the maven wrapper in projects that prohibit checking in binary data.
##########################################################################################
if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then
if [ "$MVNW_VERBOSE" = true ]; then
echo "Found .mvn/wrapper/maven-wrapper.jar"
fi
else
if [ "$MVNW_VERBOSE" = true ]; then
echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..."
fi
jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.4.2/maven-wrapper-0.4.2.jar"
while IFS="=" read key value; do
case "$key" in (wrapperUrl) jarUrl="$value"; break ;;
esac
done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties"
if [ "$MVNW_VERBOSE" = true ]; then
echo "Downloading from: $jarUrl"
fi
wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar"
if command -v wget > /dev/null; then
if [ "$MVNW_VERBOSE" = true ]; then
echo "Found wget ... using wget"
fi
wget "$jarUrl" -O "$wrapperJarPath"
elif command -v curl > /dev/null; then
if [ "$MVNW_VERBOSE" = true ]; then
echo "Found curl ... using curl"
fi
curl -o "$wrapperJarPath" "$jarUrl"
else
if [ "$MVNW_VERBOSE" = true ]; then
echo "Falling back to using Java to download"
fi
javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java"
if [ -e "$javaClass" ]; then
if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
if [ "$MVNW_VERBOSE" = true ]; then
echo " - Compiling MavenWrapperDownloader.java ..."
fi
# Compiling the Java class
("$JAVA_HOME/bin/javac" "$javaClass")
fi
if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
# Running the downloader
if [ "$MVNW_VERBOSE" = true ]; then
echo " - Running MavenWrapperDownloader.java ..."
fi
("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR")
fi
fi
fi
fi
##########################################################################################
# End of extension
##########################################################################################
export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}
if [ "$MVNW_VERBOSE" = true ]; then
echo $MAVEN_PROJECTBASEDIR
fi
MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS"
# For Cygwin, switch paths to Windows format before running java
if $cygwin; then
[ -n "$M2_HOME" ] &&
M2_HOME=`cygpath --path --windows "$M2_HOME"`
[ -n "$JAVA_HOME" ] &&
JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"`
[ -n "$CLASSPATH" ] &&
CLASSPATH=`cygpath --path --windows "$CLASSPATH"`
[ -n "$MAVEN_PROJECTBASEDIR" ] &&
MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"`
fi
WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
exec "$JAVACMD" \
$MAVEN_OPTS \
-classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \
"-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@"

View File

@@ -0,0 +1,161 @@
@REM ----------------------------------------------------------------------------
@REM Licensed to the Apache Software Foundation (ASF) under one
@REM or more contributor license agreements. See the NOTICE file
@REM distributed with this work for additional information
@REM regarding copyright ownership. The ASF licenses this file
@REM to you under the Apache License, Version 2.0 (the
@REM "License"); you may not use this file except in compliance
@REM with the License. You may obtain a copy of the License at
@REM
@REM https://www.apache.org/licenses/LICENSE-2.0
@REM
@REM Unless required by applicable law or agreed to in writing,
@REM software distributed under the License is distributed on an
@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
@REM KIND, either express or implied. See the License for the
@REM specific language governing permissions and limitations
@REM under the License.
@REM ----------------------------------------------------------------------------
@REM ----------------------------------------------------------------------------
@REM Maven2 Start Up Batch script
@REM
@REM Required ENV vars:
@REM JAVA_HOME - location of a JDK home dir
@REM
@REM Optional ENV vars
@REM M2_HOME - location of maven2's installed home dir
@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending
@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
@REM e.g. to debug Maven itself, use
@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
@REM ----------------------------------------------------------------------------
@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
@echo off
@REM set title of command window
title %0
@REM enable echoing my setting MAVEN_BATCH_ECHO to 'on'
@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO%
@REM set %HOME% to equivalent of $HOME
if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
@REM Execute a user defined script before this one
if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
@REM check for pre script, once with legacy .bat ending and once with .cmd ending
if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat"
if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd"
:skipRcPre
@setlocal
set ERROR_CODE=0
@REM To isolate internal variables from possible post scripts, we use another setlocal
@setlocal
@REM ==== START VALIDATION ====
if not "%JAVA_HOME%" == "" goto OkJHome
echo.
echo Error: JAVA_HOME not found in your environment. >&2
echo Please set the JAVA_HOME variable in your environment to match the >&2
echo location of your Java installation. >&2
echo.
goto error
:OkJHome
if exist "%JAVA_HOME%\bin\java.exe" goto init
echo.
echo Error: JAVA_HOME is set to an invalid directory. >&2
echo JAVA_HOME = "%JAVA_HOME%" >&2
echo Please set the JAVA_HOME variable in your environment to match the >&2
echo location of your Java installation. >&2
echo.
goto error
@REM ==== END VALIDATION ====
:init
@REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
@REM Fallback to current working directory if not found.
set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
set EXEC_DIR=%CD%
set WDIR=%EXEC_DIR%
:findBaseDir
IF EXIST "%WDIR%"\.mvn goto baseDirFound
cd ..
IF "%WDIR%"=="%CD%" goto baseDirNotFound
set WDIR=%CD%
goto findBaseDir
:baseDirFound
set MAVEN_PROJECTBASEDIR=%WDIR%
cd "%EXEC_DIR%"
goto endDetectBaseDir
:baseDirNotFound
set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
cd "%EXEC_DIR%"
:endDetectBaseDir
IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
@setlocal EnableExtensions EnableDelayedExpansion
for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
:endReadAdditionalConfig
SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar"
set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.4.2/maven-wrapper-0.4.2.jar"
FOR /F "tokens=1,2 delims==" %%A IN (%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties) DO (
IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B
)
@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
@REM This allows using the maven wrapper in projects that prohibit checking in binary data.
if exist %WRAPPER_JAR% (
echo Found %WRAPPER_JAR%
) else (
echo Couldn't find %WRAPPER_JAR%, downloading it ...
echo Downloading from: %DOWNLOAD_URL%
powershell -Command "(New-Object Net.WebClient).DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"
echo Finished downloading %WRAPPER_JAR%
)
@REM End of extension
%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %*
if ERRORLEVEL 1 goto error
goto end
:error
set ERROR_CODE=1
:end
@endlocal & set ERROR_CODE=%ERROR_CODE%
if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost
@REM check for post script, once with legacy .bat ending and once with .cmd ending
if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat"
if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd"
:skipRcPost
@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
if "%MAVEN_BATCH_PAUSE%" == "on" pause
if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE%
exit /B %ERROR_CODE%

View File

@@ -0,0 +1,46 @@
<?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.yexuejc.springboot</groupId>
<artifactId>yexuejc-springboot-parent</artifactId>
<version>2.1.3</version>
</parent>
<groupId>top.yexuejc</groupId>
<artifactId>yexuejc-springboot-simple</artifactId>
<version>0.0.1</version>
<name>yexuejc-springboot-simple</name>
<description>测试工程</description>
<properties>
<yexuejc-springboot.version>${parent.version}</yexuejc-springboot.version>
</properties>
<dependencies>
<dependency>
<groupId>com.yexuejc.springboot</groupId>
<artifactId>yexuejc-springboot-base</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>

View File

@@ -0,0 +1,14 @@
package top.yexuejc.springboot.simple;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class YexuejcSpringbootSimpleApplication {
public static void main(String[] args) {
SpringApplication.run(YexuejcSpringbootSimpleApplication.class, args);
}
}

View File

@@ -0,0 +1,2 @@
logging.level.root=info

View File

@@ -0,0 +1,13 @@
package top.yexuejc.springboot.simple;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
public class YexuejcSpringbootSimpleApplicationTests {
@Test
public void contextLoads() {
}
}