# security-box
**Repository Path**: lixueju/security-box
## Basic Information
- **Project Name**: security-box
- **Description**: 安全盒子,基于Spring Security 和 Spring Security OAuth 实现了企业级的认证和授权。
- **Primary Language**: Java
- **License**: Not specified
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 2
- **Forks**: 1
- **Created**: 2019-11-13
- **Last Updated**: 2021-11-02
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# security-box
## 介绍
安全盒子,基于Spring Security 和 Spring Security OAuth 实现了企业级的认证和授权。
## 安装教程
### 1. 生成密钥证书
* 本项目中Jwt令牌采用的加密算法是RSA非对称加密算法,所以需要RSA密钥证书(项目中虽有默认的证书,但是为了安全,建议您生成自己的密钥证书)
* 命令如下:(例子)
```shell
keytool -genkeypair -alias securityBoxAlias -keyalg RSA -keypass securityBoxKeypass -keystore securityBox.keystore -storepass SecurityBoxStorePass
```
* Keytool 是一个java提供的证书管理工具
* -alias:密钥的别名
* -keyalg:使用的hash算法
* -keypass:密钥的访问密码
* -keystore:密钥库文件名,xc.keystore保存了生成的证书
* -storepass:密钥库的访问密码
* 使用openssl导出公钥,openssl是一个加解密工具包
* 下载openssl:[http://slproweb.com/products/Win32OpenSSL.html ](http://slproweb.com/products/Win32OpenSSL.html)安装资料目录下的Win64OpenSSL-1_1_1b.exe
* 配置openssl的path环境变量,本教程配置在D:\Program Files\OpenSSL-Win64\bin
* cmd进入securityBox.keystore文件所在目录执行如下命令:
```shell
keytool -list -rfc -keystore securityBox.keystore | openssl x509 -inform pem -pubkey
```
* 将上边的公钥拷贝到文本文件中,合并为一行。(publickey.txt)
### 2. 认证授权服务
* Maven依赖
```xml
com.lixueju.security
security-box-web
1.1.0
```
* 将自己的密钥证书放到资源根目录。
* 在启动类上添加扫描注解
```java
@ComponentScan("com.lixueju.security.box")
@MapperScan("com.lixueju.security.box.web.mapper")
```
* 配置信息(可选)
```yaml
security-box:
weixin: #微信配置信息
apps[0]: #微信app信息,数组类型。
name: #app名称,项目中会根据该属性判断当前的app信息。
codeType: #微信认证code类型,值为jscode或者oauth2,默认oauth2
appid: #微信应用的appid
secret: #微信应用的密钥secret
openUrl: #开放的Url,多个Url之间用英文分号分割,默认/security/box/login
encrypt: #密钥证书配置信息
key-store:
location: #密钥文件位置,默认classpath:/securityBox.keystore
secret: #密钥库的访问密码
alias: #密钥的别名
password: #密钥的访问密码
```
### 3. 资源服务
* Maven依赖
```xml
com.lixueju.security
security-box-resource
1.1.0
```
* 将自己的公钥文件(publickey.txt)放到资源根目录,该文件由认证服务器的密钥证书得来。
* 在启动类上添加扫描注解
```java
@ComponentScan("com.lixueju.security.box")
```
* 配置信息(可选)
```yaml
security-box:
openUrl: #开放的Url,多个Url之间用英文分号分割
```
### 4. 验证码服务
* 认证服务和资源服务都包含了验证码服务,无需单独引入。
* Maven依赖
```xml
com.lixueju.security
security-box-validate-code
1.1.0
```
* 在启动类上添加扫描注解
```java
@ComponentScan("com.lixueju.security.box")
```
* 配置信息(可选)
```yaml
security-box:
code: #验证码相关配置
sms:
length: #短信验证码长度
expireIn: #短信验证码过期时间
url: #短信验证码要拦截的url,多个用英文分号分隔。
image:
width: #图形验证码宽度
height: #图形验证码高度
length: #图形验证码长度
expireIn: #图形验证码过期时间
url: #图形验证码要拦截的url,多个用英文分号分隔。
```
* 使用方法
* 发送短信验证码 或 验证短信验证码时,Get请求,需要携带参数 ```mobile```
* 验证短信验证码时,Post请求,请求body体中需要携带参数 ```smsCode```
* 验证图片验证码时,Post请求,请求body体中需要携带参数 ```imageCode```
### 5. SecurityBoxUtils 安装。
* Maven依赖
```xml
com.lixueju.security
security-box-core
1.1.0
```
* 在项目中获取 SecurityBoxUtils
```java
@Autowired
private SecurityBoxUtils securityBoxUtils;
```
## 接口说明
### 1. 认证
#### 1.1 返回数据
* 说明:所有登录接口返回的数据均是以下格式:
```json
{
"code": 0,
"msg": "成功",
"data": {
"id": 10000000,
"companyId": 0,
"username": "admin",
"token": "239e225f-620a-4095-b911-967001555cb7",
"nickName": "系统管理员",
... 更多属性 ...
}
}
```
* 返回值说明:data类型为Object属性如下。
| 名称 | 类型 | 说明 |
| ------------ | ------ | ------------------------------------------------------------ |
| id | String | 是 |
| token | String | 用户认证的授权的凭据,所有需要登录后操作的请求,都需要在请求头中携带此参数,Headers的key为"token" |
| companyId | String | 公司ID |
| username | String | 用户名 |
| mobile | String | 手机号 |
| email | String | 邮箱 |
| zfbBindingId | String | 支付宝绑定ID |
| wxBindingId | String | 微信绑定ID |
| permission | String | 身份许可证 |
| nickName | String | 昵称 |
| userType | String | 用户类型 |
| realName | String | 真实姓名 |
| identityNo | String | 身份证号 |
| gender | String | 性别,详见枚举 |
| birthday | String | 出生日期 |
| avatarUrl | String | 头像 |
| provinceName | String | 省 |
| provinceCode | String | 省code |
| cityName | String | 市 |
| cityCode | String | 市code |
| areaName | String | 区、县 |
| areaCode | String | 区code |
| gpsAddress | String | 定位地址(地图选址) |
| address | String | 通信地址(手动输入) |
| status | int | 状态:详见枚举 |
| permissions | Array | 权限集合 |
#### 1.2 公共请求参数
* 请求方式:Post
* 所有登录方式的共有参数
| 名称 | 类型 | 是否必须 | 说明 |
| ------------------ | ------- | -------- | ------------------------------- |
| userType | int | 是 | 用户类型 |
| companyId | String | 否 | 公司ID |
| containPermissions | boolean | 否 | 是否包含权限码集合,默认false。 |
#### 1.3 用户名密码登录
* 请求URL:/security/box/login/username
| 名称 | 类型 | 是否必须 | 说明 |
| -------- | ------ | -------- | ------ |
| username | String | 是 | 用户名 |
| password | String | 是 | 密码 |
#### 1.4 手机号验证码登录
* 请求URL:/security/box/login/sms
| 名称 | 类型 | 是否必须 | 说明 |
| ------- | ------ | -------- | ------ |
| mobile | String | 是 | 手机号 |
| smsCode | String | 是 | 验证码 |
#### 1.5 支付宝登录请求
#### 1.6 微信登录请求
* 请求URL:/security/box/login/weixin
* 适用于:app
| 名称 | 类型 | 是否必须 | 说明 |
| ------- | ------ | -------- | ------------------------------------ |
| appName | String | 是 | 移动端值为:app (以服务端配置为准) |
| code | String | 是 | 授权码:微信给返回的授权码 |
#### 1.7 微信密文登录请求
* 请求URL:/security/box/login/weixin/decode
* 适用于:小程序
| 名称 | 类型 | 是否必须 | 说明 |
| ------------- | ------ | -------- | ----------------------------------------- |
| appName | String | 是 | C端小程序值为:c_mini(以服务端配置为准) |
| code | String | 是 | 授权码:微信给返回的授权码 |
| encryptedData | String | 否 | 小程序需要获取unionid时必传 |
| iv | String | 否 | 小程序需要获取unionid时必传 |
#### 1.8 退出登录
* 请求URL:/security/box/user/logOut
* 请求方式:Get
* 返回值:data类型为Boolean。true代表成功。
### 2. 授权
* 本项目的权限菜单是按照 ant-design-pro-vue 项目编写的。
#### 2.1 菜单管理
##### 2.1.1 菜单列表
* 请求URL:/security/box/authMenu/menuList
* 请求方式:Get
* 请求参数:(支持分页)
| 名称 | 类型 | 是否必须 | 说明 |
| ---- | ------ | -------- | -------- |
| name | String | 否 | 菜单名称 |
* 返回值:data类型为Array,Array中为Object,Object属性如下。
| 名称 | 类型 | 说明 |
| ----------- | ------ | ------------------------------ |
| id | String | 唯一主键 |
| parentId | String | 父级菜单ID |
| name | String | 菜单名称 |
| icon | String | 菜单图标 |
| path | String | 菜单地址 |
| redirect | String | 重定向 |
| component | String | 组件:所对应页面的组件 |
| permission | String | 许可证 |
| status | int | 菜单状态:1正常 |
| systemType | int | 系统类型:1系统后台、2用户类型 |
| type | int | 菜单类型:1菜单、2操作 |
| hidden | int | 是否隐藏:1显示、2隐藏 |
| orderNum | int | 排序字段 |
| description | String | 描述信息 |
| createTime | String | 创建时间 |
| updateTime | String | 修改时间 |
| delFlag | int | 删除标签:1未删除、2删除 |
##### 2.1.2 新增or修改
* 请求URL:/security/box/authMenu/addOrUpdateAuthMenu
* 请求方式:Post
* 请求参数:
| 名称 | 类型 | 是否必须 | 说明 |
| ----------- | ------ | -------- | ---------------------------------------------- |
| id | String | 否 | 唯一主键,修改时必须传递 |
| parentId | String | 是 | 父级菜单ID |
| name | String | 是 | 菜单名称 |
| icon | String | 否 | 菜单图标,type值为1时,建议传递 |
| path | String | 是 | 菜单地址 |
| redirect | String | 否 | 重定向 |
| component | String | 否 | 组件:所对应页面的组件,type值为1时,必须传递。 |
| permission | String | 是 | 许可证 |
| status | int | 是 | 菜单状态:1正常 |
| systemType | int | 是 | 系统类型:1系统后台、2用户类型 |
| type | int | 是 | 菜单类型:1菜单、2操作 |
| hidden | int | 是 | 是否隐藏:1显示、2隐藏 |
| orderNum | int | 是 | 排序字段 |
| description | String | 否 | 描述信息 |
* 返回值:data类型为Boolean。true代表新增或修改成功。
##### 2.1.3 删除菜单
* 请求URL:/security/box/authMenu/deleteAuthMenu
* 请求方式:Post
* 请求参数:
| 名称 | 类型 | 是否必须 | 说明 |
| ---- | ------ | -------- | -------- |
| id | String | 是 | 唯一主键 |
* 返回值:data类型为Boolean。true代表删除成功。
#### 2.2 角色管理
##### 2.2.1 角色列表
* 请求URL:/security/box/authRole/authRoleList
* 请求方式:Get
* 请求参数:(支持分页)
| 名称 | 类型 | 是否必须 | 说明 |
| ---- | ------ | -------- | -------- |
| name | String | 否 | 角色名称 |
* 返回值:data类型为Array,Array中为Object,Object属性如下。
| 名称 | 类型 | 说明 |
| ----------- | ------ | ----------------------- |
| id | String | 唯一主键 |
| name | String | 角色名称 |
| status | int | 状态 |
| orderNum | int | 排序 |
| description | String | 描述信息 |
| createTime | String | 创建时间 |
| updateTime | String | 修改时间 |
| delFlag | int | 删除标签:1未删除、2删除 |
##### 2.2.2 新增or修改
* 请求URL:/security/box/authRole/addOrUpdateAuthRole
* 请求方式:Post
* 请求参数:
| 名称 | 类型 | 是否必须 | 说明 |
| ----------- | ------ | -------- | ------------------------ |
| id | String | 否 | 唯一主键,修改时必须传递 |
| name | String | 是 | 角色名称 |
| status | int | 是 | 状态 |
| orderNum | int | 是 | 排序 |
| description | String | 否 | 描述信息 |
* 返回值:data类型为Boolean。true代表新增或修改成功。
##### 2.2.3 删除角色
* 请求URL:/security/box/authRole/deleteAuthRole
* 请求方式:Post
* 请求参数:
| 名称 | 类型 | 是否必须 | 说明 |
| ---- | ------ | -------- | -------- |
| id | String | 是 | 唯一主键 |
* 返回值:data类型为Boolean。true代表删除成功。
##### 2.2.4 修改角色权限
* 请求URL:/security/box/authRole/updatePermission
* 请求方式:Post
* 请求参数:
| 名称 | 类型 | 是否必须 | 说明 |
| ------- | ------ | -------- | ------------------ |
| roleId | String | 是 | 角色唯一主键 |
| menuIds | Array | 是 | 授权的菜单主键集合 |
* 返回值:data类型为Boolean。true代表修改成功。
#### 2.3 用户管理
##### 2.3.1 用户列表
* 请求URL:/security/box/user/userList
* 请求方式:Get
* 请求参数:(支持分页)
| 名称 | 类型 | 是否必须 | 说明 |
| -------- | ------ | -------- | -------- |
| username | String | 否 | 用户名称 |
* 返回值:data类型为Array,Array中为Object,Object属性如下。
| 名称 | 类型 | 说明 |
| ---------- | ------ | ------------ |
| id | String | 数据唯一主键 |
| username | String | 用户名 |
| mobile | String | 手机号 |
| nickName | String | 昵称 |
| userType | int | 用户类型 |
| realName | String | 真实姓名 |
| avatarUrl | String | 头像 |
| permission | String | 身份许可证 |
| createTime | String | 创建时间 |
##### 2.3.2 修改用户角色
* 请求URL:/security/box/user/updateUserRole
* 请求方式:Post
* 请求参数:
| 名称 | 类型 | 是否必须 | 说明 |
| ------- | ------ | -------- | ------------------ |
| roleIds | Array | 是 | 授权的角色主键集合 |
| id | String | 是 | 用户主键 |
| ... ... | | | |
* 返回值:data类型为Boolean。true代表修改成功。
### 3. 其它接口
#### 3.1 获取用户可访问的菜单
- 请求URL:/security/box/authMenu/getUserMenuList
- 请求方式:Get
- 请求参数:(无)
- 返回值:data类型为Array,Array中为Object,Object属性如下。
| 名称 | 类型 | 说明 |
| ----------- | ------ | ------------------------------ |
| id | String | 唯一主键 |
| parentId | String | 父级菜单ID |
| name | String | 菜单名称 |
| icon | String | 菜单图标 |
| path | String | 菜单地址 |
| redirect | String | 重定向 |
| component | String | 组件:所对应页面的组件 |
| permission | String | 许可证 |
| status | int | 菜单状态:1正常 |
| systemType | int | 系统类型:1系统后台、2用户类型 |
| type | int | 菜单类型:1菜单、2操作 |
| hidden | int | 是否隐藏:1显示、2隐藏 |
| orderNum | int | 排序字段 |
| description | String | 描述信息 |
| createTime | String | 创建时间 |
| updateTime | String | 修改时间 |
| delFlag | int | 删除标签:1未删除、2删除 |
#### 3.2 新增用户
- 请求URL:/security/box/user/addUser
- 请求方式:Post
- 请求参数:
| 名称 | 类型 | 是否必须 | 说明 |
| --------- | ------ | -------- | ------ |
| companyId | Long | 否 | 公司ID |
| username | String | 是 | 用户名 |
| mobile | String | | 手机号 |
| ... | | | |
- 返回值:data类型为Boolean。true代表修改成功。
#### 3.3 修改用户
- 请求URL:/security/box/user/updateUser
- 请求方式:Post
- 请求参数:
| 名称 | 类型 | 是否必须 | 说明 |
| --------- | ------ | -------- | -------- |
| id | Long | 是 | 唯一主键 |
| companyId | Long | 否 | 公司ID |
| username | String | | 用户名 |
| ... | | | |
- 返回值:data类型为Boolean。true代表修改成功。
#### 3.4 绑定手机号
- 请求URL:/security/box/user/bindMobile
- 请求方式:Post
- 请求参数:
| 名称 | 类型 | 是否必须 | 说明 |
| ------- | ------ | -------- | ---------- |
| mobile | String | 是 | 用户名 |
| smsCode | String | 是 | 短信验证码 |
- 返回值:和登录返回的相同。
#### 3.5 绑定手机号—微信授权
- 请求URL:/security/box/user/bindWeixinMobile
- 请求方式:Post
- 适用于:小程序
- 请求参数:
| 名称 | 类型 | 是否必须 | 说明 |
| ------------- | ------ | -------- | --------------------------------------------------- |
| appName | String | 是 | C端小程序值为:c_mini。(以后台配置文件中的名称为准) |
| code | String | 是 | 授权码:微信给返回的授权码 |
| encryptedData | String | 是 | 微信提供的encryptedData |
| iv | String | 是 | 微信提供的iv |
- 返回值:和登录返回的相同。
#### 3.6 绑定微信
- 请求URL:/security/box/user/bindWeixin
- 请求方式:Post
- 适用于:app
- 请求参数:
| 名称 | 类型 | 是否必须 | 说明 |
| ------- | ------ | -------- | --------------------------------------------- |
| appName | String | 是 | 移动端值为:app。(以后台配置文件中的名称为准) |
| code | String | 是 | 授权码:微信给返回的授权码 |
- 返回值:和登录返回的相同。
#### 3.7 修改密码(根据旧密码)
- 请求URL:/security/box/user/upPassword
- 请求方式:Post
- 请求参数:
| 名称 | 类型 | 是否必须 | 说明 |
| ------------- | ------ | -------- | ---------- |
| oldPassword | String | 是 | 旧密码 |
| newPassword | String | 是 | 新密码 |
| reNewPassword | String | 是 | 确认新密码 |
- 返回值:data类型为Boolean。true代表修改成功。
#### 3.7 修改密码(根据手机验证码)
- 请求URL:/security/box/user/upPasswordByMobile
- 请求方式:Post
- 请求参数:
| 名称 | 类型 | 是否必须 | 说明 |
| ------------- | ------ | -------- | ---------- |
| mobile | String | 是 | 手机号 |
| smsCode | String | 是 | 短信验证码 |
| newPassword | String | 是 | 新密码 |
| reNewPassword | String | 是 | 确认新密码 |
- 返回值:data类型为Boolean。true代表修改成功。