浏览代码

代码优化

woody 6 月之前
父节点
当前提交
abf07ee095
共有 18 个文件被更改,包括 246 次插入309 次删除
  1. 4 13
      framework-base/src/main/java/com/chelvc/framework/base/crypto/AESCipherHandler.java
  2. 40 0
      framework-base/src/main/java/com/chelvc/framework/base/crypto/AbstractCipherHandler.java
  3. 32 17
      framework-base/src/main/java/com/chelvc/framework/base/crypto/CipherHandler.java
  4. 5 23
      framework-database/src/main/java/com/chelvc/framework/database/crypto/DefaultDatabaseCipherHandler.java
  5. 5 5
      framework-database/src/main/java/com/chelvc/framework/database/handler/JsonTypeHandler.java
  6. 16 10
      framework-security/src/main/java/com/chelvc/framework/security/config/OAuthConfigurer.java
  7. 24 29
      framework-security/src/main/java/com/chelvc/framework/security/config/SecurityProperties.java
  8. 0 111
      framework-security/src/main/java/com/chelvc/framework/security/context/AuthorizeContextHolder.java
  9. 84 0
      framework-security/src/main/java/com/chelvc/framework/security/context/SecurityContextHolder.java
  10. 2 1
      framework-security/src/main/java/com/chelvc/framework/security/crypto/AbstractSecurityCipherHandler.java
  11. 0 38
      framework-security/src/main/java/com/chelvc/framework/security/crypto/CustomizeSecurityCipherHandler.java
  12. 8 36
      framework-security/src/main/java/com/chelvc/framework/security/crypto/DefaultSecurityCipherHandler.java
  13. 2 2
      framework-security/src/main/java/com/chelvc/framework/security/interceptor/SecurityValidateInterceptor.java
  14. 6 6
      framework-security/src/main/java/com/chelvc/framework/security/session/DefaultSessionValidator.java
  15. 3 3
      framework-security/src/main/java/com/chelvc/framework/security/session/OAuthSessionFactory.java
  16. 11 11
      framework-security/src/main/java/com/chelvc/framework/security/session/RedisSessionValidator.java
  17. 1 1
      framework-security/src/main/java/com/chelvc/framework/security/session/SessionValidator.java
  18. 3 3
      framework-security/src/main/java/com/chelvc/framework/security/session/TokenExpiredValidator.java

+ 4 - 13
framework-base/src/main/java/com/chelvc/framework/base/crypto/AESCipherHandler.java

@@ -3,7 +3,7 @@ package com.chelvc.framework.base.crypto;
 import javax.crypto.Cipher;
 
 import com.chelvc.framework.common.util.AESUtils;
-import com.chelvc.framework.common.util.CodecUtils;
+import lombok.Getter;
 import lombok.NonNull;
 
 /**
@@ -12,8 +12,9 @@ import lombok.NonNull;
  * @author Woody
  * @date 2024/12/27
  */
-public class AESCipherHandler implements CipherHandler {
-    protected final Cipher encryptor, decrypter;
+@Getter
+public class AESCipherHandler extends AbstractCipherHandler {
+    private final Cipher encryptor, decrypter;
 
     public AESCipherHandler(@NonNull String secret) {
         this(AESUtils.ECB_PKCS5PADDING, secret);
@@ -28,14 +29,4 @@ public class AESCipherHandler implements CipherHandler {
         this.encryptor = AESUtils.getEncryptor(name, secret, iv);
         this.decrypter = AESUtils.getDecrypter(name, secret, iv);
     }
-
-    @Override
-    public byte[] encrypt(byte[] bytes) {
-        return CodecUtils.codec(this.encryptor, bytes);
-    }
-
-    @Override
-    public byte[] decrypt(byte[] bytes) {
-        return CodecUtils.codec(this.decrypter, bytes);
-    }
 }

+ 40 - 0
framework-base/src/main/java/com/chelvc/framework/base/crypto/AbstractCipherHandler.java

@@ -0,0 +1,40 @@
+package com.chelvc.framework.base.crypto;
+
+import java.util.Objects;
+import javax.crypto.Cipher;
+
+import com.chelvc.framework.common.util.CodecUtils;
+
+/**
+ * 加解密处理抽象实现
+ *
+ * @author Woody
+ * @date 2025/1/14
+ */
+public abstract class AbstractCipherHandler implements CipherHandler {
+    /**
+     * 获取加密处理器
+     *
+     * @return 密码处理器实例
+     */
+    public abstract Cipher getEncryptor();
+
+    /**
+     * 获取解密处理器
+     *
+     * @return 密码处理器实例
+     */
+    public abstract Cipher getDecrypter();
+
+    @Override
+    public byte[] encrypt(byte[] bytes) {
+        Cipher encryptor = Objects.requireNonNull(this.getEncryptor());
+        return CodecUtils.codec(encryptor, bytes);
+    }
+
+    @Override
+    public byte[] decrypt(byte[] bytes) {
+        Cipher decrypter = Objects.requireNonNull(this.getDecrypter());
+        return CodecUtils.codec(decrypter, bytes);
+    }
+}

+ 32 - 17
framework-base/src/main/java/com/chelvc/framework/base/crypto/CipherHandler.java

@@ -1,13 +1,16 @@
 package com.chelvc.framework.base.crypto;
 
 import java.nio.charset.StandardCharsets;
+import java.util.Collection;
+import java.util.Collections;
 import java.util.List;
 import java.util.Set;
-import java.util.stream.Collectors;
 
 import com.chelvc.framework.common.util.CodecUtils;
 import com.chelvc.framework.common.util.ObjectUtils;
 import com.chelvc.framework.common.util.StringUtils;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
 import org.apache.commons.codec.binary.Base64;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -116,31 +119,37 @@ public interface CipherHandler {
         if (ObjectUtils.isEmpty(plaintexts)) {
             return plaintexts;
         }
-        return plaintexts.stream().map(plaintext -> this.encrypt(plaintext, force)).collect(Collectors.toSet());
+        Set<String> ciphertexts = Sets.newHashSetWithExpectedSize(plaintexts.size());
+        plaintexts.forEach(plaintext -> ciphertexts.add(this.encrypt(plaintext, force)));
+        return ciphertexts;
     }
 
     /**
      * 数据加密
      *
-     * @param plaintexts 明文列表
+     * @param plaintexts 明文集合
      * @return 密文列表
      */
-    default List<String> encrypt(List<String> plaintexts) {
+    default List<String> encrypt(Collection<String> plaintexts) {
         return this.encrypt(plaintexts, false);
     }
 
     /**
      * 数据加密
      *
-     * @param plaintexts 明文列表
+     * @param plaintexts 明文集合
      * @param force      是否忽略异常
      * @return 密文列表
      */
-    default List<String> encrypt(List<String> plaintexts, boolean force) {
-        if (ObjectUtils.isEmpty(plaintexts)) {
-            return plaintexts;
+    default List<String> encrypt(Collection<String> plaintexts, boolean force) {
+        if (plaintexts == null) {
+            return null;
+        } else if (plaintexts.isEmpty()) {
+            return Collections.emptyList();
         }
-        return plaintexts.stream().map(plaintext -> this.encrypt(plaintext, force)).collect(Collectors.toList());
+        List<String> ciphertexts = Lists.newArrayListWithCapacity(plaintexts.size());
+        plaintexts.forEach(plaintext -> ciphertexts.add(this.encrypt(plaintext, force)));
+        return ciphertexts;
     }
 
     /**
@@ -235,30 +244,36 @@ public interface CipherHandler {
         if (ObjectUtils.isEmpty(ciphertexts)) {
             return ciphertexts;
         }
-        return ciphertexts.stream().map(ciphertext -> this.decrypt(ciphertext, force)).collect(Collectors.toSet());
+        Set<String> plaintexts = Sets.newHashSetWithExpectedSize(ciphertexts.size());
+        ciphertexts.forEach(ciphertext -> plaintexts.add(this.decrypt(ciphertext, force)));
+        return plaintexts;
     }
 
     /**
      * 数据解密
      *
-     * @param ciphertexts 密文列表
+     * @param ciphertexts 密文集合
      * @return 明文列表
      */
-    default List<String> decrypt(List<String> ciphertexts) {
+    default List<String> decrypt(Collection<String> ciphertexts) {
         return this.decrypt(ciphertexts, false);
     }
 
     /**
      * 数据解密
      *
-     * @param ciphertexts 密文列表
+     * @param ciphertexts 密文集合
      * @param force       是否忽略异常
      * @return 明文列表
      */
-    default List<String> decrypt(List<String> ciphertexts, boolean force) {
-        if (ObjectUtils.isEmpty(ciphertexts)) {
-            return ciphertexts;
+    default List<String> decrypt(Collection<String> ciphertexts, boolean force) {
+        if (ciphertexts == null) {
+            return null;
+        } else if (ciphertexts.isEmpty()) {
+            return Collections.emptyList();
         }
-        return ciphertexts.stream().map(ciphertext -> this.decrypt(ciphertext, force)).collect(Collectors.toList());
+        List<String> plaintexts = Lists.newArrayListWithCapacity(ciphertexts.size());
+        ciphertexts.forEach(ciphertext -> plaintexts.add(this.decrypt(ciphertext, force)));
+        return plaintexts;
     }
 }

+ 5 - 23
framework-database/src/main/java/com/chelvc/framework/database/crypto/DefaultDatabaseCipherHandler.java

@@ -2,10 +2,11 @@ package com.chelvc.framework.database.crypto;
 
 import javax.crypto.Cipher;
 
+import com.chelvc.framework.base.crypto.AbstractCipherHandler;
 import com.chelvc.framework.common.util.AESUtils;
-import com.chelvc.framework.common.util.CodecUtils;
 import com.chelvc.framework.common.util.StringUtils;
 import com.chelvc.framework.database.config.DatabaseProperties;
+import lombok.Getter;
 import lombok.NonNull;
 
 /**
@@ -14,9 +15,10 @@ import lombok.NonNull;
  * @author Woody
  * @date 2024/12/27
  */
-public class DefaultDatabaseCipherHandler implements DatabaseCipherHandler {
+@Getter
+public class DefaultDatabaseCipherHandler extends AbstractCipherHandler implements DatabaseCipherHandler {
     private final boolean mixed, writable;
-    protected final Cipher encryptor, decrypter;
+    private final Cipher encryptor, decrypter;
 
     public DefaultDatabaseCipherHandler(@NonNull DatabaseProperties.Crypto properties) {
         this.mixed = properties.isMixed();
@@ -28,24 +30,4 @@ public class DefaultDatabaseCipherHandler implements DatabaseCipherHandler {
                 properties.getSecret(), secret -> AESUtils.getDecrypter(AESUtils.ECB_PKCS5PADDING, secret)
         );
     }
-
-    @Override
-    public boolean isMixed() {
-        return this.mixed;
-    }
-
-    @Override
-    public boolean isWritable() {
-        return this.writable;
-    }
-
-    @Override
-    public byte[] encrypt(byte[] bytes) {
-        return CodecUtils.codec(this.encryptor, bytes);
-    }
-
-    @Override
-    public byte[] decrypt(byte[] bytes) {
-        return CodecUtils.codec(this.decrypter, bytes);
-    }
 }

+ 5 - 5
framework-database/src/main/java/com/chelvc/framework/database/handler/JsonTypeHandler.java

@@ -51,7 +51,7 @@ public interface JsonTypeHandler<T> extends TypeHandler<T> {
     /**
      * 对象JSON序列化/反序列化处理器实例
      */
-    ObjectMapper mapper = JacksonUtils.initializeSerializer().setAnnotationIntrospector(
+    ObjectMapper MAPPER = JacksonUtils.initializeSerializer().setAnnotationIntrospector(
             new JacksonAnnotationIntrospector() {
                 @Override
                 public Object findSerializer(Annotated am) {
@@ -204,7 +204,7 @@ public interface JsonTypeHandler<T> extends TypeHandler<T> {
      * @throws SQLException SQL异常
      */
     default void setNonNullParameter(PreparedStatement ps, int i, T parameter, JdbcType jdbcType) throws SQLException {
-        ps.setString(i, JacksonUtils.serialize(mapper, parameter));
+        ps.setString(i, JacksonUtils.serialize(MAPPER, parameter));
     }
 
     /**
@@ -217,7 +217,7 @@ public interface JsonTypeHandler<T> extends TypeHandler<T> {
      */
     @SuppressWarnings("unchecked")
     default T getNullableResult(ResultSet rs, String columnName) throws SQLException {
-        return (T) JacksonUtils.deserialize(mapper, rs.getString(columnName), this.getType());
+        return (T) JacksonUtils.deserialize(MAPPER, rs.getString(columnName), this.getType());
     }
 
     /**
@@ -230,7 +230,7 @@ public interface JsonTypeHandler<T> extends TypeHandler<T> {
      */
     @SuppressWarnings("unchecked")
     default T getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
-        return (T) JacksonUtils.deserialize(mapper, rs.getString(columnIndex), this.getType());
+        return (T) JacksonUtils.deserialize(MAPPER, rs.getString(columnIndex), this.getType());
     }
 
     /**
@@ -243,7 +243,7 @@ public interface JsonTypeHandler<T> extends TypeHandler<T> {
      */
     @SuppressWarnings("unchecked")
     default T getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
-        return (T) JacksonUtils.deserialize(mapper, cs.getString(columnIndex), this.getType());
+        return (T) JacksonUtils.deserialize(MAPPER, cs.getString(columnIndex), this.getType());
     }
 
     /**

+ 16 - 10
framework-security/src/main/java/com/chelvc/framework/security/config/AuthorizeConfigurer.java → framework-security/src/main/java/com/chelvc/framework/security/config/OAuthConfigurer.java

@@ -21,10 +21,10 @@ import com.chelvc.framework.common.util.AssertUtils;
 import com.chelvc.framework.common.util.ObjectUtils;
 import com.chelvc.framework.common.util.StringUtils;
 import com.chelvc.framework.security.annotation.Authorize;
-import com.chelvc.framework.security.context.AuthorizeContextHolder;
-import com.chelvc.framework.security.token.DefaultSessionValidator;
-import com.chelvc.framework.security.token.SessionValidator;
-import com.chelvc.framework.security.token.TimestampTokenValidator;
+import com.chelvc.framework.security.context.SecurityContextHolder;
+import com.chelvc.framework.security.session.DefaultSessionValidator;
+import com.chelvc.framework.security.session.SessionValidator;
+import com.chelvc.framework.security.session.TokenExpiredValidator;
 import com.google.common.collect.Sets;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
@@ -66,26 +66,32 @@ import org.springframework.security.web.access.AccessDeniedHandler;
  * @author Woody
  * @date 2024/1/30
  */
+
+/**
+ * OAuth认证配置
+ *
+ * @author Woody
+ * @date 2024/1/30
+ */
 @Slf4j
 @EnableWebSecurity
 @RequiredArgsConstructor(onConstructor = @__(@Autowired))
-@ConditionalOnProperty(value = "security.authorize.enabled", havingValue = "true")
-public class AuthorizeConfigurer extends WebSecurityConfigurerAdapter {
+@ConditionalOnProperty(value = "security.oauth.enabled", havingValue = "true")
+public class OAuthConfigurer extends WebSecurityConfigurerAdapter {
     private final SecurityProperties properties;
     private final ApplicationContext applicationContext;
 
     @Bean
     public JwtDecoder jwtDecoder() {
         // 构建JWT解码器实例
-        String secret = this.properties.getAuthorize().getSecret();
+        String secret = this.properties.getOauth().getSecret();
         AssertUtils.check(StringUtils.notEmpty(secret), () -> "Jwt secret is missing");
         SecretKey key = new SecretKeySpec(secret.getBytes(), AESUtils.ALGORITHM);
         NimbusJwtDecoder decoder = NimbusJwtDecoder.withSecretKey(key).build();
 
         // 添加自定义令牌验证器
         Collection<OAuth2TokenValidator<Jwt>> validators = Arrays.asList(
-                new TimestampTokenValidator(),
-                this.applicationContext.getBean(SessionValidator.class)
+                new TokenExpiredValidator(), this.applicationContext.getBean(SessionValidator.class)
         );
         decoder.setJwtValidator(new DelegatingOAuth2TokenValidator<>(validators));
         return decoder;
@@ -128,7 +134,7 @@ public class AuthorizeConfigurer extends WebSecurityConfigurerAdapter {
         JwtAuthenticationConverter jwtAuthenticationConverter = new JwtAuthenticationConverter();
         JwtGrantedAuthoritiesConverter jwtGrantedAuthoritiesConverter = new JwtGrantedAuthoritiesConverter();
         jwtGrantedAuthoritiesConverter.setAuthorityPrefix(StringUtils.EMPTY);
-        jwtGrantedAuthoritiesConverter.setAuthoritiesClaimName(AuthorizeContextHolder.AUTHORITIES);
+        jwtGrantedAuthoritiesConverter.setAuthoritiesClaimName(SecurityContextHolder.AUTHORITIES);
         jwtAuthenticationConverter.setJwtGrantedAuthoritiesConverter(jwtGrantedAuthoritiesConverter);
         return jwtAuthenticationConverter;
     }

+ 24 - 29
framework-security/src/main/java/com/chelvc/framework/security/config/SecurityProperties.java

@@ -18,6 +18,11 @@ import org.springframework.context.annotation.Configuration;
 @Configuration
 @ConfigurationProperties("security")
 public class SecurityProperties {
+    /**
+     * OAuth认证配置
+     */
+    private final OAuth oauth = new OAuth();
+
     /**
      * 加解密配置
      */
@@ -28,30 +33,30 @@ public class SecurityProperties {
      */
     private final Request request = new Request();
 
-    /**
-     * 认证配置
-     */
-    private final Authorize authorize = new Authorize();
-
     /**
      * 忽略地址列表
      */
     private List<String> ignores = Collections.emptyList();
 
     /**
-     * 使用配置
+     * OAuth认证信息
      */
     @Data
-    public static class Request {
+    public static class OAuth {
         /**
-         * 请求时长(毫秒)
+         * 令牌密钥
+         */
+        private String secret;
+
+        /**
+         * 是否区分应用范围
          */
-        private long duration = 60 * 1000;
+        private boolean scoped = false;
 
         /**
-         * 使用刷新时间间隔(毫秒)
+         * 是否启用认证
          */
-        private long interval = Using.DEFAULT_NEWLY_INTERVAL;
+        private boolean enabled = true;
     }
 
     /**
@@ -86,14 +91,9 @@ public class SecurityProperties {
         private String secret;
 
         /**
-         * 是否混合读取(同时包含明文、密文)
-         */
-        private boolean mixed = false;
-
-        /**
-         * 是否可写入密文
+         * 加解密向量
          */
-        private boolean writable = true;
+        private String iv;
 
         /**
          * 加解密缓存配置
@@ -102,23 +102,18 @@ public class SecurityProperties {
     }
 
     /**
-     * 认证信息
+     * 使用配置
      */
     @Data
-    public static class Authorize {
-        /**
-         * 令牌密钥
-         */
-        private String secret;
-
+    public static class Request {
         /**
-         * 是否区分应用范围
+         * 请求过期时长(毫秒)
          */
-        private boolean scoped = false;
+        private long expiration = 60 * 1000;
 
         /**
-         * 是否启用认证
+         * 使用分类刷新时间间隔(毫秒)
          */
-        private boolean enabled = true;
+        private long usingRefreshInterval = Using.DEFAULT_NEWLY_INTERVAL;
     }
 }

+ 0 - 111
framework-security/src/main/java/com/chelvc/framework/security/context/AuthorizeContextHolder.java

@@ -1,111 +0,0 @@
-package com.chelvc.framework.security.context;
-
-import java.util.Collections;
-import java.util.List;
-import java.util.Set;
-
-import com.chelvc.framework.common.util.ObjectUtils;
-import com.chelvc.framework.common.util.StringUtils;
-import com.google.common.collect.Sets;
-import lombok.NonNull;
-import org.springframework.security.oauth2.jwt.Jwt;
-
-/**
- * 认证上下文工具类
- *
- * @author Woody
- * @date 2024/1/30
- */
-public final class AuthorizeContextHolder {
-    /**
-     * 应用范围标识
-     */
-    public static final String SCOPE = "scope";
-
-    /**
-     * 客户端登陆标识
-     */
-    public static final String CLIENT = "client";
-
-    /**
-     * 手机号码标识
-     */
-    public static final String MOBILE = "mobile";
-
-    /**
-     * 用户账号标识
-     */
-    public static final String USERNAME = "user_name";
-
-    /**
-     * 主体创建时间戳
-     */
-    public static final String CREATING = "creating";
-
-    /**
-     * 主体注册时间戳
-     */
-    public static final String REGISTERING = "registering";
-
-    /**
-     * 用户权限标识
-     */
-    public static final String AUTHORITIES = "authorities";
-
-    private AuthorizeContextHolder() {
-    }
-
-    /**
-     * 构建访问令牌标识
-     *
-     * @param id 主体标识
-     * @return 令牌标识
-     */
-    public static String key(@NonNull Object id) {
-        return "token:" + id;
-    }
-
-    /**
-     * 获取主体身份
-     *
-     * @param jwt JWT对象
-     * @return 主体身份标识
-     */
-    public static Long getId(Jwt jwt) {
-        return jwt == null ? null : StringUtils.ifEmpty(jwt.getClaimAsString(USERNAME), Long::parseLong);
-    }
-
-    /**
-     * 获取应用范围
-     *
-     * @param jwt Jwt对象
-     * @return 应用范围
-     */
-    public static String getScope(Jwt jwt) {
-        return jwt == null ? null : StringUtils.ifEmpty(jwt.getClaimAsString(SCOPE), (String) null);
-    }
-
-    /**
-     * 是否是客户端登陆
-     *
-     * @param jwt Jwt对象
-     * @return true/false
-     */
-    public static boolean isClient(Jwt jwt) {
-        return jwt != null && Boolean.TRUE.equals(jwt.getClaimAsBoolean(CLIENT));
-    }
-
-    /**
-     * 获取用户授权信息
-     *
-     * @param jwt JWT对象
-     * @return 授权信息集合
-     */
-    public static Set<String> getAuthorities(Jwt jwt) {
-        if (jwt == null) {
-            return Collections.emptySet();
-        }
-        List<String> authorities = jwt.getClaimAsStringList(AUTHORITIES);
-        return ObjectUtils.isEmpty(authorities) ? Collections.emptySet() : Sets.newHashSet(authorities);
-    }
-}

+ 84 - 0
framework-security/src/main/java/com/chelvc/framework/security/context/SecurityContextHolder.java

@@ -1,5 +1,7 @@
 package com.chelvc.framework.security.context;
 
+import java.util.Collections;
+import java.util.List;
 import java.util.Set;
 import java.util.stream.Stream;
 
@@ -7,8 +9,11 @@ import com.chelvc.framework.base.context.ApplicationContextHolder;
 import com.chelvc.framework.base.context.Session;
 import com.chelvc.framework.base.context.SessionContextHolder;
 import com.chelvc.framework.common.util.ObjectUtils;
+import com.chelvc.framework.common.util.StringUtils;
 import com.chelvc.framework.security.crypto.SecurityCipherHandler;
+import com.google.common.collect.Sets;
 import lombok.NonNull;
+import org.springframework.security.oauth2.jwt.Jwt;
 
 /**
  * 应用安全相关操作上下文工具类
@@ -17,6 +22,41 @@ import lombok.NonNull;
  * @date 2024/5/24
  */
 public final class SecurityContextHolder {
+    /**
+     * 应用范围标识
+     */
+    public static final String SCOPE = "scope";
+
+    /**
+     * 客户端登陆标识
+     */
+    public static final String CLIENT = "client";
+
+    /**
+     * 手机号码标识
+     */
+    public static final String MOBILE = "mobile";
+
+    /**
+     * 用户账号标识
+     */
+    public static final String USERNAME = "user_name";
+
+    /**
+     * 主体创建时间戳
+     */
+    public static final String CREATING = "creating";
+
+    /**
+     * 主体注册时间戳
+     */
+    public static final String REGISTERING = "registering";
+
+    /**
+     * 用户权限标识
+     */
+    public static final String AUTHORITIES = "authorities";
+
     /**
      * 默认权限分组
      */
@@ -30,6 +70,50 @@ public final class SecurityContextHolder {
     private SecurityContextHolder() {
     }
 
+    /**
+     * 获取主体身份
+     *
+     * @param jwt JWT对象
+     * @return 主体身份标识
+     */
+    public static Long getId(Jwt jwt) {
+        return jwt == null ? null : StringUtils.ifEmpty(jwt.getClaimAsString(USERNAME), Long::parseLong);
+    }
+
+    /**
+     * 获取应用范围
+     *
+     * @param jwt Jwt对象
+     * @return 应用范围
+     */
+    public static String getScope(Jwt jwt) {
+        return jwt == null ? null : StringUtils.ifEmpty(jwt.getClaimAsString(SCOPE), (String) null);
+    }
+
+    /**
+     * 是否是客户端登陆
+     *
+     * @param jwt Jwt对象
+     * @return true/false
+     */
+    public static boolean isClient(Jwt jwt) {
+        return jwt != null && Boolean.TRUE.equals(jwt.getClaimAsBoolean(CLIENT));
+    }
+
+    /**
+     * 获取用户授权信息
+     *
+     * @param jwt JWT对象
+     * @return 授权信息集合
+     */
+    public static Set<String> getAuthorities(Jwt jwt) {
+        if (jwt == null) {
+            return Collections.emptySet();
+        }
+        List<String> authorities = jwt.getClaimAsStringList(AUTHORITIES);
+        return ObjectUtils.isEmpty(authorities) ? Collections.emptySet() : Sets.newHashSet(authorities);
+    }
+
     /**
      * 获取数据安全加解密处理器
      *

+ 2 - 1
framework-security/src/main/java/com/chelvc/framework/security/crypto/AbstractSecurityCipherHandler.java

@@ -1,6 +1,7 @@
 package com.chelvc.framework.security.crypto;
 
 import com.chelvc.framework.base.context.Session;
+import com.chelvc.framework.base.crypto.AbstractCipherHandler;
 import com.chelvc.framework.common.util.CodecUtils;
 import com.chelvc.framework.common.util.ObjectUtils;
 import com.chelvc.framework.common.util.StringUtils;
@@ -13,7 +14,7 @@ import lombok.NonNull;
  * @author Woody
  * @date 2025/1/6
  */
-public abstract class AbstractSecurityCipherHandler implements SecurityCipherHandler {
+public abstract class AbstractSecurityCipherHandler extends AbstractCipherHandler implements SecurityCipherHandler {
     protected final String secret;
 
     public AbstractSecurityCipherHandler(@NonNull SecurityProperties.Crypto properties) {

+ 0 - 38
framework-security/src/main/java/com/chelvc/framework/security/crypto/CustomizeSecurityCipherHandler.java

@@ -1,38 +0,0 @@
-package com.chelvc.framework.security.crypto;
-
-import javax.crypto.Cipher;
-
-import com.chelvc.framework.common.util.CodecUtils;
-import com.chelvc.framework.security.config.SecurityProperties;
-import lombok.NonNull;
-
-/**
- * 自定义数据安全加解密处理抽象实现
- *
- * @author Woody
- * @date 2025/1/6
- */
-public abstract class CustomizeSecurityCipherHandler extends AbstractSecurityCipherHandler
-        implements SecurityCipherHandler {
-    public CustomizeSecurityCipherHandler(@NonNull SecurityProperties.Crypto properties) {
-        super(properties);
-    }
-
-    /**
-     * 获取密码处理器
-     *
-     * @param mode 加解密模式
-     * @return 密码处理器
-     */
-    protected abstract Cipher getCipher(int mode);
-
-    @Override
-    public byte[] encrypt(byte[] bytes) {
-        return CodecUtils.codec(this.getCipher(Cipher.ENCRYPT_MODE), bytes);
-    }
-
-    @Override
-    public byte[] decrypt(byte[] bytes) {
-        return CodecUtils.codec(this.getCipher(Cipher.DECRYPT_MODE), bytes);
-    }
-}

+ 8 - 36
framework-security/src/main/java/com/chelvc/framework/security/crypto/DefaultSecurityCipherHandler.java

@@ -3,9 +3,9 @@ package com.chelvc.framework.security.crypto;
 import javax.crypto.Cipher;
 
 import com.chelvc.framework.common.util.AESUtils;
-import com.chelvc.framework.common.util.CodecUtils;
 import com.chelvc.framework.common.util.StringUtils;
 import com.chelvc.framework.security.config.SecurityProperties;
+import lombok.Getter;
 import lombok.NonNull;
 
 /**
@@ -14,44 +14,16 @@ import lombok.NonNull;
  * @author Woody
  * @date 2025/1/3
  */
+@Getter
 public class DefaultSecurityCipherHandler extends AbstractSecurityCipherHandler implements SecurityCipherHandler {
-    protected final Cipher encryptor, decrypter;
+    private final Cipher encryptor, decrypter;
 
     public DefaultSecurityCipherHandler(@NonNull SecurityProperties.Crypto properties) {
         super(properties);
-        String name = AESUtils.CBC_PKCS5PADDING, iv = this.str2iv(this.secret);
-        this.encryptor = StringUtils.isEmpty(this.secret) ? null : AESUtils.getEncryptor(name, this.secret, iv);
-        this.decrypter = StringUtils.isEmpty(this.secret) ? null : AESUtils.getDecrypter(name, this.secret, iv);
-    }
-
-    /**
-     * 根据字符串获取向量
-     *
-     * @param str 字符串
-     * @return 向量
-     */
-    private String str2iv(String str) {
-        if (StringUtils.isEmpty(str)) {
-            return str;
-        }
-        int size = Math.min(str.length(), 16);
-        if (size == 1) {
-            return str;
-        }
-        StringBuilder iv = new StringBuilder(size);
-        for (int i = str.length() - 1, max = 0; i >= 0 && max < size; i--, max++) {
-            iv.append(str.charAt(i));
-        }
-        return iv.toString();
-    }
-
-    @Override
-    public byte[] encrypt(byte[] bytes) {
-        return CodecUtils.codec(this.encryptor, bytes);
-    }
-
-    @Override
-    public byte[] decrypt(byte[] bytes) {
-        return CodecUtils.codec(this.decrypter, bytes);
+        String name = AESUtils.CBC_PKCS5PADDING, secret = properties.getSecret(), iv = properties.getIv();
+        this.encryptor = StringUtils.ifEmpty(secret, s -> StringUtils.isEmpty(iv) ?
+                AESUtils.getEncryptor(name, secret) : AESUtils.getEncryptor(name, secret, iv));
+        this.decrypter = StringUtils.ifEmpty(secret, s -> StringUtils.isEmpty(iv) ?
+                AESUtils.getDecrypter(name, secret) : AESUtils.getDecrypter(name, secret, iv));
     }
 }

+ 2 - 2
framework-security/src/main/java/com/chelvc/framework/security/interceptor/SecurityValidateInterceptor.java

@@ -148,8 +148,8 @@ public class SecurityValidateInterceptor implements HandlerInterceptor, WebMvcCo
             throw new FrameworkException(HttpStatus.BAD_REQUEST.name(), null,
                     ApplicationContextHolder.getMessage("Header.Missing"));
         }
-        long duration = this.properties.getRequest().getDuration();
-        if (duration > 0 && Math.abs(System.currentTimeMillis() - session.getTimestamp()) > duration) {
+        long expiration = this.properties.getRequest().getExpiration();
+        if (expiration > 0 && Math.abs(System.currentTimeMillis() - session.getTimestamp()) > expiration) {
             throw new FrameworkException(HttpStatus.BAD_REQUEST.name(), null,
                     ApplicationContextHolder.getMessage("Time.Deviated"));
         }

+ 6 - 6
framework-security/src/main/java/com/chelvc/framework/security/token/DefaultSessionValidator.java → framework-security/src/main/java/com/chelvc/framework/security/session/DefaultSessionValidator.java

@@ -1,10 +1,10 @@
-package com.chelvc.framework.security.token;
+package com.chelvc.framework.security.session;
 
 import java.util.Set;
 
 import com.chelvc.framework.base.context.ApplicationContextHolder;
 import com.chelvc.framework.base.context.SessionContextHolder;
-import com.chelvc.framework.security.context.AuthorizeContextHolder;
+import com.chelvc.framework.security.context.SecurityContextHolder;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.security.oauth2.core.OAuth2AuthenticationException;
 import org.springframework.security.oauth2.core.OAuth2Error;
@@ -27,7 +27,7 @@ public class DefaultSessionValidator implements SessionValidator {
      */
     protected Long getId(Jwt jwt) {
         try {
-            return AuthorizeContextHolder.getId(jwt);
+            return SecurityContextHolder.getId(jwt);
         } catch (Exception e) {
             log.error("JWT id convert failed", e);
             throw new OAuth2AuthenticationException(new OAuth2Error(
@@ -43,7 +43,7 @@ public class DefaultSessionValidator implements SessionValidator {
      * @return 应用范围
      */
     protected String getScope(Jwt jwt) {
-        return AuthorizeContextHolder.getScope(jwt);
+        return SecurityContextHolder.getScope(jwt);
     }
 
     /**
@@ -53,12 +53,12 @@ public class DefaultSessionValidator implements SessionValidator {
      * @return 授权信息集合
      */
     protected Set<String> getAuthorities(Jwt jwt) {
-        return AuthorizeContextHolder.getAuthorities(jwt);
+        return SecurityContextHolder.getAuthorities(jwt);
     }
 
     @Override
     public OAuth2TokenValidatorResult validate(Jwt jwt) {
-        if (!AuthorizeContextHolder.isClient(jwt)) {
+        if (!SecurityContextHolder.isClient(jwt)) {
             SessionContextHolder.setSession(this.getId(jwt), this.getScope(jwt), this.getAuthorities(jwt));
         }
         return OAuth2TokenValidatorResult.success();

+ 3 - 3
framework-security/src/main/java/com/chelvc/framework/security/context/AuthorizeSessionFactory.java → framework-security/src/main/java/com/chelvc/framework/security/session/OAuthSessionFactory.java

@@ -1,4 +1,4 @@
-package com.chelvc.framework.security.context;
+package com.chelvc.framework.security.session;
 
 import java.util.Collections;
 import javax.servlet.http.HttpServletRequest;
@@ -11,13 +11,13 @@ import lombok.NonNull;
 import org.springframework.stereotype.Component;
 
 /**
- * 认证会话工厂
+ * OAuth认证会话工厂
  *
  * @author Woody
  * @date 2024/7/7
  */
 @Component
-public class AuthorizeSessionFactory extends DefaultSessionFactory implements SessionFactory {
+public class OAuthSessionFactory extends DefaultSessionFactory implements SessionFactory {
     @Override
     public Session build(@NonNull HttpServletRequest request) {
         return Session.builder().using(Using.NORMAL).host(this.getHost(request))

+ 11 - 11
framework-security/src/main/java/com/chelvc/framework/security/token/RedisSessionValidator.java → framework-security/src/main/java/com/chelvc/framework/security/session/RedisSessionValidator.java

@@ -1,4 +1,4 @@
-package com.chelvc.framework.security.token;
+package com.chelvc.framework.security.session;
 
 import java.util.Map;
 import java.util.Objects;
@@ -12,7 +12,7 @@ import com.chelvc.framework.redis.context.RedisContextHolder;
 import com.chelvc.framework.redis.context.RedisHashHolder;
 import com.chelvc.framework.redis.context.RedisUserDailyHashHolder;
 import com.chelvc.framework.security.config.SecurityProperties;
-import com.chelvc.framework.security.context.AuthorizeContextHolder;
+import com.chelvc.framework.security.context.SecurityContextHolder;
 import lombok.RequiredArgsConstructor;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
@@ -37,14 +37,14 @@ public class RedisSessionValidator extends DefaultSessionValidator {
 
     @Override
     public OAuth2TokenValidatorResult validate(Jwt jwt) {
-        if (AuthorizeContextHolder.isClient(jwt)) {
+        if (SecurityContextHolder.isClient(jwt)) {
             return OAuth2TokenValidatorResult.success();
         }
 
         // 校验令牌有效性
         Long id = this.getId(jwt);
         RedisTemplate<String, Object> template = RedisContextHolder.getDefaultTemplate();
-        Map<String, ?> context = RedisHashHolder.get(template, AuthorizeContextHolder.key(id));
+        Map<String, ?> context = RedisHashHolder.get(template, "token:" + id);
         String terminal = String.valueOf(SessionContextHolder.getTerminal());
         String token = (String) context.get(terminal), scope = this.getScope(jwt);
         if (StringUtils.isEmpty(token)) {
@@ -56,9 +56,9 @@ public class RedisSessionValidator extends DefaultSessionValidator {
             throw new OAuth2AuthenticationException(new OAuth2Error(
                     "TOKEN_CHANGED", ApplicationContextHolder.getMessage("Token.Changed"), null
             ));
-        } else if (this.properties.getAuthorize().isScoped()) {
+        } else if (this.properties.getOauth().isScoped()) {
             // 判断应用范围是否相同,如果不同则表示应用范围已被重置,需要刷新令牌
-            String real = (String) context.get(AuthorizeContextHolder.SCOPE);
+            String real = (String) context.get(SecurityContextHolder.SCOPE);
             if (!Objects.equals(scope, real)) {
                 String arg = StringUtils.ifEmpty(real, ApplicationContextHolder::getMessage);
                 String message = ApplicationContextHolder.getMessage("Scope.Changed", new Object[]{arg});
@@ -67,12 +67,12 @@ public class RedisSessionValidator extends DefaultSessionValidator {
         }
 
         // 更新会话主体信息
-        long interval = this.properties.getRequest().getInterval();
-        String mobile = (String) context.get(AuthorizeContextHolder.MOBILE);
-        Long creating = (Long) context.get(AuthorizeContextHolder.CREATING);
-        Long registering = (Long) context.get(AuthorizeContextHolder.REGISTERING);
+        String mobile = (String) context.get(SecurityContextHolder.MOBILE);
+        Long creating = (Long) context.get(SecurityContextHolder.CREATING);
+        Long registering = (Long) context.get(SecurityContextHolder.REGISTERING);
+        long interval = this.properties.getRequest().getUsingRefreshInterval();
         Using using = Using.from(RedisUserDailyHashHolder.using(template, id), creating, interval);
-        Set<String> authorities = AuthorizeContextHolder.getAuthorities(jwt);
+        Set<String> authorities = SecurityContextHolder.getAuthorities(jwt);
         SessionContextHolder.setSession(id, using, scope, mobile, registering, authorities);
         return OAuth2TokenValidatorResult.success();
     }

+ 1 - 1
framework-security/src/main/java/com/chelvc/framework/security/token/SessionValidator.java → framework-security/src/main/java/com/chelvc/framework/security/session/SessionValidator.java

@@ -1,4 +1,4 @@
-package com.chelvc.framework.security.token;
+package com.chelvc.framework.security.session;
 
 import org.springframework.security.oauth2.core.OAuth2TokenValidator;
 import org.springframework.security.oauth2.jwt.Jwt;

+ 3 - 3
framework-security/src/main/java/com/chelvc/framework/security/token/TimestampTokenValidator.java → framework-security/src/main/java/com/chelvc/framework/security/session/TokenExpiredValidator.java

@@ -1,4 +1,4 @@
-package com.chelvc.framework.security.token;
+package com.chelvc.framework.security.session;
 
 import com.chelvc.framework.base.context.ApplicationContextHolder;
 import org.springframework.security.oauth2.core.OAuth2AuthenticationException;
@@ -9,12 +9,12 @@ import org.springframework.security.oauth2.jwt.Jwt;
 import org.springframework.security.oauth2.jwt.JwtTimestampValidator;
 
 /**
- * 令牌时间戳验证器实现
+ * 令牌过期验证器实现
  *
  * @author Woody
  * @date 2024/6/23
  */
-public class TimestampTokenValidator implements OAuth2TokenValidator<Jwt> {
+public class TokenExpiredValidator implements OAuth2TokenValidator<Jwt> {
     private final JwtTimestampValidator delegate = new JwtTimestampValidator();
 
     @Override