diff --git a/pom.xml b/pom.xml
index d2bc6c5..502101a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -13,6 +13,7 @@
qiaoba-apis
qiaoba-commons
qiaoba-application
+ qiaoba-auth
@@ -104,6 +105,11 @@
+
+ com.qiaoba
+ qiaoba-auth
+ ${qiaoba.version}
+
com.qiaoba
qiaoba-common-base
@@ -136,12 +142,12 @@
com.qiaoba
- qiaoba-common-security
+ qiaoba-common-poi
${qiaoba.version}
com.qiaoba
- qiaoba-common-poi
+ qiaoba-common-redis
${qiaoba.version}
diff --git a/qiaoba-apis/pom.xml b/qiaoba-apis/pom.xml
index b74aa80..d2d497c 100644
--- a/qiaoba-apis/pom.xml
+++ b/qiaoba-apis/pom.xml
@@ -31,7 +31,7 @@
com.qiaoba
- qiaoba-common-security
+ qiaoba-auth
com.qiaoba
diff --git a/qiaoba-apis/qiaoba-api-system/src/main/java/com/qiaoba/api/system/entity/SysDept.java b/qiaoba-apis/qiaoba-api-system/src/main/java/com/qiaoba/api/system/entity/SysDept.java
index 05993eb..816616a 100644
--- a/qiaoba-apis/qiaoba-api-system/src/main/java/com/qiaoba/api/system/entity/SysDept.java
+++ b/qiaoba-apis/qiaoba-api-system/src/main/java/com/qiaoba/api/system/entity/SysDept.java
@@ -2,12 +2,15 @@ package com.qiaoba.api.system.entity;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
-import com.fasterxml.jackson.databind.annotation.JsonSerialize;
-import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import com.qiaoba.common.base.entity.BaseEntity;
import lombok.Data;
import lombok.EqualsAndHashCode;
+import javax.validation.constraints.Max;
+import javax.validation.constraints.Min;
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.Size;
+
/**
* 部门信息 sys_dept
*
@@ -41,11 +44,14 @@ public class SysDept extends BaseEntity {
/**
* 部门名称
*/
+ @Size(min = 1, max = 20, message = "部门名称允许长度: {min}-{max}")
private String deptName;
/**
* 显示顺序
*/
+ @Min(value = 1, message = "排序最小允许: {value}")
+ @Max(value = Integer.MAX_VALUE, message = "排序最大允许: {value}")
private Integer orderNum;
/**
@@ -66,6 +72,7 @@ public class SysDept extends BaseEntity {
/**
* 部门状态:0停用,1正常
*/
+ @NotBlank(message = "状态不能为空")
private String status;
}
diff --git a/qiaoba-apis/qiaoba-api-system/src/main/java/com/qiaoba/api/system/entity/SysPost.java b/qiaoba-apis/qiaoba-api-system/src/main/java/com/qiaoba/api/system/entity/SysPost.java
index 3528193..7e35f6c 100644
--- a/qiaoba-apis/qiaoba-api-system/src/main/java/com/qiaoba/api/system/entity/SysPost.java
+++ b/qiaoba-apis/qiaoba-api-system/src/main/java/com/qiaoba/api/system/entity/SysPost.java
@@ -4,9 +4,15 @@ import cn.afterturn.easypoi.excel.annotation.Excel;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.qiaoba.common.base.entity.BaseEntity;
+import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
+import javax.validation.constraints.Max;
+import javax.validation.constraints.Min;
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.Size;
+
/**
* 岗位信息 sys_post
*
@@ -22,19 +28,28 @@ public class SysPost extends BaseEntity {
private static final long serialVersionUID = 1L;
@TableId
- @Excel(name = "岗位序号" , width = 20)
+ @Excel(name = "岗位序号", width = 20)
private String postId;
- @Excel(name = "岗位编码" , width = 20)
- private String postCode;
-
- @Excel(name = "岗位名称" , width = 20)
+ @Excel(name = "岗位名称", width = 20)
+ @Schema(description = "岗位名称")
+ @Size(min = 1, max = 20, message = "岗位名称允许长度: {min}-{max}")
private String postName;
- @Excel(name = "岗位排序" , width = 20)
- private String postSort;
+ @Excel(name = "岗位编码", width = 20)
+ @Schema(description = "岗位编码")
+ @Size(min = 1, max = 20, message = "岗位编码允许长度: {min}-{max}")
+ private String postCode;
- @Excel(name = "状态" , width = 20, replace = {"正常_1" , "异常_0"})
+ @Excel(name = "岗位排序", width = 20)
+ @Schema(description = "岗位排序")
+ @Min(value = 1, message = "排序最小允许: {value}")
+ @Max(value = Integer.MAX_VALUE, message = "排序最大允许: {value}")
+ private Integer postSort;
+
+ @Excel(name = "状态", width = 20, replace = {"正常_1", "异常_0"})
+ @Schema(description = "状态(0->禁用,1->正常)")
+ @NotBlank(message = "状态不能为空")
private String status;
}
diff --git a/qiaoba-apis/qiaoba-api-system/src/main/java/com/qiaoba/api/system/entity/dto/LoginDto.java b/qiaoba-apis/qiaoba-api-system/src/main/java/com/qiaoba/api/system/entity/dto/LoginDto.java
new file mode 100644
index 0000000..eed22e2
--- /dev/null
+++ b/qiaoba-apis/qiaoba-api-system/src/main/java/com/qiaoba/api/system/entity/dto/LoginDto.java
@@ -0,0 +1,35 @@
+package com.qiaoba.api.system.entity.dto;
+
+import lombok.Data;
+
+/**
+ * 用户登录对象
+ *
+ * @author ailanyin
+ * @version 1.0
+ * @since 2021/10/15 0015 上午 10:05
+ */
+@Data
+public class LoginDto {
+
+ /**
+ * 用户名
+ */
+ private String username;
+
+ /**
+ * 用户密码
+ */
+ private String password;
+
+ /**
+ * 验证码
+ */
+ private String code;
+
+ /**
+ * 唯一标识
+ */
+ private String uuid = "";
+
+}
diff --git a/qiaoba-apis/qiaoba-api-system/src/main/java/com/qiaoba/api/system/entity/param/SysDeptParam.java b/qiaoba-apis/qiaoba-api-system/src/main/java/com/qiaoba/api/system/entity/param/SysDeptParam.java
index 4fb456a..86deb40 100644
--- a/qiaoba-apis/qiaoba-api-system/src/main/java/com/qiaoba/api/system/entity/param/SysDeptParam.java
+++ b/qiaoba-apis/qiaoba-api-system/src/main/java/com/qiaoba/api/system/entity/param/SysDeptParam.java
@@ -1,5 +1,6 @@
package com.qiaoba.api.system.entity.param;
+import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Getter;
import lombok.Setter;
@@ -18,6 +19,8 @@ public class SysDeptParam implements Serializable {
private static final long serialVersionUID = 1L;
+ @Schema(description = "部门名称")
private String deptName;
+ @Schema(description = "状态(0->禁用,1->正常)")
private String status;
}
diff --git a/qiaoba-apis/qiaoba-api-system/src/main/java/com/qiaoba/api/system/entity/param/SysPostParam.java b/qiaoba-apis/qiaoba-api-system/src/main/java/com/qiaoba/api/system/entity/param/SysPostParam.java
index 387e4e1..2c9d550 100644
--- a/qiaoba-apis/qiaoba-api-system/src/main/java/com/qiaoba/api/system/entity/param/SysPostParam.java
+++ b/qiaoba-apis/qiaoba-api-system/src/main/java/com/qiaoba/api/system/entity/param/SysPostParam.java
@@ -1,5 +1,6 @@
package com.qiaoba.api.system.entity.param;
+import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Getter;
import lombok.Setter;
@@ -18,10 +19,13 @@ public class SysPostParam implements Serializable {
private static final long serialVersionUID = 1L;
+ @Schema(description = "岗位名称")
private String postName;
+ @Schema(description = "岗位编码")
private String postCode;
+ @Schema(description = "状态(0->禁用,1->正常)")
private String status;
public SysPostParam() {
diff --git a/qiaoba-apis/qiaoba-api-system/src/main/java/com/qiaoba/api/system/service/SysDeptApiService.java b/qiaoba-apis/qiaoba-api-system/src/main/java/com/qiaoba/api/system/service/SysDeptApiService.java
index 3e959fb..13fa2e0 100644
--- a/qiaoba-apis/qiaoba-api-system/src/main/java/com/qiaoba/api/system/service/SysDeptApiService.java
+++ b/qiaoba-apis/qiaoba-api-system/src/main/java/com/qiaoba/api/system/service/SysDeptApiService.java
@@ -45,7 +45,7 @@ public interface SysDeptApiService {
* @param deptId 部门Id
* @return 部门信息
*/
- SysDept selectById(Long deptId);
+ SysDept selectById(String deptId);
/**
* 删除部门
@@ -53,7 +53,7 @@ public interface SysDeptApiService {
* @param deptId 部门Id
* @return > 0 = success
*/
- int deleteById(Long deptId);
+ int deleteById(String deptId);
/**
* 构建前端部门树
diff --git a/qiaoba-apis/qiaoba-api-system/src/main/java/com/qiaoba/api/system/service/SysMenuApiService.java b/qiaoba-apis/qiaoba-api-system/src/main/java/com/qiaoba/api/system/service/SysMenuApiService.java
index 0977453..85198c5 100644
--- a/qiaoba-apis/qiaoba-api-system/src/main/java/com/qiaoba/api/system/service/SysMenuApiService.java
+++ b/qiaoba-apis/qiaoba-api-system/src/main/java/com/qiaoba/api/system/service/SysMenuApiService.java
@@ -5,6 +5,7 @@ import com.qiaoba.api.system.entity.param.SysMenuParam;
import com.qiaoba.api.system.entity.vo.SysMenuVo;
import java.util.List;
+import java.util.Set;
/**
* 菜单对外暴露接口
@@ -54,4 +55,5 @@ public interface SysMenuApiService {
* @return > 0 = success
*/
int deleteById(String menuId);
+
}
diff --git a/qiaoba-apis/qiaoba-api-system/src/main/java/com/qiaoba/api/system/service/SysRoleApiService.java b/qiaoba-apis/qiaoba-api-system/src/main/java/com/qiaoba/api/system/service/SysRoleApiService.java
index 9180a34..eca34be 100644
--- a/qiaoba-apis/qiaoba-api-system/src/main/java/com/qiaoba/api/system/service/SysRoleApiService.java
+++ b/qiaoba-apis/qiaoba-api-system/src/main/java/com/qiaoba/api/system/service/SysRoleApiService.java
@@ -60,7 +60,7 @@ public interface SysRoleApiService {
* 批量删除
*
* @param ids 角色ID列表
- * @return > 0 = success
+ * @return > 0 = success
*/
int deleteByIds(List ids);
@@ -71,4 +71,5 @@ public interface SysRoleApiService {
* @return 结果
*/
int authDataScope(DataScopeDto dto);
+
}
diff --git a/qiaoba-apis/qiaoba-api-system/src/main/java/com/qiaoba/api/system/service/SysUserApiService.java b/qiaoba-apis/qiaoba-api-system/src/main/java/com/qiaoba/api/system/service/SysUserApiService.java
index 6db65fe..7bfa599 100644
--- a/qiaoba-apis/qiaoba-api-system/src/main/java/com/qiaoba/api/system/service/SysUserApiService.java
+++ b/qiaoba-apis/qiaoba-api-system/src/main/java/com/qiaoba/api/system/service/SysUserApiService.java
@@ -37,6 +37,14 @@ public interface SysUserApiService {
*/
SysUser selectById(String userId, Boolean hasPassword);
+ /**
+ * 查询用户
+ *
+ * @param username 登录账号
+ * @return SysUser
+ */
+ SysUser selectByUsername(String username);
+
/**
* 重置密码
*
diff --git a/qiaoba-application/src/main/resources/application.yml b/qiaoba-application/src/main/resources/application.yml
index ea168f1..aab78bf 100644
--- a/qiaoba-application/src/main/resources/application.yml
+++ b/qiaoba-application/src/main/resources/application.yml
@@ -16,8 +16,23 @@ spring:
date-format: yyyy-MM-dd HH:mm:ss
time-zone: GMT+8
+qiaoba:
+ auth:
+ whitelist:
+ - /
+ - /*.*
+ - /favicon.ico
+ - /**/*.html
+ - /**/*.css
+ - /**/*.js
+ - /swagger-resources
+ - /v3/api-docs/**
+ - /druid/**
+ - /file/**
+ - /login
+ - /register
+ - /captchaImage
-# springdoc-openapi项目配置
springdoc:
swagger-ui:
path: /swagger-ui.html
@@ -29,6 +44,7 @@ springdoc:
- group: '系统管理'
paths-to-match: '/**'
packages-to-scan: com.qiaoba.module.system.controller
+
# knife4j的增强配置,不需要增强可以不配
knife4j:
enable: true
diff --git a/qiaoba-auth/pom.xml b/qiaoba-auth/pom.xml
new file mode 100644
index 0000000..2a2c23f
--- /dev/null
+++ b/qiaoba-auth/pom.xml
@@ -0,0 +1,36 @@
+
+
+
+ qiaoba-boot
+ com.qiaoba
+ 1.0
+
+ 4.0.0
+
+ qiaoba-auth
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-security
+
+
+
+ com.qiaoba
+ qiaoba-common-base
+
+
+ com.qiaoba
+ qiaoba-common-web
+
+
+
+ com.qiaoba
+ qiaoba-common-redis
+
+
+
+
diff --git a/qiaoba-auth/src/main/java/com/qiaoba/auth/config/SpringSecurityConfig.java b/qiaoba-auth/src/main/java/com/qiaoba/auth/config/SpringSecurityConfig.java
new file mode 100644
index 0000000..37870e9
--- /dev/null
+++ b/qiaoba-auth/src/main/java/com/qiaoba/auth/config/SpringSecurityConfig.java
@@ -0,0 +1,96 @@
+package com.qiaoba.auth.config;
+
+import cn.hutool.core.util.RandomUtil;
+import cn.hutool.crypto.SecureUtil;
+import com.qiaoba.auth.constants.SecurityConstant;
+import com.qiaoba.auth.filters.JwtAuthenticationTokenFilter;
+import com.qiaoba.auth.handler.AccessDeniedHandler;
+import com.qiaoba.auth.handler.LogoutHandler;
+import com.qiaoba.auth.properties.AuthConfigProperties;
+import com.qiaoba.auth.utils.TokenUtil;
+import com.qiaoba.common.redis.service.RedisService;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.http.HttpMethod;
+import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
+import org.springframework.security.config.annotation.web.builders.HttpSecurity;
+import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
+import org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer;
+import org.springframework.security.config.http.SessionCreationPolicy;
+import org.springframework.security.web.SecurityFilterChain;
+import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
+
+import javax.annotation.PostConstruct;
+
+/**
+ * SpringSecurity安全配置
+ *
+ * @author ailanyin
+ * @version 1.0
+ * @since 2023/5/15 11:23
+ */
+@Configuration
+@RequiredArgsConstructor
+@EnableWebSecurity
+@EnableGlobalMethodSecurity(prePostEnabled = true)
+@Slf4j
+public class SpringSecurityConfig {
+
+ private final AuthConfigProperties authConfigProperties;
+ private final AccessDeniedHandler accessDeniedHandler;
+ private final LogoutHandler logoutHandler;
+ private final JwtAuthenticationTokenFilter jwtAuthenticationTokenFilter;
+ private final RedisService redisService;
+
+ /**
+ * 创建Token秘钥
+ */
+ @PostConstruct
+ public void initSecret() {
+ if (redisService.hasKey(SecurityConstant.REDIS_SECRET_KEY)) {
+ TokenUtil.secret = SecureUtil.md5(SecureUtil.md5(redisService.get(SecurityConstant.REDIS_SECRET_KEY).toString()));
+ } else {
+ String random = RandomUtil.randomString(8);
+ TokenUtil.secret = SecureUtil.md5(SecureUtil.md5(random));
+ redisService.set(SecurityConstant.REDIS_SECRET_KEY, random);
+ }
+ }
+
+ @Bean
+ SecurityFilterChain filterChain(HttpSecurity httpSecurity) throws Exception {
+ ExpressionUrlAuthorizationConfigurer.ExpressionInterceptUrlRegistry registry = httpSecurity.authorizeRequests();
+ //白名单
+ for (String url : authConfigProperties.getWhitelist()) {
+ registry.antMatchers(url).permitAll();
+ }
+
+ // 由于使用的是JWT,我们这里不需要csrf
+ httpSecurity.csrf()
+ .disable()
+ //添加自定义未授权和未登录结果返回
+ .exceptionHandling()
+ .authenticationEntryPoint(accessDeniedHandler)
+ .and()
+ // 基于token,所以不需要session
+ .sessionManagement()
+ .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
+ .and()
+ .authorizeRequests()
+ //跨域请求会先进行一次options请求
+ .antMatchers(HttpMethod.OPTIONS)
+ .permitAll()
+ // 除上面外的所有请求全部需要鉴权认证
+ .anyRequest()
+ .authenticated();
+ // 禁用缓存
+ httpSecurity.headers().cacheControl();
+ // 退出处理
+ httpSecurity.logout().logoutUrl(SecurityConstant.LOGOUT_URL).logoutSuccessHandler(logoutHandler);
+ // 添加JWT filter
+ httpSecurity.addFilterBefore(jwtAuthenticationTokenFilter, UsernamePasswordAuthenticationFilter.class);
+
+ return httpSecurity.build();
+ }
+}
diff --git a/qiaoba-auth/src/main/java/com/qiaoba/auth/constants/SecurityConstant.java b/qiaoba-auth/src/main/java/com/qiaoba/auth/constants/SecurityConstant.java
new file mode 100644
index 0000000..4bf7f5c
--- /dev/null
+++ b/qiaoba-auth/src/main/java/com/qiaoba/auth/constants/SecurityConstant.java
@@ -0,0 +1,81 @@
+package com.qiaoba.auth.constants;
+
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * 安全常量
+ *
+ * @author ailanyin
+ * @version 1.0
+ * @since 2022/9/8 0008 下午 14:54
+ */
+public class SecurityConstant {
+
+ public static final int MAX_ERROR_COUNT = 5;
+ public static final String LOGOUT_URL = "/logout";
+ public static final String HAS_BEEN_PULLED_BLACK = "您的IP已经被系统拉黑";
+ public static final String ACCESS_DENIED = "暂无权限访问, 请重新登录";
+ public static final String BLACKLIST_KEY = "login:blacklist";
+ public static final String LOGIN_ERROR_COUNT = "login:errorCount:";
+ public static final String BLACKLIST_ON = "true";
+ public static final String BLACKLIST_ON_OFF_KEY = "sys_config:sys.account.blacklistOnOff";
+ public static final String CAPTCHA_KEY = "login:captcha:";
+ public static final String CAPTCHA_ON_OFF_KEY = "sys_config:sys.account.captchaOnOff";
+ public static final String CAPTCHA_ON = "true";
+ public static final String REGISTER_ON_OFF_KEY = "sys_config:sys.account.registerUser";
+ public static final String REGISTER_ON = "true";
+ public static final String REDIS_SECRET_KEY = "sys:secret:secret";
+ /**
+ * 登录成功
+ */
+ public static final String LOGIN_SUCCESS = "登录成功";
+ /**
+ * 登录失败
+ */
+ public static final String LOGIN_FAIL = "登录失败";
+ /**
+ * 密码错误
+ */
+ public static final String PASSWORD_ERROR = "密码错误";
+
+ /**
+ * token header
+ */
+ public static final String TOKEN_HEADER = "Authorization";
+
+ /**
+ * token前缀
+ */
+ public static final String TOKEN_HEAD = "Bearer ";
+
+
+ /**
+ * Xss过滤白名单
+ */
+ public final static List XSS_WHITELIST = Arrays.asList(
+ "/captchaImage" ,
+ "/login",
+ "/workflow/process/start",
+ "/workflow/model/save"
+ );
+
+ /**
+ * 需要限流的接口
+ */
+ public final static List LIMIT_URI = Arrays.asList(
+ "/captchaImage" ,
+ "/login" ,
+ "/register"
+ );
+
+ /**
+ * 限流的RedisKey
+ */
+ public final static String RATE_LIMIT_KEY = "rateLimit:";
+
+ /**
+ * 同IP每秒最大允许访问次数
+ */
+ public final static Integer MAX_RATE_LIMIT_TOTAL = 5;
+}
diff --git a/qiaoba-auth/src/main/java/com/qiaoba/auth/entity/LoginUser.java b/qiaoba-auth/src/main/java/com/qiaoba/auth/entity/LoginUser.java
new file mode 100644
index 0000000..c3d0c13
--- /dev/null
+++ b/qiaoba-auth/src/main/java/com/qiaoba/auth/entity/LoginUser.java
@@ -0,0 +1,172 @@
+package com.qiaoba.auth.entity;
+
+import cn.hutool.core.util.StrUtil;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.authority.SimpleGrantedAuthority;
+import org.springframework.security.core.userdetails.UserDetails;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+/**
+ * 登录用户身份权限
+ *
+ * @author ailanyin
+ * @version 1.0
+ * @since 2021/10/15 0015 上午 10:05
+ */
+public class LoginUser implements UserDetails {
+
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 用户ID
+ */
+ private String userId;
+
+ /**
+ * 部门ID
+ */
+ private String deptId;
+
+ /**
+ * 登录账号
+ */
+ private String username;
+
+ /**
+ * 用户名称
+ */
+ private String nickname;
+
+
+ /**
+ * 角色列表
+ */
+ private List roleIds;
+
+
+ /**
+ * 权限列表
+ */
+ private Set permissions;
+
+
+ public LoginUser() {
+ }
+
+ public LoginUser(String userId, String deptId, String username, String nickname, List roleIds, Set permissions) {
+ this.userId = userId;
+ this.deptId = deptId;
+ this.username = username;
+ this.permissions = permissions;
+ this.nickname = nickname;
+ this.roleIds = roleIds;
+ }
+
+ public String getUserId() {
+ return userId;
+ }
+
+ public void setUserId(String userId) {
+ this.userId = userId;
+ }
+
+ public String getDeptId() {
+ return deptId;
+ }
+
+ public void setDeptId(String deptId) {
+ this.deptId = deptId;
+ }
+
+
+ public List getRoleIds() {
+ return roleIds;
+ }
+
+ public void setRoleIds(List roleIds) {
+ this.roleIds = roleIds;
+ }
+
+ public Set getPermissions() {
+ return permissions;
+ }
+
+ public void setPermissions(Set permissions) {
+ this.permissions = permissions;
+ }
+
+ public String getNickname() {
+ return nickname;
+ }
+
+ public void setNickname(String nickname) {
+ this.nickname = nickname;
+ }
+
+ public void setUsername(String username) {
+ this.username = username;
+ }
+
+
+ @Override
+ public String getUsername() {
+ return this.username;
+ }
+
+ @Override
+ public String getPassword() {
+ return null;
+ }
+
+ /**
+ * 账户是否未过期,过期无法验证
+ */
+ @Override
+ public boolean isAccountNonExpired() {
+ return true;
+ }
+
+ /**
+ * 指定用户是否解锁,锁定的用户无法进行身份验证
+ */
+ @Override
+ public boolean isAccountNonLocked() {
+ return true;
+ }
+
+ /**
+ * 指示是否已过期的用户的凭据(密码),过期的凭据防止认证
+ *
+ * @return boolean
+ */
+ @Override
+ public boolean isCredentialsNonExpired() {
+ return true;
+ }
+
+ /**
+ * 是否可用 ,禁用的用户不能身份验证
+ *
+ * @return boolean
+ */
+ @Override
+ public boolean isEnabled() {
+ return true;
+ }
+
+ @Override
+ @JsonIgnore
+ public Collection extends GrantedAuthority> getAuthorities() {
+ //返回当前用户的权限
+ return permissions.stream()
+ .filter(StrUtil::isNotBlank)
+ .map(SimpleGrantedAuthority::new)
+ .collect(Collectors.toList());
+ }
+
+}
diff --git a/qiaoba-auth/src/main/java/com/qiaoba/auth/filters/JwtAuthenticationTokenFilter.java b/qiaoba-auth/src/main/java/com/qiaoba/auth/filters/JwtAuthenticationTokenFilter.java
new file mode 100644
index 0000000..c2764c4
--- /dev/null
+++ b/qiaoba-auth/src/main/java/com/qiaoba/auth/filters/JwtAuthenticationTokenFilter.java
@@ -0,0 +1,62 @@
+package com.qiaoba.auth.filters;
+
+import cn.hutool.core.util.StrUtil;
+import com.qiaoba.auth.constants.SecurityConstant;
+import com.qiaoba.auth.properties.AuthConfigProperties;
+import com.qiaoba.auth.utils.TokenUtil;
+import lombok.RequiredArgsConstructor;
+import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.security.core.userdetails.UserDetails;
+import org.springframework.security.core.userdetails.UserDetailsService;
+import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
+import org.springframework.web.filter.OncePerRequestFilter;
+
+import javax.servlet.FilterChain;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.util.Objects;
+
+/**
+ * JwtAuthenticationTokenFilter
+ * 为了保证 SecurityContext 上下文中 userInfo 是最新的
+ *
+ * @author ailanyin
+ * @version 1.0
+ * @since 2021/10/21 0021 下午 14:13
+ */
+@RequiredArgsConstructor
+public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {
+
+ private final UserDetailsService userDetailsService;
+ private final AuthConfigProperties authConfigProperties;
+
+ @Override
+ protected void doFilterInternal(HttpServletRequest request,
+ HttpServletResponse response,
+ FilterChain chain) throws ServletException, IOException {
+ // 鉴权白名单, 放行
+ if (authConfigProperties.getWhitelist().contains(request.getRequestURI())) {
+ chain.doFilter(request, response);
+ return;
+ }
+ // 取Header中的Token
+ String authHeader = request.getHeader(SecurityConstant.TOKEN_HEADER);
+ if (StrUtil.isNotBlank(authHeader) && authHeader.startsWith(SecurityConstant.TOKEN_HEAD)) {
+ String authToken = authHeader.substring(SecurityConstant.TOKEN_HEAD.length());
+ if (TokenUtil.validateToken(authToken)) {
+ String username = TokenUtil.getUserNameFromToken(authToken);
+ if (StrUtil.isNotBlank(username) && Objects.isNull(SecurityContextHolder.getContext().getAuthentication())) {
+ UserDetails userDetails = this.userDetailsService.loadUserByUsername(username);
+ UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
+ authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
+ SecurityContextHolder.getContext().setAuthentication(authentication);
+ }
+ }
+ }
+
+ chain.doFilter(request, response);
+ }
+}
diff --git a/qiaoba-auth/src/main/java/com/qiaoba/auth/handler/AccessDeniedHandler.java b/qiaoba-auth/src/main/java/com/qiaoba/auth/handler/AccessDeniedHandler.java
new file mode 100644
index 0000000..55fd811
--- /dev/null
+++ b/qiaoba-auth/src/main/java/com/qiaoba/auth/handler/AccessDeniedHandler.java
@@ -0,0 +1,31 @@
+package com.qiaoba.auth.handler;
+
+import cn.hutool.http.HttpStatus;
+import cn.hutool.json.JSONUtil;
+import com.qiaoba.auth.constants.SecurityConstant;
+import com.qiaoba.common.base.result.AjaxResult;
+import com.qiaoba.common.web.utils.ResponseUtil;
+import org.springframework.security.core.AuthenticationException;
+import org.springframework.security.web.AuthenticationEntryPoint;
+import org.springframework.stereotype.Component;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+
+/**
+ * 无权限处理器
+ *
+ * @author ailanyin
+ * @version 1.0
+ * @since 2023/5/15 14:14
+ */
+@Component
+public class AccessDeniedHandler implements AuthenticationEntryPoint {
+ @Override
+ public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException {
+ AjaxResult result = AjaxResult.error(HttpStatus.HTTP_UNAUTHORIZED, SecurityConstant.ACCESS_DENIED);
+ ResponseUtil.response(response, JSONUtil.toJsonStr(result));
+ }
+}
diff --git a/qiaoba-auth/src/main/java/com/qiaoba/auth/handler/LogoutHandler.java b/qiaoba-auth/src/main/java/com/qiaoba/auth/handler/LogoutHandler.java
new file mode 100644
index 0000000..59d51b8
--- /dev/null
+++ b/qiaoba-auth/src/main/java/com/qiaoba/auth/handler/LogoutHandler.java
@@ -0,0 +1,26 @@
+package com.qiaoba.auth.handler;
+
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;
+import org.springframework.stereotype.Component;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+/**
+ * 退出处理器
+ *
+ * @author ailanyin
+ * @version 1.0
+ * @since 2022/1/4 0004 下午 16:20
+ */
+@Component
+public class LogoutHandler implements LogoutSuccessHandler {
+
+ @Override
+ public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse httpServletResponse, Authentication authentication) {
+ //删除SecurityContext上下文中的信息
+ SecurityContextHolder.clearContext();
+ }
+}
diff --git a/qiaoba-auth/src/main/java/com/qiaoba/auth/properties/AuthConfigProperties.java b/qiaoba-auth/src/main/java/com/qiaoba/auth/properties/AuthConfigProperties.java
new file mode 100644
index 0000000..7554899
--- /dev/null
+++ b/qiaoba-auth/src/main/java/com/qiaoba/auth/properties/AuthConfigProperties.java
@@ -0,0 +1,24 @@
+package com.qiaoba.auth.properties;
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.context.annotation.Configuration;
+
+import java.util.List;
+
+/**
+ * 鉴权配置(白名单/XSS)
+ *
+ * @author ailanyin
+ * @version 1.0
+ * @since 2023/5/15 11:09
+ */
+@Configuration
+@ConfigurationProperties(prefix = "qiaoba.auth")
+@Data
+@EnableConfigurationProperties
+public class AuthConfigProperties {
+
+ private List whitelist;
+}
diff --git a/qiaoba-auth/src/main/java/com/qiaoba/auth/utils/SecurityUtil.java b/qiaoba-auth/src/main/java/com/qiaoba/auth/utils/SecurityUtil.java
new file mode 100644
index 0000000..27945f6
--- /dev/null
+++ b/qiaoba-auth/src/main/java/com/qiaoba/auth/utils/SecurityUtil.java
@@ -0,0 +1,74 @@
+package com.qiaoba.auth.utils;
+
+import com.qiaoba.auth.entity.LoginUser;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.context.SecurityContext;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
+
+/**
+ * SecurityUtil
+ *
+ * @author ailanyin
+ * @version 1.0
+ * @since 2022/8/16 0016 下午 14:51
+ */
+public class SecurityUtil {
+
+ private static final BCryptPasswordEncoder PASSWORD_ENCODER = new BCryptPasswordEncoder();
+
+ /**
+ * 获取登录用户的账号
+ *
+ * @return username
+ */
+ public static String getLoginUsername() {
+ return getLoginUser().getUsername();
+ }
+
+ /**
+ * 获取登录用户的账号
+ *
+ * @return nickname
+ */
+ public static String getLoginNickname() {
+ return getLoginUser().getNickname();
+ }
+
+ /**
+ * 获取登录用户的ID
+ *
+ * @return userId
+ */
+ public static String getLoginUserId() {
+ return getLoginUser().getUserId();
+ }
+
+
+ public static LoginUser getLoginUser() {
+ SecurityContext ctx = SecurityContextHolder.getContext();
+ Authentication auth = ctx.getAuthentication();
+ return (LoginUser) auth.getPrincipal();
+ }
+
+ /**
+ * 加密密码
+ *
+ * @param password 原密码
+ * @return 加密后密码
+ */
+ public static String encryptPassword(String password) {
+ return PASSWORD_ENCODER.encode(password);
+ }
+
+ /**
+ * 判断密码是否相同
+ *
+ * @param rawPassword 真实密码
+ * @param encodedPassword 加密后字符
+ * @return 结果
+ */
+ public static boolean matchesPassword(String rawPassword, String encodedPassword) {
+ return PASSWORD_ENCODER.matches(rawPassword, encodedPassword);
+ }
+}
diff --git a/qiaoba-auth/src/main/java/com/qiaoba/auth/utils/TokenUtil.java b/qiaoba-auth/src/main/java/com/qiaoba/auth/utils/TokenUtil.java
new file mode 100644
index 0000000..aeb86d7
--- /dev/null
+++ b/qiaoba-auth/src/main/java/com/qiaoba/auth/utils/TokenUtil.java
@@ -0,0 +1,70 @@
+package com.qiaoba.auth.utils;
+
+import cn.hutool.core.date.DateField;
+import cn.hutool.core.date.DateTime;
+import cn.hutool.jwt.JWTPayload;
+import cn.hutool.jwt.JWTUtil;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * TokenUtil
+ *
+ * @author ailanyin
+ * @version 1.0
+ * @since 2022/6/8 0008 上午 11:44
+ */
+public class TokenUtil {
+
+
+ /**
+ * jwt 加解密密钥,第一次项目启动时创建随机数
+ */
+ public static String secret;
+
+
+ public static String generateToken(String username) {
+ DateTime now = DateTime.now();
+ // 3天过期
+ DateTime newTime = now.offsetNew(DateField.HOUR, 72);
+
+ Map payload = new HashMap(4);
+ //签发时间
+ payload.put(JWTPayload.ISSUED_AT, now);
+ //过期时间
+ payload.put(JWTPayload.EXPIRES_AT, newTime);
+ //生效时间
+ payload.put(JWTPayload.NOT_BEFORE, now);
+ //载荷
+ payload.put(JWTPayload.SUBJECT, username);
+
+ return JWTUtil.createToken(payload, secret.getBytes());
+ }
+
+ public static String getUserNameFromToken(String token) {
+ try {
+ return JWTUtil.parseToken(token).getPayload(JWTPayload.SUBJECT).toString();
+ } catch (Exception e) {
+ return null;
+ }
+ }
+
+ /**
+ * 验证Token是否有效
+ *
+ * @param token token
+ * @return 是/否
+ */
+ public static boolean validateToken(String token) {
+ try {
+ if (!JWTUtil.verify(token, secret.getBytes())) {
+ return false;
+ }
+ long expireTime = Long.parseLong(JWTUtil.parseToken(token).getPayload(JWTPayload.EXPIRES_AT).toString() + "000");
+ return new DateTime(expireTime).after(DateTime.now());
+ } catch (Exception e) {
+ return false;
+ }
+ }
+}
diff --git a/qiaoba-auth/src/main/resources/META-INF/spring-configuration-metadata.json b/qiaoba-auth/src/main/resources/META-INF/spring-configuration-metadata.json
new file mode 100644
index 0000000..0ca18bc
--- /dev/null
+++ b/qiaoba-auth/src/main/resources/META-INF/spring-configuration-metadata.json
@@ -0,0 +1,17 @@
+{
+ "groups": [
+ {
+ "name": "qiaoba.auth",
+ "type": "com.qiaoba.auth.properties.AuthConfigProperties",
+ "sourceType": "com.qiaoba.auth.properties.AuthConfigProperties"
+ }
+ ],
+ "properties": [
+ {
+ "name": "qiaoba.auth.whitelist",
+ "type": "java.util.List",
+ "sourceType": "com.qiaoba.auth.properties.AuthConfigProperties"
+ }
+ ],
+ "hints": []
+}
diff --git a/qiaoba-auth/src/main/resources/META-INF/spring.factories b/qiaoba-auth/src/main/resources/META-INF/spring.factories
new file mode 100644
index 0000000..65cc811
--- /dev/null
+++ b/qiaoba-auth/src/main/resources/META-INF/spring.factories
@@ -0,0 +1,6 @@
+org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
+ com.qiaoba.auth.properties.AuthConfigProperties,\
+ com.qiaoba.auth.handler.AccessDeniedHandler,\
+ com.qiaoba.auth.handler.LogoutHandler,\
+ com.qiaoba.auth.filters.JwtAuthenticationTokenFilter,\
+ com.qiaoba.auth.config.SpringSecurityConfig
diff --git a/qiaoba-commons/pom.xml b/qiaoba-commons/pom.xml
index 73cfdd6..fe55844 100644
--- a/qiaoba-commons/pom.xml
+++ b/qiaoba-commons/pom.xml
@@ -17,7 +17,6 @@
qiaoba-common-web
qiaoba-common-doc
qiaoba-common-redis
- qiaoba-common-security
qiaoba-common-poi
diff --git a/qiaoba-commons/qiaoba-common-base/pom.xml b/qiaoba-commons/qiaoba-common-base/pom.xml
index 68fd04f..df45e79 100644
--- a/qiaoba-commons/qiaoba-common-base/pom.xml
+++ b/qiaoba-commons/qiaoba-common-base/pom.xml
@@ -16,5 +16,9 @@
cn.hutool
hutool-all
+
+ org.springframework.boot
+ spring-boot-starter-validation
+
diff --git a/qiaoba-commons/qiaoba-common-datasource/src/main/java/com/qiaoba/common/database/utils/TenantUtil.java b/qiaoba-commons/qiaoba-common-base/src/main/java/com/qiaoba/common/base/utils/TenantUtil.java
similarity index 93%
rename from qiaoba-commons/qiaoba-common-datasource/src/main/java/com/qiaoba/common/database/utils/TenantUtil.java
rename to qiaoba-commons/qiaoba-common-base/src/main/java/com/qiaoba/common/base/utils/TenantUtil.java
index c72d3ff..4f171df 100644
--- a/qiaoba-commons/qiaoba-common-datasource/src/main/java/com/qiaoba/common/database/utils/TenantUtil.java
+++ b/qiaoba-commons/qiaoba-common-base/src/main/java/com/qiaoba/common/base/utils/TenantUtil.java
@@ -1,4 +1,4 @@
-package com.qiaoba.common.database.utils;
+package com.qiaoba.common.base.utils;
/**
* 租户工具类
diff --git a/qiaoba-commons/qiaoba-common-datasource/src/main/java/com/qiaoba/common/database/config/MybatisPlusConfig.java b/qiaoba-commons/qiaoba-common-datasource/src/main/java/com/qiaoba/common/database/config/MybatisPlusConfig.java
index 37f669a..56482fb 100644
--- a/qiaoba-commons/qiaoba-common-datasource/src/main/java/com/qiaoba/common/database/config/MybatisPlusConfig.java
+++ b/qiaoba-commons/qiaoba-common-datasource/src/main/java/com/qiaoba/common/database/config/MybatisPlusConfig.java
@@ -4,7 +4,7 @@ import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.handler.TenantLineHandler;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.TenantLineInnerInterceptor;
-import com.qiaoba.common.database.utils.TenantUtil;
+import com.qiaoba.common.base.utils.TenantUtil;
import net.sf.jsqlparser.expression.Expression;
import net.sf.jsqlparser.expression.StringValue;
import org.springframework.context.annotation.Bean;
diff --git a/qiaoba-commons/qiaoba-common-datasource/src/main/java/com/qiaoba/common/database/entity/PageQuery.java b/qiaoba-commons/qiaoba-common-datasource/src/main/java/com/qiaoba/common/database/entity/PageQuery.java
index 2e07a5b..8d1a8db 100644
--- a/qiaoba-commons/qiaoba-common-datasource/src/main/java/com/qiaoba/common/database/entity/PageQuery.java
+++ b/qiaoba-commons/qiaoba-common-datasource/src/main/java/com/qiaoba/common/database/entity/PageQuery.java
@@ -1,14 +1,10 @@
package com.qiaoba.common.database.entity;
-import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
-import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.Data;
import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.List;
/**
* 分页查询实体类
@@ -31,16 +27,6 @@ public class PageQuery implements Serializable {
*/
private Integer pageNum;
- /**
- * 排序列
- */
- private String orderByColumn;
-
- /**
- * 排序的方向desc或者asc
- */
- private String isAsc;
-
/**
* 当前记录起始索引 默认值
*/
@@ -57,12 +43,7 @@ public class PageQuery implements Serializable {
if (pageNum <= 0) {
pageNum = DEFAULT_PAGE_NUM;
}
- Page page = new Page<>(pageNum, pageSize);
-/* List orderItems = buildOrderItem();
- if (CollUtil.isNotEmpty(orderItems)) {
- page.addOrder(orderItems);
- }*/
- return page;
+ return new Page<>(pageNum, pageSize);
}
}
diff --git a/qiaoba-commons/qiaoba-common-datasource/src/main/java/com/qiaoba/common/database/filters/DynamicDataSourceFilter.java b/qiaoba-commons/qiaoba-common-datasource/src/main/java/com/qiaoba/common/database/filters/DynamicDataSourceFilter.java
index 37a6955..a5777a7 100644
--- a/qiaoba-commons/qiaoba-common-datasource/src/main/java/com/qiaoba/common/database/filters/DynamicDataSourceFilter.java
+++ b/qiaoba-commons/qiaoba-common-datasource/src/main/java/com/qiaoba/common/database/filters/DynamicDataSourceFilter.java
@@ -2,14 +2,13 @@ package com.qiaoba.common.database.filters;
import com.qiaoba.common.database.config.DynamicDataSourceContext;
import com.qiaoba.common.database.constants.DynamicDatasourceConstant;
-import com.qiaoba.common.database.utils.TenantUtil;
+import com.qiaoba.common.base.utils.TenantUtil;
import com.qiaoba.common.web.utils.ResponseUtil;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import javax.servlet.*;
-import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
diff --git a/qiaoba-commons/qiaoba-common-datasource/src/main/resources/META-INF/spring.factories b/qiaoba-commons/qiaoba-common-datasource/src/main/resources/META-INF/spring.factories
index 49807c2..f955e9d 100644
--- a/qiaoba-commons/qiaoba-common-datasource/src/main/resources/META-INF/spring.factories
+++ b/qiaoba-commons/qiaoba-common-datasource/src/main/resources/META-INF/spring.factories
@@ -1,5 +1,3 @@
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.qiaoba.common.database.factories.DynamicDataSourceFactory,\
com.qiaoba.common.database.config.MybatisPlusConfig
-
-
diff --git a/qiaoba-commons/qiaoba-common-redis/pom.xml b/qiaoba-commons/qiaoba-common-redis/pom.xml
index 3750505..6d5258d 100644
--- a/qiaoba-commons/qiaoba-common-redis/pom.xml
+++ b/qiaoba-commons/qiaoba-common-redis/pom.xml
@@ -17,10 +17,14 @@
org.springframework.boot
spring-boot-starter-data-redis
+
+ com.qiaoba
+ qiaoba-common-base
+
com.fasterxml.jackson.core
jackson-databind
-
\ No newline at end of file
+
diff --git a/qiaoba-commons/qiaoba-common-redis/src/main/java/com/qiaoba/common/redis/service/impl/RedisServiceImpl.java b/qiaoba-commons/qiaoba-common-redis/src/main/java/com/qiaoba/common/redis/service/impl/RedisServiceImpl.java
index 06b2d24..eb6beaf 100644
--- a/qiaoba-commons/qiaoba-common-redis/src/main/java/com/qiaoba/common/redis/service/impl/RedisServiceImpl.java
+++ b/qiaoba-commons/qiaoba-common-redis/src/main/java/com/qiaoba/common/redis/service/impl/RedisServiceImpl.java
@@ -1,8 +1,9 @@
package com.qiaoba.common.redis.service.impl;
+import com.qiaoba.common.base.utils.TenantUtil;
import com.qiaoba.common.redis.service.RedisService;
-import org.springframework.beans.factory.annotation.Autowired;
+import lombok.RequiredArgsConstructor;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
@@ -20,33 +21,34 @@ import java.util.concurrent.TimeUnit;
* @since 2021/10/2 0003 下午 17:44
*/
@Service
+@RequiredArgsConstructor
public class RedisServiceImpl implements RedisService {
- @Autowired
- private RedisTemplate redisTemplate;
+ private final RedisTemplate redisTemplate;
@Override
public void set(String key, Object value, long time) {
- redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);
+ redisTemplate.opsForValue().set(handleKey(key), value, time, TimeUnit.SECONDS);
}
@Override
public void set(String key, Object value) {
- redisTemplate.opsForValue().set(key, value);
+ redisTemplate.opsForValue().set(handleKey(key), value);
}
@Override
public Object get(String key) {
- return redisTemplate.opsForValue().get(key);
+ return redisTemplate.opsForValue().get(handleKey(key));
}
@Override
public Boolean del(String key) {
- return redisTemplate.delete(key);
+ return redisTemplate.delete(handleKey(key));
}
@Override
public void del(Collection collection) {
+ // todo
redisTemplate.delete(collection);
}
@@ -57,168 +59,178 @@ public class RedisServiceImpl implements RedisService {
@Override
public Long getExpire(String key) {
- return redisTemplate.getExpire(key, TimeUnit.SECONDS);
+ return redisTemplate.getExpire(handleKey(key), TimeUnit.SECONDS);
}
@Override
public Boolean hasKey(String key) {
- return redisTemplate.hasKey(key);
+ return redisTemplate.hasKey(handleKey(key));
}
@Override
public Long incr(String key, long delta) {
- return redisTemplate.opsForValue().increment(key, delta);
+ return redisTemplate.opsForValue().increment(handleKey(key), delta);
}
@Override
public Long decr(String key, long delta) {
- return redisTemplate.opsForValue().increment(key, -delta);
+ return redisTemplate.opsForValue().increment(handleKey(key), -delta);
}
@Override
public Object hGet(String key, String hashKey) {
- return redisTemplate.opsForHash().get(key, hashKey);
+ return redisTemplate.opsForHash().get(handleKey(key), hashKey);
}
@Override
public Boolean hSet(String key, String hashKey, Object value, long time) {
- redisTemplate.opsForHash().put(key, hashKey, value);
- return expire(key, time);
+ String newKey = handleKey(key);
+ redisTemplate.opsForHash().put(newKey, hashKey, value);
+ return expire(newKey, time);
}
@Override
public void hSet(String key, String hashKey, Object value) {
- redisTemplate.opsForHash().put(key, hashKey, value);
+ redisTemplate.opsForHash().put(handleKey(key), hashKey, value);
}
@Override
public Map