Browse Source

重构国际化,公共组件,权限开发。

master
caojianbin 1 year ago
parent
commit
178e58da5b
  1. 79
      ecell-internationalize/ecell-internationalize-auth/pom.xml
  2. 27
      ecell-internationalize/ecell-internationalize-auth/src/main/java/com/ecell/internationalize/auth/EcellAuthApplication.java
  3. 40
      ecell-internationalize/ecell-internationalize-auth/src/main/java/com/ecell/internationalize/auth/config/ExceptionAdviceConfig.java
  4. 20
      ecell-internationalize/ecell-internationalize-auth/src/main/java/com/ecell/internationalize/auth/controller/AuthController.java
  5. 33
      ecell-internationalize/ecell-internationalize-auth/src/main/resources/application-dev.yml
  6. 25
      ecell-internationalize/ecell-internationalize-auth/src/main/resources/bootstrap.yml
  7. 8
      ecell-internationalize/ecell-internationalize-auth/src/main/resources/i18n/messages.properties
  8. 8
      ecell-internationalize/ecell-internationalize-auth/src/main/resources/i18n/messages_en_US.properties
  9. 8
      ecell-internationalize/ecell-internationalize-auth/src/main/resources/i18n/messages_ru_RU.properties
  10. 8
      ecell-internationalize/ecell-internationalize-auth/src/main/resources/i18n/messages_zh_CN.properties
  11. 7
      ecell-internationalize/ecell-internationalize-common/ecell-internationalize-core/pom.xml
  12. 59
      ecell-internationalize/ecell-internationalize-common/ecell-internationalize-core/src/main/java/com/ecell/internationalize/common/core/domain/LoginUser.java
  13. 60
      ecell-internationalize/ecell-internationalize-common/ecell-internationalize-core/src/main/java/com/ecell/internationalize/common/core/domain/SysRole.java
  14. 98
      ecell-internationalize/ecell-internationalize-common/ecell-internationalize-core/src/main/java/com/ecell/internationalize/common/core/domain/SysUser.java
  15. 38
      ecell-internationalize/ecell-internationalize-common/ecell-internationalize-core/src/main/java/com/ecell/internationalize/common/core/enums/UserStatus.java
  16. 20
      ecell-internationalize/ecell-internationalize-common/ecell-internationalize-core/src/main/java/com/ecell/internationalize/common/core/utils/locale/LocaleUtil.java
  17. 2
      ecell-internationalize/ecell-internationalize-common/ecell-internationalize-core/src/main/resources/META-INF/spring.factories
  18. 22
      ecell-internationalize/ecell-internationalize-common/ecell-internationalize-security/pom.xml
  19. 29
      ecell-internationalize/ecell-internationalize-common/ecell-internationalize-security/src/main/java/com/ecell/internationalize/common/security/annotation/EnableCustomConfig.java
  20. 16
      ecell-internationalize/ecell-internationalize-common/ecell-internationalize-security/src/main/java/com/ecell/internationalize/common/security/annotation/InnerAuth.java
  21. 18
      ecell-internationalize/ecell-internationalize-common/ecell-internationalize-security/src/main/java/com/ecell/internationalize/common/security/annotation/Logical.java
  22. 15
      ecell-internationalize/ecell-internationalize-common/ecell-internationalize-security/src/main/java/com/ecell/internationalize/common/security/annotation/RequiresLogin.java
  23. 23
      ecell-internationalize/ecell-internationalize-common/ecell-internationalize-security/src/main/java/com/ecell/internationalize/common/security/annotation/RequiresPermissions.java
  24. 23
      ecell-internationalize/ecell-internationalize-common/ecell-internationalize-security/src/main/java/com/ecell/internationalize/common/security/annotation/RequiresRoles.java
  25. 44
      ecell-internationalize/ecell-internationalize-common/ecell-internationalize-security/src/main/java/com/ecell/internationalize/common/security/aspect/InnerAuthAspect.java
  26. 89
      ecell-internationalize/ecell-internationalize-common/ecell-internationalize-security/src/main/java/com/ecell/internationalize/common/security/aspect/PreAuthorizeAspect.java
  27. 371
      ecell-internationalize/ecell-internationalize-common/ecell-internationalize-security/src/main/java/com/ecell/internationalize/common/security/auth/AuthLogic.java
  28. 161
      ecell-internationalize/ecell-internationalize-common/ecell-internationalize-security/src/main/java/com/ecell/internationalize/common/security/auth/AuthUtil.java
  29. 20
      ecell-internationalize/ecell-internationalize-common/ecell-internationalize-security/src/main/java/com/ecell/internationalize/common/security/config/ApplicationConfig.java
  30. 30
      ecell-internationalize/ecell-internationalize-common/ecell-internationalize-security/src/main/java/com/ecell/internationalize/common/security/config/WebMvcConfig.java
  31. 17
      ecell-internationalize/ecell-internationalize-common/ecell-internationalize-security/src/main/java/com/ecell/internationalize/common/security/feign/FeignAutoConfiguration.java
  32. 48
      ecell-internationalize/ecell-internationalize-common/ecell-internationalize-security/src/main/java/com/ecell/internationalize/common/security/feign/FeignRequestInterceptor.java
  33. 125
      ecell-internationalize/ecell-internationalize-common/ecell-internationalize-security/src/main/java/com/ecell/internationalize/common/security/handler/GlobalExceptionHandler.java
  34. 52
      ecell-internationalize/ecell-internationalize-common/ecell-internationalize-security/src/main/java/com/ecell/internationalize/common/security/interceptor/HeaderInterceptor.java
  35. 170
      ecell-internationalize/ecell-internationalize-common/ecell-internationalize-security/src/main/java/com/ecell/internationalize/common/security/service/TokenService.java
  36. 159
      ecell-internationalize/ecell-internationalize-common/ecell-internationalize-security/src/main/java/com/ecell/internationalize/common/security/utils/SecurityUtils.java
  37. 17
      ecell-internationalize/ecell-internationalize-common/ecell-internationalize-swagger/pom.xml
  38. 18
      ecell-internationalize/ecell-internationalize-common/ecell-internationalize-swagger/src/main/java/com/ecell/internationalize/common/swagger/annotation/EnableCustomSwagger2.java
  39. 128
      ecell-internationalize/ecell-internationalize-common/ecell-internationalize-swagger/src/main/java/com/ecell/internationalize/common/swagger/config/SwaggerAutoConfiguration.java
  40. 45
      ecell-internationalize/ecell-internationalize-common/ecell-internationalize-swagger/src/main/java/com/ecell/internationalize/common/swagger/config/SwaggerBeanPostProcessor.java
  41. 301
      ecell-internationalize/ecell-internationalize-common/ecell-internationalize-swagger/src/main/java/com/ecell/internationalize/common/swagger/config/SwaggerProperties.java
  42. 20
      ecell-internationalize/ecell-internationalize-common/ecell-internationalize-swagger/src/main/java/com/ecell/internationalize/common/swagger/config/SwaggerWebConfiguration.java
  43. 1
      ecell-internationalize/pom.xml

79
ecell-internationalize/ecell-internationalize-auth/pom.xml

@ -0,0 +1,79 @@ @@ -0,0 +1,79 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>ecell-internationalize</artifactId>
<groupId>com.ecell.internationalize</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>com.ecell.internationalize.auth</groupId>
<artifactId>ecell-internationalize-auth</artifactId>
<dependencies>
<!-- SpringCloud Alibaba Nacos -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!-- SpringCloud Alibaba Nacos Config -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<!-- SpringCloud Alibaba Sentinel -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
<!-- SpringBoot Actuator -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!-- SpringBoot Web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Swagger UI -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>${swagger.fox.version}</version>
</dependency>
<dependency>
<groupId>com.ecell.internationalize.common.swagger</groupId>
<artifactId>ecell-internationalize-swagger</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.ecell.internationalize.common.core</groupId>
<artifactId>ecell-internationalize-core</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.ecell.internationalize.common.security</groupId>
<artifactId>ecell-internationalize-security</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<!--lombok依赖 -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
</project>

27
ecell-internationalize/ecell-internationalize-auth/src/main/java/com/ecell/internationalize/auth/EcellAuthApplication.java

@ -0,0 +1,27 @@ @@ -0,0 +1,27 @@
package com.ecell.internationalize.auth;
import com.ecell.internationalize.auth.config.ExceptionAdviceConfig;
import com.ecell.internationalize.common.core.utils.SpringUtils;
import com.ecell.internationalize.common.swagger.annotation.EnableCustomSwagger2;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.ConfigurableApplicationContext;
/**
* @author borui
*/
@EnableFeignClients
@EnableCustomSwagger2
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class },scanBasePackages = {"com.ecell.internationalize"})
public class EcellAuthApplication {
public static void main(String[] args)
{
SpringApplication.run(EcellAuthApplication.class, args);
System.out.println("(♥◠‿◠)ノ゙ 认证授权中心启动成功 ლ(´ڡ`ლ)゙ \n");
}
}

40
ecell-internationalize/ecell-internationalize-auth/src/main/java/com/ecell/internationalize/auth/config/ExceptionAdviceConfig.java

@ -0,0 +1,40 @@ @@ -0,0 +1,40 @@
package com.ecell.internationalize.auth.config;
import com.ecell.internationalize.common.core.utils.ServletUtils;
import com.ecell.internationalize.common.core.utils.SpringUtils;
import com.ecell.internationalize.common.core.utils.locale.LocaleUtil;
import com.ecell.internationalize.common.core.web.domain.AjaxResult;
import net.bytebuddy.implementation.bytecode.constant.FieldConstant;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.MessageSource;
import org.springframework.http.HttpRequest;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import java.util.Locale;
/**
* @author borui
*/
@RestControllerAdvice
public class ExceptionAdviceConfig {
private static final Logger logger = LoggerFactory.getLogger(ExceptionAdviceConfig.class);
/**
* 全局异常处理,配置国际化
* @Author: liy
* @Date: 2022/7/8 13:53
*/
@ExceptionHandler(Exception.class)
public AjaxResult exceptionHandler(Exception e) {
e.printStackTrace();
// Locale locale = LocaleUtil.getLocale();
//
// MessageSource messageSource = SpringUtils.getBean(MessageSource.class);
// String message = messageSource.getMessage("messages.login.empty", null, locale);
String message = LocaleUtil.getMessage("messages.login.empty");
System.out.println("获取到的国际化语言是:=="+message);
return AjaxResult.error(message);
}
}

20
ecell-internationalize/ecell-internationalize-auth/src/main/java/com/ecell/internationalize/auth/controller/AuthController.java

@ -0,0 +1,20 @@ @@ -0,0 +1,20 @@
package com.ecell.internationalize.auth.controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @author borui
*/
@RestController
@RequestMapping("/auth")
public class AuthController {
@GetMapping("test")
public String test( ){
int a=1;
int b= a/0;
return "111";
}
}

33
ecell-internationalize/ecell-internationalize-auth/src/main/resources/application-dev.yml

@ -0,0 +1,33 @@ @@ -0,0 +1,33 @@
spring:
redis:
host: 120.77.209.176
port: 6379
database: 2
password: Ecell...20201001
# 配置国际化资源文件路径
messages:
basename: i18n/messages
encoding: UTF-8
#设置静态资源路径,多个以逗号分隔
web:
resources:
static-locations: classpath:static/
mybatis:
#配置SQL映射文件路径
mapper-locations: classpath:mapper/*.xml
# 搜索指定包别名
typeAliasesPackage: com.yisai.auth
#驼峰命名
configuration:
map-underscore-to-camel-case: true
#开启熔断降级
feign:
sentinel:
enabled: true
client:
config:
default:
connectTimeout: 10000
readTimeout: 60000

25
ecell-internationalize/ecell-internationalize-auth/src/main/resources/bootstrap.yml

@ -0,0 +1,25 @@ @@ -0,0 +1,25 @@
# Tomcat
server:
port: 9998
# Spring
spring:
application:
# 应用名称
name: ecell-internationalize-auth
profiles:
# 环境配置
active: dev
cloud:
nacos:
discovery:
# 服务注册地址
server-addr: 127.0.0.1:8848
config:
# 配置中心地址
server-addr: 127.0.0.1:8848
# 配置文件格式
file-extension: yml
# 共享配置
shared-configs:
- application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}

8
ecell-internationalize/ecell-internationalize-auth/src/main/resources/i18n/messages.properties

@ -0,0 +1,8 @@ @@ -0,0 +1,8 @@
messages.login.empty=账号或者密码不能为空
messages.fallback.info=服务不存在或网络端口错误
messages.login.error=用户名不存在
messages.account.delete=您的账号已被删除
messages.account.stop=您的账号已被禁用
messages.success=操作成功
messages.error=操作失败,请联系管理员处理
messages.error.password=输入的密码错误

8
ecell-internationalize/ecell-internationalize-auth/src/main/resources/i18n/messages_en_US.properties

@ -0,0 +1,8 @@ @@ -0,0 +1,8 @@
messages.login.empty=Account or password cannot be empty
messages.fallback.info=Service does not exist or network port error
messages.login.error=user name does not exist
messages.account.delete=Your account has been deleted
messages.account.stop=Your account has been disabled
messages.success=Operation successful
messages.error=Operation failed, please contact the administrator for handling
messages.error.password=Wrong password entered

8
ecell-internationalize/ecell-internationalize-auth/src/main/resources/i18n/messages_ru_RU.properties

@ -0,0 +1,8 @@ @@ -0,0 +1,8 @@
messages.fallback.info=\u0421\u0435\u0440\u0432\u0438\u0441\u044B \u043D\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044E\u0442 \u0438\u043B\u0438 \u043E\u0448\u0438\u0431\u043A\u0438 \u0441\u0435\u0442\u0435\u0432\u044B\u0445 \u043F\u043E\u0440\u0442\u043E\u0432
messages.login.error=\u0418\u043C\u0435\u043D\u0438 \u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u0435\u043B\u044F \u043D\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442
messages.account.stop=\u0412\u0430\u0448 \u0430\u043A\u043A\u0430\u0443\u043D\u0442 \u0437\u0430\u0431\u043B\u043E\u043A\u0438\u0440\u043E\u0432\u0430\u043D
messages.error.password=\u0412\u0432\u0435\u0434\u0435\u043D\u0430 \u043E\u0448\u0438\u0431\u043A\u0430 \u0432 \u043A\u043E\u0434\u0435
messages.success=\u041E\u043F\u0435\u0440\u0430\u0446\u0438\u044F \u0432\u044B\u043F\u043E\u043B\u043D\u0435\u043D\u0430.
messages.account.delete=\u0412\u0430\u0448 \u0430\u043A\u043A\u0430\u0443\u043D\u0442 \u0431\u044B\u043B \u0443\u0434\u0430\u043B\u0435\u043D
messages.login.empty=\u041D\u043E\u043C\u0435\u0440 \u0441\u0447\u0435\u0442\u0430 \u0438\u043B\u0438 \u043F\u0430\u0440\u043E\u043B\u044C \u043D\u0435 \u043C\u043E\u0436\u0435\u0442 \u0431\u044B\u0442\u044C \u043F\u0443\u0441\u0442\u044B\u043C
messages.error=\u041F\u043E\u0436\u0430\u043B\u0443\u0439\u0441\u0442\u0430, \u0441\u0432\u044F\u0436\u0438\u0442\u0435\u0441\u044C \u0441 \u0430\u0434\u043C\u0438\u043D\u0438\u0441\u0442\u0440\u0430\u0442\u043E\u0440\u043E\u043C

8
ecell-internationalize/ecell-internationalize-auth/src/main/resources/i18n/messages_zh_CN.properties

@ -0,0 +1,8 @@ @@ -0,0 +1,8 @@
messages.login.empty=账号或者密码不能为空
messages.fallback.info=服务不存在或网络端口错误
messages.login.error=用户名不存在
messages.account.delete=您的账号已被删除
messages.account.stop=您的账号已被禁用
messages.success=操作成功
messages.error=操作失败,请联系管理员处理
messages.error.password=输入的密码错误

7
ecell-internationalize/ecell-internationalize-common/ecell-internationalize-core/pom.xml

@ -120,6 +120,13 @@ @@ -120,6 +120,13 @@
<artifactId>swagger-annotations</artifactId>
</dependency>
<!--lombok依赖 -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
</project>

59
ecell-internationalize/ecell-internationalize-common/ecell-internationalize-core/src/main/java/com/ecell/internationalize/common/core/domain/LoginUser.java

@ -0,0 +1,59 @@ @@ -0,0 +1,59 @@
package com.ecell.internationalize.common.core.domain;
import lombok.Data;
import java.io.Serializable;
import java.util.Set;
/**
* @author borui
*/
@Data
public class LoginUser implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 用户唯一标识
*/
private String token;
/**
* 用户名id
*/
private Long userid;
/**
* 用户名
*/
private String username;
/**
* 登录时间
*/
private Long loginTime;
/**
* 过期时间
*/
private Long expireTime;
/**
* 登录IP地址
*/
private String ipaddr;
/**
* 权限列表
*/
private Set<String> permissions;
/**
* 角色列表
*/
private Set<String> roles;
/**
* 用户信息
*/
private SysUser sysUser;
}

60
ecell-internationalize/ecell-internationalize-common/ecell-internationalize-core/src/main/java/com/ecell/internationalize/common/core/domain/SysRole.java

@ -0,0 +1,60 @@ @@ -0,0 +1,60 @@
package com.ecell.internationalize.common.core.domain;
import com.ecell.internationalize.common.core.annotation.Excel;
import com.ecell.internationalize.common.core.web.domain.BaseEntity;
import lombok.Data;
/**
* @author borui
*/
@Data
public class SysRole extends BaseEntity {
private static final long serialVersionUID = 1L;
/** 角色ID */
@Excel(name = "角色序号", cellType = Excel.ColumnType.NUMERIC)
private Long roleId;
/** 角色名称 */
@Excel(name = "角色名称")
private String roleName;
/** 角色权限 */
@Excel(name = "角色权限")
private String roleKey;
/** 角色排序 */
@Excel(name = "角色排序")
private String roleSort;
/** 数据范围(1:所有数据权限;2:自定义数据权限;3:本部门数据权限;4:本部门及以下数据权限;5:仅本人数据权限) */
@Excel(name = "数据范围", readConverterExp = "1=所有数据权限,2=自定义数据权限,3=本部门数据权限,4=本部门及以下数据权限,5=仅本人数据权限")
private String dataScope;
/** 菜单树选择项是否关联显示( 0:父子不互相关联显示 1:父子互相关联显示) */
private boolean menuCheckStrictly;
/** 部门树选择项是否关联显示(0:父子不互相关联显示 1:父子互相关联显示 ) */
private boolean deptCheckStrictly;
/** 角色状态(0正常 1停用) */
@Excel(name = "角色状态", readConverterExp = "0=正常,1=停用")
private String status;
/** 删除标志(0代表存在 2代表删除) */
private String delFlag;
/** 用户是否存在此角色标识 默认不存在 */
private boolean flag = false;
/** 菜单组 */
private Long[] menuIds;
/** 部门组(数据权限) */
private Long[] deptIds;
public SysRole()
{
}
}

98
ecell-internationalize/ecell-internationalize-common/ecell-internationalize-core/src/main/java/com/ecell/internationalize/common/core/domain/SysUser.java

@ -0,0 +1,98 @@ @@ -0,0 +1,98 @@
package com.ecell.internationalize.common.core.domain;
import com.ecell.internationalize.common.core.annotation.Excel;
import com.ecell.internationalize.common.core.annotation.Excels;
import com.ecell.internationalize.common.core.web.domain.BaseEntity;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
import java.util.Set;
/**
* @author borui
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@ApiModel(value = "SysUser对象", description = "系统用户")
public class SysUser extends BaseEntity {
private static final long serialVersionUID = 1L;
/** 用户ID */
@Excel(name = "用户序号", cellType = Excel.ColumnType.NUMERIC, prompt = "用户编号")
private Long userId;
/** 部门ID */
@Excel(name = "部门编号", type = Excel.Type.IMPORT)
private Long deptId;
/** 用户账号 */
@Excel(name = "登录名称")
private String userName;
/** 用户昵称 */
@Excel(name = "用户名称")
private String nickName;
/** 用户邮箱 */
@Excel(name = "用户邮箱")
private String email;
/** 手机号码 */
@Excel(name = "手机号码")
private String phonenumber;
/** 用户性别 */
@Excel(name = "用户性别", readConverterExp = "0=男,1=女,2=未知")
private String sex;
/** 用户头像 */
private String avatar;
/** 密码 */
private String password;
/** 帐号状态(0正常 1停用) */
@Excel(name = "帐号状态", readConverterExp = "0=正常,1=停用")
private String status;
/** 删除标志(0代表存在 2代表删除) */
private String delFlag;
/** 最后登录IP */
@Excel(name = "最后登录IP", type = Excel.Type.EXPORT)
private String loginIp;
/** 最后登录时间 */
@Excel(name = "最后登录时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss", type = Excel.Type.EXPORT)
private Date loginDate;
/** 部门对象 */
@Excels({
@Excel(name = "部门名称", targetAttr = "deptName", type = Excel.Type.EXPORT),
@Excel(name = "部门负责人", targetAttr = "leader", type = Excel.Type.EXPORT)
})
/** 角色对象 */
private List<SysRole> roles;
/** 角色组 */
private Long[] roleIds;
/** 岗位组 */
private Long[] postIds;
/** 角色ID */
private Long roleId;
public SysUser()
{
}
}

38
ecell-internationalize/ecell-internationalize-common/ecell-internationalize-core/src/main/java/com/ecell/internationalize/common/core/enums/UserStatus.java

@ -5,23 +5,23 @@ package com.ecell.internationalize.common.core.enums; @@ -5,23 +5,23 @@ package com.ecell.internationalize.common.core.enums;
* @author borui
*/
public class UserStatus {
OK("0", "正常"),DISABLE("1", "停用"),DELETED("2", "删除");
private final String code;
private final String info;
UserStatus(String code, String info)
{
this.code = code;
this.info = info;
}
public String getCode()
{
return code;
}
public String getInfo()
{
return info;
}
// OK("0", "正常"),DISABLE("1", "停用"),DELETED("2", "删除");
// private final String code;
// private final String info;
//
// UserStatus(String code, String info)
// {
// this.code = code;
// this.info = info;
// }
//
// public String getCode()
// {
// return code;
// }
//
// public String getInfo()
// {
// return info;
// }
}

20
ecell-internationalize/ecell-internationalize-common/ecell-internationalize-core/src/main/java/com/ecell/internationalize/common/core/utils/locale/LocaleUtil.java

@ -1,6 +1,10 @@ @@ -1,6 +1,10 @@
package com.ecell.internationalize.common.core.utils.locale;
import com.ecell.internationalize.common.core.utils.ServletUtils;
import com.ecell.internationalize.common.core.utils.SpringUtils;
import com.ecell.internationalize.common.core.utils.StringUtils;
import org.springframework.context.MessageSource;
import org.springframework.http.HttpRequest;
import java.util.Locale;
@ -8,13 +12,16 @@ import java.util.Locale; @@ -8,13 +12,16 @@ import java.util.Locale;
* @author borui
*/
public class LocaleUtil {
public static Locale getLocale(String lang){
public static Locale getLocale(){
String language = ServletUtils.getHeader(ServletUtils.getRequest(), "content-language");
Locale locale;
if (StringUtils.isEmpty(lang)) {
if (StringUtils.isEmpty(language)) {
locale = Locale.US;
} else {
try {
String [] split = lang.split("_");
String [] split = language.split("_");
locale = new Locale(split[0], split[1]);
} catch (Exception e) {
locale = Locale.US;
@ -22,4 +29,11 @@ public class LocaleUtil { @@ -22,4 +29,11 @@ public class LocaleUtil {
}
return locale;
}
public static String getMessage(String code) {
Locale locale = getLocale();
return SpringUtils.getBean(MessageSource.class).getMessage(code, null, locale);
}
}

2
ecell-internationalize/ecell-internationalize-common/ecell-internationalize-core/src/main/resources/META-INF/spring.factories

@ -1,4 +1,4 @@ @@ -1,4 +1,4 @@
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.ruoyi.common.core.utils.SpringUtils
com.ecell.internationalize.common.core.utils.SpringUtils

22
ecell-internationalize/ecell-internationalize-common/ecell-internationalize-security/pom.xml

@ -12,9 +12,23 @@ @@ -12,9 +12,23 @@
<groupId>com.ecell.internationalize.common.security</groupId>
<artifactId>ecell-internationalize-security</artifactId>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencies>
<!-- Spring Web -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
</dependency>
<dependency>
<groupId>com.ecell.internationalize.common.redis</groupId>
<artifactId>ecell-internationalize-redis</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<!--lombok依赖 -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
</project>

29
ecell-internationalize/ecell-internationalize-common/ecell-internationalize-security/src/main/java/com/ecell/internationalize/common/security/annotation/EnableCustomConfig.java

@ -0,0 +1,29 @@ @@ -0,0 +1,29 @@
package com.ecell.internationalize.common.security.annotation;
import com.ecell.internationalize.common.security.config.ApplicationConfig;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.cloud.openfeign.FeignAutoConfiguration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.context.annotation.Import;
import org.springframework.scheduling.annotation.EnableAsync;
import java.lang.annotation.*;
/**
* @author borui
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
// 表示通过aop框架暴露该代理对象,AopContext能够访问
@EnableAspectJAutoProxy(exposeProxy = true)
// 指定要扫描的Mapper类的包的路径
@MapperScan("com.campus.**.mapper")
// 开启线程异步执行
@EnableAsync
// 自动加载类
@Import({ ApplicationConfig.class, FeignAutoConfiguration.class })
public @interface EnableCustomConfig {
}

16
ecell-internationalize/ecell-internationalize-common/ecell-internationalize-security/src/main/java/com/ecell/internationalize/common/security/annotation/InnerAuth.java

@ -0,0 +1,16 @@ @@ -0,0 +1,16 @@
package com.ecell.internationalize.common.security.annotation;
import java.lang.annotation.*;
/**
* @author borui
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface InnerAuth {
/**
* 是否校验用户信息
*/
boolean isUser() default false;
}

18
ecell-internationalize/ecell-internationalize-common/ecell-internationalize-security/src/main/java/com/ecell/internationalize/common/security/annotation/Logical.java

@ -0,0 +1,18 @@ @@ -0,0 +1,18 @@
package com.ecell.internationalize.common.security.annotation;
/**
* @author borui
*/
public enum Logical {
/**
* 必须具有所有的元素
*/
AND,
/**
* 只需具有其中一个元素
*/
OR
}

15
ecell-internationalize/ecell-internationalize-common/ecell-internationalize-security/src/main/java/com/ecell/internationalize/common/security/annotation/RequiresLogin.java

@ -0,0 +1,15 @@ @@ -0,0 +1,15 @@
package com.ecell.internationalize.common.security.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* @author borui
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.METHOD, ElementType.TYPE })
public @interface RequiresLogin {
}

23
ecell-internationalize/ecell-internationalize-common/ecell-internationalize-security/src/main/java/com/ecell/internationalize/common/security/annotation/RequiresPermissions.java

@ -0,0 +1,23 @@ @@ -0,0 +1,23 @@
package com.ecell.internationalize.common.security.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* @author borui
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.METHOD, ElementType.TYPE })
public @interface RequiresPermissions {
/**
* 需要校验的权限码
*/
String[] value() default {};
/**
* 验证模式AND | OR默认AND
*/
Logical logical() default Logical.AND;
}

23
ecell-internationalize/ecell-internationalize-common/ecell-internationalize-security/src/main/java/com/ecell/internationalize/common/security/annotation/RequiresRoles.java

@ -0,0 +1,23 @@ @@ -0,0 +1,23 @@
package com.ecell.internationalize.common.security.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* @author borui
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.METHOD, ElementType.TYPE })
public @interface RequiresRoles {
/**
* 需要校验的角色标识
*/
String[] value() default {};
/**
* 验证逻辑AND | OR默认AND
*/
Logical logical() default Logical.AND;
}

44
ecell-internationalize/ecell-internationalize-common/ecell-internationalize-security/src/main/java/com/ecell/internationalize/common/security/aspect/InnerAuthAspect.java

@ -0,0 +1,44 @@ @@ -0,0 +1,44 @@
package com.ecell.internationalize.common.security.aspect;
import com.ecell.internationalize.common.core.constant.SecurityConstants;
import com.ecell.internationalize.common.core.exception.InnerAuthException;
import com.ecell.internationalize.common.core.utils.ServletUtils;
import com.ecell.internationalize.common.core.utils.StringUtils;
import com.ecell.internationalize.common.security.annotation.InnerAuth;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;
/**
* @author borui
*/
@Aspect
@Component
public class InnerAuthAspect implements Ordered {
@Around("@annotation(innerAuth)")
public Object innerAround(ProceedingJoinPoint point, InnerAuth innerAuth) throws Throwable
{
String source = ServletUtils.getRequest().getHeader(SecurityConstants.FROM_SOURCE);
// 内部请求验证
if (!StringUtils.equals(SecurityConstants.INNER, source))
{
throw new InnerAuthException("没有内部访问权限,不允许访问");
}
String userid = ServletUtils.getRequest().getHeader(SecurityConstants.DETAILS_USER_ID);
String username = ServletUtils.getRequest().getHeader(SecurityConstants.DETAILS_USERNAME);
// 用户信息验证
if (innerAuth.isUser() && (StringUtils.isEmpty(userid) || StringUtils.isEmpty(username)))
{
throw new InnerAuthException("没有设置用户信息,不允许访问 ");
}
return point.proceed();
}
@Override
public int getOrder() {
return Ordered.HIGHEST_PRECEDENCE + 1;
}
}

89
ecell-internationalize/ecell-internationalize-common/ecell-internationalize-security/src/main/java/com/ecell/internationalize/common/security/aspect/PreAuthorizeAspect.java

@ -0,0 +1,89 @@ @@ -0,0 +1,89 @@
package com.ecell.internationalize.common.security.aspect;
import com.ecell.internationalize.common.security.annotation.RequiresLogin;
import com.ecell.internationalize.common.security.annotation.RequiresPermissions;
import com.ecell.internationalize.common.security.annotation.RequiresRoles;
import com.ecell.internationalize.common.security.auth.AuthUtil;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import java.lang.reflect.Method;
/**
* @author borui
*/
@Aspect
@Component
public class PreAuthorizeAspect {
/**
* 定义AOP签名 (切入所有使用鉴权注解的方法)
*/
public static final String POINTCUT_SIGN = " @annotation(com.ecell.internationalize.common.security.annotation.RequiresLogin) || "
+ "@annotation(com.ecell.internationalize.common.security.annotation.RequiresPermissions) || "
+ "@annotation(com.ecell.internationalize.common.security.annotation.RequiresRoles)";
/**
* 声明AOP签名
*/
@Pointcut(POINTCUT_SIGN)
public void pointcut() {
}
/**
* 环绕切入
*
* @param joinPoint 切面对象
* @return 底层方法执行后的返回值
* @throws Throwable 底层方法抛出的异常
*/
@Around("pointcut()")
public Object around(ProceedingJoinPoint joinPoint) throws Throwable
{
// 注解鉴权
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
checkMethodAnnotation(signature.getMethod());
try
{
// 执行原有逻辑
Object obj = joinPoint.proceed();
return obj;
}
catch (Throwable e)
{
throw e;
}
}
/**
* 对一个Method对象进行注解检查
*/
public void checkMethodAnnotation(Method method)
{
// 校验 @RequiresLogin 注解
RequiresLogin requiresLogin = method.getAnnotation(RequiresLogin.class);
if (requiresLogin != null)
{
AuthUtil.checkLogin();
}
// 校验 @RequiresRoles 注解
RequiresRoles requiresRoles = method.getAnnotation(RequiresRoles.class);
if (requiresRoles != null)
{
AuthUtil.checkRole(requiresRoles);
}
// 校验 @RequiresPermissions 注解
RequiresPermissions requiresPermissions = method.getAnnotation(RequiresPermissions.class);
if (requiresPermissions != null)
{
AuthUtil.checkPermi(requiresPermissions);
}
}
}

371
ecell-internationalize/ecell-internationalize-common/ecell-internationalize-security/src/main/java/com/ecell/internationalize/common/security/auth/AuthLogic.java

@ -0,0 +1,371 @@ @@ -0,0 +1,371 @@
package com.ecell.internationalize.common.security.auth;
import com.ecell.internationalize.common.core.domain.LoginUser;
import com.ecell.internationalize.common.core.domain.SysUser;
import com.ecell.internationalize.common.core.exception.auth.NotLoginException;
import com.ecell.internationalize.common.core.exception.auth.NotPermissionException;
import com.ecell.internationalize.common.core.exception.auth.NotRoleException;
import com.ecell.internationalize.common.core.utils.SpringUtils;
import com.ecell.internationalize.common.core.utils.StringUtils;
import com.ecell.internationalize.common.security.annotation.Logical;
import com.ecell.internationalize.common.security.annotation.RequiresLogin;
import com.ecell.internationalize.common.security.annotation.RequiresPermissions;
import com.ecell.internationalize.common.security.annotation.RequiresRoles;
import com.ecell.internationalize.common.security.service.TokenService;
import com.ecell.internationalize.common.security.utils.SecurityUtils;
import org.springframework.util.PatternMatchUtils;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
/**
* @author borui
*/
public class AuthLogic {
/** 所有权限标识 */
private static final String ALL_PERMISSION = "*:*:*";
/** 管理员角色权限标识 */
private static final String SUPER_ADMIN = "admin";
public TokenService tokenService = SpringUtils.getBean(TokenService.class);
/**
* 会话注销
*/
public void logout()
{
String token = SecurityUtils.getToken();
if (token == null)
{
return;
}
logoutByToken(token);
}
/**
* 会话注销根据指定Token
*/
public void logoutByToken(String token)
{
tokenService.delLoginUser(token);
}
/**
* 检验用户是否已经登录如未登录则抛出异常
*/
public void checkLogin()
{
getLoginUser();
}
/**
* 获取当前用户缓存信息, 如果未登录则抛出异常
*
* @return 用户缓存信息
*/
public LoginUser getLoginUser()
{
String token = SecurityUtils.getToken();
if (token == null)
{
throw new NotLoginException("未提供token");
}
LoginUser loginUser = SecurityUtils.getLoginUser();
if (loginUser == null)
{
throw new NotLoginException("无效的token");
}
return loginUser;
}
/**
* 获取当前用户缓存信息, 如果未登录则抛出异常
*
* @param token 前端传递的认证信息
* @return 用户缓存信息
*/
public LoginUser getLoginUser(String token)
{
return tokenService.getLoginUser(token);
}
/**
* 验证当前用户有效期, 如果相差不足120分钟自动刷新缓存
*
* @param loginUser 当前用户信息
*/
public void verifyLoginUserExpire(LoginUser loginUser)
{
tokenService.verifyToken(loginUser);
}
/**
* 验证用户是否具备某权限
*
* @param permission 权限字符串
* @return 用户是否具备某权限
*/
public boolean hasPermi(String permission)
{
return hasPermi(getPermiList(), permission);
}
/**
* 验证用户是否具备某权限, 如果验证未通过则抛出异常: NotPermissionException
*
* @param permission 权限字符串
* @return 用户是否具备某权限
*/
public void checkPermi(String permission)
{
if (!hasPermi(getPermiList(), permission))
{
throw new NotPermissionException(permission);
}
}
/**
* 根据注解(@RequiresPermissions)鉴权, 如果验证未通过则抛出异常: NotPermissionException
*
* @param requiresPermissions 注解对象
*/
public void checkPermi(RequiresPermissions requiresPermissions)
{
if (requiresPermissions.logical() == Logical.AND)
{
checkPermiAnd(requiresPermissions.value());
}
else
{
checkPermiOr(requiresPermissions.value());
}
}
/**
* 验证用户是否含有指定权限必须全部拥有
*
* @param permissions 权限列表
*/
public void checkPermiAnd(String... permissions)
{
Set<String> permissionList = getPermiList();
for (String permission : permissions)
{
if (!hasPermi(permissionList, permission))
{
throw new NotPermissionException(permission);
}
}
}
/**
* 验证用户是否含有指定权限只需包含其中一个
*
* @param permissions 权限码数组
*/
public void checkPermiOr(String... permissions)
{
Set<String> permissionList = getPermiList();
for (String permission : permissions)
{
if (hasPermi(permissionList, permission))
{
return;
}
}
if (permissions.length > 0)
{
throw new NotPermissionException(permissions);
}
}
/**
* 判断用户是否拥有某个角色
*
* @param role 角色标识
* @return 用户是否具备某角色
*/
public boolean hasRole(String role)
{
return hasRole(getRoleList(), role);
}
/**
* 判断用户是否拥有某个角色, 如果验证未通过则抛出异常: NotRoleException
*
* @param role 角色标识
*/
public void checkRole(String role)
{
if (!hasRole(role))
{
throw new NotRoleException(role);
}
}
/**
* 根据注解(@RequiresRoles)鉴权
*
* @param requiresRoles 注解对象
*/
public void checkRole(RequiresRoles requiresRoles)
{
if (requiresRoles.logical() == Logical.AND)
{
checkRoleAnd(requiresRoles.value());
}
else
{
checkRoleOr(requiresRoles.value());
}
}
/**
* 验证用户是否含有指定角色必须全部拥有
*
* @param roles 角色标识数组
*/
public void checkRoleAnd(String... roles)
{
Set<String> roleList = getRoleList();
for (String role : roles)
{
if (!hasRole(roleList, role))
{
throw new NotRoleException(role);
}
}
}
/**
* 验证用户是否含有指定角色只需包含其中一个
*
* @param roles 角色标识数组
*/
public void checkRoleOr(String... roles)
{
Set<String> roleList = getRoleList();
for (String role : roles)
{
if (hasRole(roleList, role))
{
return;
}
}
if (roles.length > 0)
{
throw new NotRoleException(roles);
}
}
/**
* 根据注解(@RequiresLogin)鉴权
*
* @param at 注解对象
*/
public void checkByAnnotation(RequiresLogin at)
{
this.checkLogin();
}
/**
* 根据注解(@RequiresRoles)鉴权
*
* @param at 注解对象
*/
public void checkByAnnotation(RequiresRoles at)
{
String[] roleArray = at.value();
if (at.logical() == Logical.AND)
{
this.checkRoleAnd(roleArray);
}
else
{
this.checkRoleOr(roleArray);
}
}
/**
* 根据注解(@RequiresPermissions)鉴权
*
* @param at 注解对象
*/
public void checkByAnnotation(RequiresPermissions at)
{
String[] permissionArray = at.value();
if (at.logical() == Logical.AND)
{
this.checkPermiAnd(permissionArray);
}
else
{
this.checkPermiOr(permissionArray);
}
}
/**
* 获取当前账号的角色列表
*
* @return 角色列表
*/
public Set<String> getRoleList()
{
try
{
LoginUser loginUser = getLoginUser();
return loginUser.getRoles();
}
catch (Exception e)
{
return new HashSet<>();
}
}
/**
* 获取当前账号的权限列表
*
* @return 权限列表
*/
public Set<String> getPermiList()
{
try
{
LoginUser loginUser = getLoginUser();
return loginUser.getPermissions();
}
catch (Exception e)
{
return new HashSet<>();
}
}
/**
* 判断是否包含权限
*
* @param authorities 权限列表
* @param permission 权限字符串
* @return 用户是否具备某权限
*/
public boolean hasPermi(Collection<String> authorities, String permission)
{
return authorities.stream().filter(StringUtils::hasText)
.anyMatch(x -> ALL_PERMISSION.contains(x) || PatternMatchUtils.simpleMatch(x, permission));
}
/**
* 判断是否包含角色
*
* @param roles 角色列表
* @param role 角色
* @return 用户是否具备某角色权限
*/
public boolean hasRole(Collection<String> roles, String role)
{
return roles.stream().filter(StringUtils::hasText)
.anyMatch(x -> SUPER_ADMIN.contains(x) || PatternMatchUtils.simpleMatch(x, role));
}
}

161
ecell-internationalize/ecell-internationalize-common/ecell-internationalize-security/src/main/java/com/ecell/internationalize/common/security/auth/AuthUtil.java

@ -0,0 +1,161 @@ @@ -0,0 +1,161 @@
package com.ecell.internationalize.common.security.auth;
import com.ecell.internationalize.common.core.domain.LoginUser;
import com.ecell.internationalize.common.core.domain.SysUser;
import com.ecell.internationalize.common.security.annotation.RequiresPermissions;
import com.ecell.internationalize.common.security.annotation.RequiresRoles;
/**
* @author borui
*/
public class AuthUtil {
/**
* 底层的 AuthLogic 对象
*/
public static AuthLogic authLogic = new AuthLogic();
/**
* 会话注销
*/
public static void logout()
{
authLogic.logout();
}
/**
* 会话注销根据指定Token
*
* @param tokenValue 指定token
*/
public static void logoutByToken(String token)
{
authLogic.logoutByToken(token);
}
/**
* 检验当前会话是否已经登录如未登录则抛出异常
*/
public static void checkLogin()
{
authLogic.checkLogin();
}
/**
* 获取当前登录用户信息
*/
public static LoginUser getLoginUser(String token)
{
return authLogic.getLoginUser(token);
}
/**
* 验证当前用户有效期
*/
public static void verifyLoginUserExpire(LoginUser loginUser)
{
authLogic.verifyLoginUserExpire(loginUser);
}
/**
* 当前账号是否含有指定角色标识, 返回true或false
*
* @param role 角色标识
* @return 是否含有指定角色标识
*/
public static boolean hasRole(String role)
{
return authLogic.hasRole(role);
}
/**
* 当前账号是否含有指定角色标识, 如果验证未通过则抛出异常: NotRoleException
*
* @param role 角色标识
*/
public static void checkRole(String role)
{
authLogic.checkRole(role);
}
/**
* 根据注解传入参数鉴权, 如果验证未通过则抛出异常: NotRoleException
*
* @param requiresRoles 角色权限注解
*/
public static void checkRole(RequiresRoles requiresRoles)
{
authLogic.checkRole(requiresRoles);
}
/**
* 当前账号是否含有指定角色标识 [指定多个必须全部验证通过]
*
* @param roles 角色标识数组
*/
public static void checkRoleAnd(String... roles)
{
authLogic.checkRoleAnd(roles);
}
/**
* 当前账号是否含有指定角色标识 [指定多个只要其一验证通过即可]
*
* @param roles 角色标识数组
*/
public static void checkRoleOr(String... roles)
{
authLogic.checkRoleOr(roles);
}
/**
* 当前账号是否含有指定权限, 返回true或false
*
* @param permission 权限码
* @return 是否含有指定权限
*/
public static boolean hasPermi(String permission)
{
return authLogic.hasPermi(permission);
}
/**
* 当前账号是否含有指定权限, 如果验证未通过则抛出异常: NotPermissionException
*
* @param permission 权限码
*/
public static void checkPermi(String permission)
{
authLogic.checkPermi(permission);
}
/**
* 根据注解传入参数鉴权, 如果验证未通过则抛出异常: NotPermissionException
*
* @param requiresPermissions 权限注解
*/
public static void checkPermi(RequiresPermissions requiresPermissions)
{
authLogic.checkPermi(requiresPermissions);
}
/**
* 当前账号是否含有指定权限 [指定多个必须全部验证通过]
*
* @param permissions 权限码数组
*/
public static void checkPermiAnd(String... permissions)
{
authLogic.checkPermiAnd(permissions);
}
/**
* 当前账号是否含有指定权限 [指定多个只要其一验证通过即可]
*
* @param permissions 权限码数组
*/
public static void checkPermiOr(String... permissions)
{
authLogic.checkPermiOr(permissions);
}
}

20
ecell-internationalize/ecell-internationalize-common/ecell-internationalize-security/src/main/java/com/ecell/internationalize/common/security/config/ApplicationConfig.java

@ -0,0 +1,20 @@ @@ -0,0 +1,20 @@
package com.ecell.internationalize.common.security.config;
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
import org.springframework.context.annotation.Bean;
import java.util.TimeZone;
/**
* @author borui
*/
public class ApplicationConfig {
/**
* 时区配置
*/
@Bean
public Jackson2ObjectMapperBuilderCustomizer jacksonObjectMapperCustomization()
{
return jacksonObjectMapperBuilder -> jacksonObjectMapperBuilder.timeZone(TimeZone.getDefault());
}
}

30
ecell-internationalize/ecell-internationalize-common/ecell-internationalize-security/src/main/java/com/ecell/internationalize/common/security/config/WebMvcConfig.java

@ -0,0 +1,30 @@ @@ -0,0 +1,30 @@
package com.ecell.internationalize.common.security.config;
import com.ecell.internationalize.common.security.interceptor.HeaderInterceptor;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
/**
* @author borui
*/
public class WebMvcConfig implements WebMvcConfigurer {
/** 不需要拦截地址 */
public static final String[] excludeUrls = { "/login", "/logout", "/refresh" };
@Override
public void addInterceptors(InterceptorRegistry registry)
{
registry.addInterceptor(getHeaderInterceptor())
.addPathPatterns("/**")
.excludePathPatterns(excludeUrls)
.order(-10);
}
/**
* 自定义请求头拦截器
*/
public HeaderInterceptor getHeaderInterceptor()
{
return new HeaderInterceptor();
}
}

17
ecell-internationalize/ecell-internationalize-common/ecell-internationalize-security/src/main/java/com/ecell/internationalize/common/security/feign/FeignAutoConfiguration.java

@ -0,0 +1,17 @@ @@ -0,0 +1,17 @@
package com.ecell.internationalize.common.security.feign;
import feign.RequestInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @author borui
*/
@Configuration
public class FeignAutoConfiguration {
@Bean
public RequestInterceptor requestInterceptor()
{
return new FeignRequestInterceptor();
}
}

48
ecell-internationalize/ecell-internationalize-common/ecell-internationalize-security/src/main/java/com/ecell/internationalize/common/security/feign/FeignRequestInterceptor.java

@ -0,0 +1,48 @@ @@ -0,0 +1,48 @@
package com.ecell.internationalize.common.security.feign;
import com.ecell.internationalize.common.core.constant.SecurityConstants;
import com.ecell.internationalize.common.core.utils.ServletUtils;
import com.ecell.internationalize.common.core.utils.StringUtils;
import com.ecell.internationalize.common.core.utils.ip.IpUtils;
import feign.RequestInterceptor;
import feign.RequestTemplate;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
import java.util.Map;
/**
* @author borui
*/
@Component
public class FeignRequestInterceptor implements RequestInterceptor {
@Override
public void apply(RequestTemplate requestTemplate)
{
HttpServletRequest httpServletRequest = ServletUtils.getRequest();
if (StringUtils.isNotNull(httpServletRequest))
{
Map<String, String> headers = ServletUtils.getHeaders(httpServletRequest);
// 传递用户信息请求头,防止丢失
String userId = headers.get(SecurityConstants.DETAILS_USER_ID);
if (StringUtils.isNotEmpty(userId))
{
requestTemplate.header(SecurityConstants.DETAILS_USER_ID, userId);
}
String userName = headers.get(SecurityConstants.DETAILS_USERNAME);
if (StringUtils.isNotEmpty(userName))
{
requestTemplate.header(SecurityConstants.DETAILS_USERNAME, userName);
}
String authentication = headers.get(SecurityConstants.AUTHORIZATION_HEADER);
if (StringUtils.isNotEmpty(authentication))
{
requestTemplate.header(SecurityConstants.AUTHORIZATION_HEADER, authentication);
}
// 配置客户端IP
requestTemplate.header("X-Forwarded-For", IpUtils.getIpAddr(ServletUtils.getRequest()));
}
}
}

125
ecell-internationalize/ecell-internationalize-common/ecell-internationalize-security/src/main/java/com/ecell/internationalize/common/security/handler/GlobalExceptionHandler.java

@ -0,0 +1,125 @@ @@ -0,0 +1,125 @@
package com.ecell.internationalize.common.security.handler;
import com.ecell.internationalize.common.core.constant.HttpStatus;
import com.ecell.internationalize.common.core.exception.InnerAuthException;
import com.ecell.internationalize.common.core.exception.ServiceException;
import com.ecell.internationalize.common.core.exception.auth.NotPermissionException;
import com.ecell.internationalize.common.core.exception.auth.NotRoleException;
import com.ecell.internationalize.common.core.utils.StringUtils;
import com.ecell.internationalize.common.core.web.domain.AjaxResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.validation.BindException;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import javax.servlet.http.HttpServletRequest;
/**
* @author borui
*/
@RestControllerAdvice
public class GlobalExceptionHandler {
private static final Logger log = LoggerFactory.getLogger(GlobalExceptionHandler.class);
/**
* 权限码异常
*/
@ExceptionHandler(NotPermissionException.class)
public AjaxResult handleNotPermissionException(NotPermissionException e, HttpServletRequest request)
{
String requestURI = request.getRequestURI();
log.error("请求地址'{}',权限码校验失败'{}'", requestURI, e.getMessage());
return AjaxResult.error(HttpStatus.FORBIDDEN, "没有访问权限,请联系管理员授权");
}
/**
* 角色权限异常
*/
@ExceptionHandler(NotRoleException.class)
public AjaxResult handleNotRoleException(NotRoleException e, HttpServletRequest request)
{
String requestURI = request.getRequestURI();
log.error("请求地址'{}',角色权限校验失败'{}'", requestURI, e.getMessage());
return AjaxResult.error(HttpStatus.FORBIDDEN, "没有访问权限,请联系管理员授权");
}
/**
* 请求方式不支持
*/
@ExceptionHandler(HttpRequestMethodNotSupportedException.class)
public AjaxResult handleHttpRequestMethodNotSupported(HttpRequestMethodNotSupportedException e,
HttpServletRequest request)
{
String requestURI = request.getRequestURI();
log.error("请求地址'{}',不支持'{}'请求", requestURI, e.getMethod());
return AjaxResult.error(e.getMessage());
}
/**
* 业务异常
*/
@ExceptionHandler(ServiceException.class)
public AjaxResult handleServiceException(ServiceException e, HttpServletRequest request)
{
log.error(e.getMessage(), e);
Integer code = e.getCode();
return StringUtils.isNotNull(code) ? AjaxResult.error(code, e.getMessage()) : AjaxResult.error(e.getMessage());
}
/**
* 拦截未知的运行时异常
*/
@ExceptionHandler(RuntimeException.class)
public AjaxResult handleRuntimeException(RuntimeException e, HttpServletRequest request)
{
String requestURI = request.getRequestURI();
log.error("请求地址'{}',发生未知异常.", requestURI, e);
return AjaxResult.error(e.getMessage());
}
/**
* 系统异常
*/
@ExceptionHandler(Exception.class)
public AjaxResult handleException(Exception e, HttpServletRequest request)
{
String requestURI = request.getRequestURI();
log.error("请求地址'{}',发生系统异常.", requestURI, e);
return AjaxResult.error(e.getMessage());
}
/**
* 自定义验证异常
*/
@ExceptionHandler(BindException.class)
public AjaxResult handleBindException(BindException e)
{
log.error(e.getMessage(), e);
String message = e.getAllErrors().get(0).getDefaultMessage();
return AjaxResult.error(message);
}
/**
* 自定义验证异常
*/
@ExceptionHandler(MethodArgumentNotValidException.class)
public Object handleMethodArgumentNotValidException(MethodArgumentNotValidException e)
{
log.error(e.getMessage(), e);
String message = e.getBindingResult().getFieldError().getDefaultMessage();
return AjaxResult.error(message);
}
/**
* 内部认证异常
*/
@ExceptionHandler(InnerAuthException.class)
public AjaxResult handleInnerAuthException(InnerAuthException e)
{
return AjaxResult.error(e.getMessage());
}
}

52
ecell-internationalize/ecell-internationalize-common/ecell-internationalize-security/src/main/java/com/ecell/internationalize/common/security/interceptor/HeaderInterceptor.java

@ -0,0 +1,52 @@ @@ -0,0 +1,52 @@
package com.ecell.internationalize.common.security.interceptor;
import com.ecell.internationalize.common.core.constant.SecurityConstants;
import com.ecell.internationalize.common.core.context.SecurityContextHolder;
import com.ecell.internationalize.common.core.domain.LoginUser;
import com.ecell.internationalize.common.core.utils.ServletUtils;
import com.ecell.internationalize.common.core.utils.StringUtils;
import com.ecell.internationalize.common.security.auth.AuthUtil;
import com.ecell.internationalize.common.security.utils.SecurityUtils;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.AsyncHandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* @author borui
*/
public class HeaderInterceptor implements AsyncHandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception
{
if (!(handler instanceof HandlerMethod))
{
return true;
}
SecurityContextHolder.setUserId(ServletUtils.getHeader(request, SecurityConstants.DETAILS_USER_ID));
SecurityContextHolder.setUserName(ServletUtils.getHeader(request, SecurityConstants.DETAILS_USERNAME));
SecurityContextHolder.setUserKey(ServletUtils.getHeader(request, SecurityConstants.USER_KEY));
String token = SecurityUtils.getToken();
if (StringUtils.isNotEmpty(token))
{
LoginUser loginUser = AuthUtil.getLoginUser(token);
if (StringUtils.isNotNull(loginUser))
{
AuthUtil.verifyLoginUserExpire(loginUser);
SecurityContextHolder.set(SecurityConstants.LOGIN_USER, loginUser);
}
}
return true;
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
throws Exception
{
SecurityContextHolder.remove();
}
}

170
ecell-internationalize/ecell-internationalize-common/ecell-internationalize-security/src/main/java/com/ecell/internationalize/common/security/service/TokenService.java

@ -0,0 +1,170 @@ @@ -0,0 +1,170 @@
package com.ecell.internationalize.common.security.service;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.ecell.internationalize.common.core.constant.CacheConstants;
import com.ecell.internationalize.common.core.constant.SecurityConstants;
import com.ecell.internationalize.common.core.domain.LoginUser;
import com.ecell.internationalize.common.core.domain.SysUser;
import com.ecell.internationalize.common.core.utils.JwtUtils;
import com.ecell.internationalize.common.core.utils.ServletUtils;
import com.ecell.internationalize.common.core.utils.StringUtils;
import com.ecell.internationalize.common.core.utils.ip.IpUtils;
import com.ecell.internationalize.common.core.utils.uuid.IdUtils;
import com.ecell.internationalize.common.redis.service.RedisService;
import com.ecell.internationalize.common.security.utils.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
/**
* @author borui
*/
@Component
public class TokenService {
@Autowired
private RedisService redisService;
protected static final long MILLIS_SECOND = 1000;
protected static final long MILLIS_MINUTE = 60 * MILLIS_SECOND;
private final static long expireTime = CacheConstants.EXPIRATION;
private final static String ACCESS_TOKEN = CacheConstants.LOGIN_TOKEN_KEY;
private final static Long MILLIS_MINUTE_TEN = CacheConstants.REFRESH_TIME * MILLIS_MINUTE;
/**
* 创建令牌
*/
public Map<String, Object> createToken(LoginUser loginUser)
{
String token = IdUtils.fastUUID();
Long userId = loginUser.getSysUser().getUserId();
String userName = loginUser.getSysUser().getUserName();
loginUser.setToken(token);
loginUser.setUserid(userId);
loginUser.setUsername(userName);
loginUser.setIpaddr(IpUtils.getIpAddr(ServletUtils.getRequest()));
refreshToken(loginUser);
// Jwt存储信息
Map<String, Object> claimsMap = new HashMap<String, Object>();
claimsMap.put(SecurityConstants.USER_KEY, token);
claimsMap.put(SecurityConstants.DETAILS_USER_ID, userId);
claimsMap.put(SecurityConstants.DETAILS_USERNAME, userName);
// 接口返回信息
Map<String, Object> rspMap = new HashMap<String, Object>();
rspMap.put("access_token", JwtUtils.createToken(claimsMap));
rspMap.put("expires_in", expireTime);
return rspMap;
}
/**
* 获取用户身份信息
*
* @return 用户信息
*/
public LoginUser getLoginUser()
{
return getLoginUser(ServletUtils.getRequest());
}
/**
* 获取用户身份信息
*
* @return 用户信息
*/
public LoginUser getLoginUser(HttpServletRequest request)
{
// 获取请求携带的令牌
String token = SecurityUtils.getToken(request);
return getLoginUser(token);
}
/**
* 获取用户身份信息
*
* @return 用户信息
*/
public LoginUser getLoginUser(String token)
{
LoginUser user = null;
try
{
if (StringUtils.isNotEmpty(token))
{
String userkey = JwtUtils.getUserKey(token);
user = redisService.getCacheObject(getTokenKey(userkey));
return user;
}
}
catch (Exception e)
{
}
return user;
}
/**
* 设置用户身份信息
*/
public void setLoginUser(LoginUser loginUser)
{
if (StringUtils.isNotNull(loginUser) && StringUtils.isNotEmpty(loginUser.getToken()))
{
refreshToken(loginUser);
}
}
/**
* 删除用户缓存信息
*/
public void delLoginUser(String token)
{
if (StringUtils.isNotEmpty(token))
{
String userkey = JwtUtils.getUserKey(token);
redisService.deleteObject(getTokenKey(userkey));
}
}
/**
* 验证令牌有效期相差不足120分钟自动刷新缓存
*
* @param loginUser
*/
public void verifyToken(LoginUser loginUser)
{
long expireTime = loginUser.getExpireTime();
long currentTime = System.currentTimeMillis();
if (expireTime - currentTime <= MILLIS_MINUTE_TEN)
{
refreshToken(loginUser);
}
}
/**
* 刷新令牌有效期
*
* @param loginUser 登录信息
*/
public void refreshToken(LoginUser loginUser)
{
loginUser.setLoginTime(System.currentTimeMillis());
loginUser.setExpireTime(loginUser.getLoginTime() + expireTime * MILLIS_MINUTE);
// 根据uuid将loginUser缓存
String userKey = getTokenKey(loginUser.getToken());
redisService.setCacheObject(userKey, loginUser, expireTime, TimeUnit.MINUTES);
}
private String getTokenKey(String token)
{
return ACCESS_TOKEN + token;
}
}

159
ecell-internationalize/ecell-internationalize-common/ecell-internationalize-security/src/main/java/com/ecell/internationalize/common/security/utils/SecurityUtils.java

@ -0,0 +1,159 @@ @@ -0,0 +1,159 @@
package com.ecell.internationalize.common.security.utils;
import com.ecell.internationalize.common.core.constant.SecurityConstants;
import com.ecell.internationalize.common.core.constant.TokenConstants;
import com.ecell.internationalize.common.core.context.SecurityContextHolder;
import com.ecell.internationalize.common.core.domain.LoginUser;
import com.ecell.internationalize.common.core.domain.SysUser;
import com.ecell.internationalize.common.core.utils.ServletUtils;
import com.ecell.internationalize.common.core.utils.StringUtils;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import javax.servlet.http.HttpServletRequest;
/**
* @author borui
*/
public class SecurityUtils {
/**
* 获取用户ID
*/
public static Long getUserId()
{
return SecurityContextHolder.getUserId();
}
/**
* yisai获取用户ID
*/
public static String getStringUserId()
{
return SecurityContextHolder.getStringUserId();
}
/**
* 获取用户名称
*/
public static String getUsername()
{
return SecurityContextHolder.getUserName();
}
/**
* 获取用户key
*/
public static String getUserKey()
{
return SecurityContextHolder.getUserKey();
}
/**
* 获取登录用户信息
*/
public static LoginUser getLoginUser()
{
return SecurityContextHolder.get(SecurityConstants.LOGIN_USER, LoginUser.class);
}
/**
* 获取请求token
*/
public static String getToken()
{
return getToken(ServletUtils.getRequest());
}
/**
* 根据request获取请求token
*/
public static String getToken(HttpServletRequest request)
{
// 从header获取token标识
String token = request.getHeader(TokenConstants.AUTHENTICATION);
return replaceTokenPrefix(token);
}
/**
* 裁剪token前缀
*/
public static String replaceTokenPrefix(String token)
{
// 如果前端设置了令牌前缀,则裁剪掉前缀
if (StringUtils.isNotEmpty(token) && token.startsWith(TokenConstants.PREFIX))
{
token = token.replaceFirst(TokenConstants.PREFIX, "");
}
return token;
}
/**
* 是否为管理员
*
* @param userId 用户ID
* @return 结果
*/
public static boolean isAdmin(Long userId)
{
return userId != null && 1L == userId;
}
/**
* yisai是否为管理员
*
* @param userId 用户ID
* @return 结果
*/
public static boolean isAdminString(String userId)
{
return userId != null && "1".equals(userId);
}
/**
* yisai是否为厂商
*
* @param firmFlag
* @return 结果
*/
public static boolean isFirm(String firmFlag)
{
return firmFlag != null && "1".equals(firmFlag);
}
/**
* yisai是否为代理商
* @param firmFlag
* @return 结果
*/
public static boolean isAgent(String firmFlag)
{
return firmFlag != null && "2".equals(firmFlag);
}
/**
* 生成BCryptPasswordEncoder密码
*
* @param password 密码
* @return 加密字符串
*/
public static String encryptPassword(String password)
{
BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
return passwordEncoder.encode(password);
}
/**
* 判断密码是否相同
*
* @param rawPassword 真实密码
* @param encodedPassword 加密后字符
* @return 结果
*/
public static boolean matchesPassword(String rawPassword, String encodedPassword)
{
BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
return passwordEncoder.matches(rawPassword, encodedPassword);
}
}

17
ecell-internationalize/ecell-internationalize-common/ecell-internationalize-swagger/pom.xml

@ -17,4 +17,21 @@ @@ -17,4 +17,21 @@
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencies>
<!-- SpringBoot Web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Swagger -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>${swagger.fox.version}</version>
</dependency>
</dependencies>
</project>

18
ecell-internationalize/ecell-internationalize-common/ecell-internationalize-swagger/src/main/java/com/ecell/internationalize/common/swagger/annotation/EnableCustomSwagger2.java

@ -0,0 +1,18 @@ @@ -0,0 +1,18 @@
package com.ecell.internationalize.common.swagger.annotation;
import com.ecell.internationalize.common.swagger.config.SwaggerAutoConfiguration;
import org.springframework.context.annotation.Import;
import java.lang.annotation.*;
/**
* @author borui
*/
@Target({ ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Import({ SwaggerAutoConfiguration.class })
public @interface EnableCustomSwagger2 {
}

128
ecell-internationalize/ecell-internationalize-common/ecell-internationalize-swagger/src/main/java/com/ecell/internationalize/common/swagger/config/SwaggerAutoConfiguration.java

@ -0,0 +1,128 @@ @@ -0,0 +1,128 @@
package com.ecell.internationalize.common.swagger.config;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.*;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spi.service.contexts.SecurityContext;
import springfox.documentation.spring.web.plugins.ApiSelectorBuilder;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.function.Predicate;
/**
* @author borui
*/
@Configuration
@EnableSwagger2
@EnableAutoConfiguration
@ConditionalOnProperty(name = "swagger.enabled", matchIfMissing = true)
public class SwaggerAutoConfiguration {
/**
* 默认的排除路径排除Spring Boot默认的错误处理路径和端点
*/
private static final List<String> DEFAULT_EXCLUDE_PATH = Arrays.asList("/error", "/actuator/**");
private static final String BASE_PATH = "/**";
@Bean
@ConditionalOnMissingBean
public SwaggerProperties swaggerProperties()
{
return new SwaggerProperties();
}
@Bean
public Docket api(SwaggerProperties swaggerProperties)
{
// base-path处理
if (swaggerProperties.getBasePath().isEmpty())
{
swaggerProperties.getBasePath().add(BASE_PATH);
}
// noinspection unchecked
List<Predicate<String>> basePath = new ArrayList<Predicate<String>>();
swaggerProperties.getBasePath().forEach(path -> basePath.add(PathSelectors.ant(path)));
// exclude-path处理
if (swaggerProperties.getExcludePath().isEmpty())
{
swaggerProperties.getExcludePath().addAll(DEFAULT_EXCLUDE_PATH);
}
List<Predicate<String>> excludePath = new ArrayList<>();
swaggerProperties.getExcludePath().forEach(path -> excludePath.add(PathSelectors.ant(path)));
ApiSelectorBuilder builder = new Docket(DocumentationType.SWAGGER_2).host(swaggerProperties.getHost())
.apiInfo(apiInfo(swaggerProperties)).select()
.apis(RequestHandlerSelectors.basePackage(swaggerProperties.getBasePackage()));
swaggerProperties.getBasePath().forEach(p -> builder.paths(PathSelectors.ant(p)));
swaggerProperties.getExcludePath().forEach(p -> builder.paths(PathSelectors.ant(p).negate()));
return builder.build().securitySchemes(securitySchemes()).securityContexts(securityContexts()).pathMapping("/");
}
/**
* 安全模式这里指定token通过Authorization头请求头传递
*/
private List<SecurityScheme> securitySchemes()
{
List<SecurityScheme> apiKeyList = new ArrayList<SecurityScheme>();
apiKeyList.add(new ApiKey("Authorization", "Authorization", "header"));
return apiKeyList;
}
/**
* 安全上下文
*/
private List<SecurityContext> securityContexts()
{
List<SecurityContext> securityContexts = new ArrayList<>();
securityContexts.add(
SecurityContext.builder()
.securityReferences(defaultAuth())
.operationSelector(o -> o.requestMappingPattern().matches("/.*"))
.build());
return securityContexts;
}
/**
* 默认的全局鉴权策略
*
* @return
*/
private List<SecurityReference> defaultAuth()
{
AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything");
AuthorizationScope[] authorizationScopes = new AuthorizationScope[1];
authorizationScopes[0] = authorizationScope;
List<SecurityReference> securityReferences = new ArrayList<>();
securityReferences.add(new SecurityReference("Authorization", authorizationScopes));
return securityReferences;
}
private ApiInfo apiInfo(SwaggerProperties swaggerProperties)
{
return new ApiInfoBuilder()
.title(swaggerProperties.getTitle())
.description(swaggerProperties.getDescription())
.license(swaggerProperties.getLicense())
.licenseUrl(swaggerProperties.getLicenseUrl())
.termsOfServiceUrl(swaggerProperties.getTermsOfServiceUrl())
.contact(new Contact(swaggerProperties.getContact().getName(), swaggerProperties.getContact().getUrl(), swaggerProperties.getContact().getEmail()))
.version(swaggerProperties.getVersion())
.build();
}
}

45
ecell-internationalize/ecell-internationalize-common/ecell-internationalize-swagger/src/main/java/com/ecell/internationalize/common/swagger/config/SwaggerBeanPostProcessor.java

@ -0,0 +1,45 @@ @@ -0,0 +1,45 @@
package com.ecell.internationalize.common.swagger.config;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.stereotype.Component;
import org.springframework.util.ReflectionUtils;
import org.springframework.web.servlet.mvc.method.RequestMappingInfoHandlerMapping;
import springfox.documentation.spring.web.plugins.WebFluxRequestHandlerProvider;
import springfox.documentation.spring.web.plugins.WebMvcRequestHandlerProvider;
import java.lang.reflect.Field;
import java.util.List;
import java.util.stream.Collectors;
/**
* @author borui
*/
@Component
public class SwaggerBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (bean instanceof WebMvcRequestHandlerProvider || bean instanceof WebFluxRequestHandlerProvider) {
customizeSpringfoxHandlerMappings(getHandlerMappings(bean));
}
return bean;
}
private <T extends RequestMappingInfoHandlerMapping> void customizeSpringfoxHandlerMappings(List<T> mappings) {
List<T> copy = mappings.stream().filter(mapping -> mapping.getPatternParser() == null)
.collect(Collectors.toList());
mappings.clear();
mappings.addAll(copy);
}
@SuppressWarnings("unchecked")
private List<RequestMappingInfoHandlerMapping> getHandlerMappings(Object bean) {
try {
Field field = ReflectionUtils.findField(bean.getClass(), "handlerMappings");
field.setAccessible(true);
return (List<RequestMappingInfoHandlerMapping>) field.get(bean);
} catch (IllegalArgumentException | IllegalAccessException e) {
throw new IllegalStateException(e);
}
}
}

301
ecell-internationalize/ecell-internationalize-common/ecell-internationalize-swagger/src/main/java/com/ecell/internationalize/common/swagger/config/SwaggerProperties.java

@ -0,0 +1,301 @@ @@ -0,0 +1,301 @@
package com.ecell.internationalize.common.swagger.config;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.List;
/**
* @author borui
*/
@Component
@ConfigurationProperties("swagger")
public class SwaggerProperties {
/**
* 是否开启swagger
*/
private Boolean enabled;
/**
* swagger会解析的包路径
**/
private String basePackage = "";
/**
* swagger会解析的url规则
**/
private List<String> basePath = new ArrayList<>();
/**
* 在basePath基础上需要排除的url规则
**/
private List<String> excludePath = new ArrayList<>();
/**
* 标题
**/
private String title = "";
/**
* 描述
**/
private String description = "";
/**
* 版本
**/
private String version = "";
/**
* 许可证
**/
private String license = "";
/**
* 许可证URL
**/
private String licenseUrl = "";
/**
* 服务条款URL
**/
private String termsOfServiceUrl = "";
/**
* host信息
**/
private String host = "";
/**
* 联系人信息
*/
private Contact contact = new Contact();
/**
* 全局统一鉴权配置
**/
private Authorization authorization = new Authorization();
public Boolean getEnabled() {
return enabled;
}
public void setEnabled(Boolean enabled) {
this.enabled = enabled;
}
public String getBasePackage() {
return basePackage;
}
public void setBasePackage(String basePackage) {
this.basePackage = basePackage;
}
public List<String> getBasePath() {
return basePath;
}
public void setBasePath(List<String> basePath) {
this.basePath = basePath;
}
public List<String> getExcludePath() {
return excludePath;
}
public void setExcludePath(List<String> excludePath) {
this.excludePath = excludePath;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getVersion() {
return version;
}
public void setVersion(String version) {
this.version = version;
}
public String getLicense() {
return license;
}
public void setLicense(String license) {
this.license = license;
}
public String getLicenseUrl() {
return licenseUrl;
}
public void setLicenseUrl(String licenseUrl) {
this.licenseUrl = licenseUrl;
}
public String getTermsOfServiceUrl() {
return termsOfServiceUrl;
}
public void setTermsOfServiceUrl(String termsOfServiceUrl) {
this.termsOfServiceUrl = termsOfServiceUrl;
}
public String getHost() {
return host;
}
public void setHost(String host) {
this.host = host;
}
public Contact getContact() {
return contact;
}
public void setContact(Contact contact) {
this.contact = contact;
}
public Authorization getAuthorization() {
return authorization;
}
public void setAuthorization(Authorization authorization) {
this.authorization = authorization;
}
public static class Contact {
/**
* 联系人
**/
private String name = "";
/**
* 联系人url
**/
private String url = "";
/**
* 联系人email
**/
private String email = "";
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
public static class Authorization {
/**
* 鉴权策略ID需要和SecurityReferences ID保持一致
*/
private String name = "";
/**
* 需要开启鉴权URL的正则
*/
private String authRegex = "^.*$";
/**
* 鉴权作用域列表
*/
private List<AuthorizationScope> authorizationScopeList = new ArrayList<>();
private List<String> tokenUrlList = new ArrayList<>();
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAuthRegex() {
return authRegex;
}
public void setAuthRegex(String authRegex) {
this.authRegex = authRegex;
}
public List<AuthorizationScope> getAuthorizationScopeList() {
return authorizationScopeList;
}
public void setAuthorizationScopeList(List<AuthorizationScope> authorizationScopeList) {
this.authorizationScopeList = authorizationScopeList;
}
public List<String> getTokenUrlList() {
return tokenUrlList;
}
public void setTokenUrlList(List<String> tokenUrlList) {
this.tokenUrlList = tokenUrlList;
}
}
public static class AuthorizationScope {
/**
* 作用域名称
*/
private String scope = "";
/**
* 作用域描述
*/
private String description = "";
public String getScope() {
return scope;
}
public void setScope(String scope) {
this.scope = scope;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
}
}

20
ecell-internationalize/ecell-internationalize-common/ecell-internationalize-swagger/src/main/java/com/ecell/internationalize/common/swagger/config/SwaggerWebConfiguration.java

@ -0,0 +1,20 @@ @@ -0,0 +1,20 @@
package com.ecell.internationalize.common.swagger.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
/**
* @author borui
*/
@Configuration
public class SwaggerWebConfiguration implements WebMvcConfigurer {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry)
{
/** swagger-ui 地址 */
registry.addResourceHandler("/swagger-ui/**")
.addResourceLocations("classpath:/META-INF/resources/webjars/springfox-swagger-ui/");
}
}

1
ecell-internationalize/pom.xml

@ -12,6 +12,7 @@ @@ -12,6 +12,7 @@
<module>ecell-internationalize-app</module>
<module>ecell-internationalize-common</module>
<module>ecell-internationalize-gateway</module>
<module>ecell-internationalize-auth</module>
</modules>
<properties>

Loading…
Cancel
Save