瀏覽代碼

重构登录信息,新增静态工具类(用于获取当前登录用户基础信息)

tsurumure 10 月之前
父節點
當前提交
18e321a473
共有 29 個文件被更改,包括 291 次插入580 次删除
  1. 4 5
      src/main/java/com/backendsys/aspect/HttpRequestAspect.java
  2. 2 2
      src/main/java/com/backendsys/config/Interceptor/TranslationInterceptor.java
  3. 2 2
      src/main/java/com/backendsys/config/Redis/utils/RedisUtil.java
  4. 1 5
      src/main/java/com/backendsys/config/Security/ApplicationConfig.java
  5. 0 10
      src/main/java/com/backendsys/config/Security/CorsConfig.java
  6. 0 205
      src/main/java/com/backendsys/config/Security/__SecurityConfig.java
  7. 22 0
      src/main/java/com/backendsys/config/Security/entity/SecurityUserInfo.java
  8. 27 22
      src/main/java/com/backendsys/config/Security/filter/JwtAuthenticationFilter.java
  9. 0 112
      src/main/java/com/backendsys/config/Security/service/__PermissionService.java
  10. 33 15
      src/main/java/com/backendsys/config/Security/utils/JwtUtil.java
  11. 21 42
      src/main/java/com/backendsys/config/Security/utils/PermissionUtil.java
  12. 68 0
      src/main/java/com/backendsys/config/Security/utils/SecurityUtil.java
  13. 16 4
      src/main/java/com/backendsys/config/Security/utils/TokenUtil.java
  14. 0 1
      src/main/java/com/backendsys/config/WebSocket/WebSocketConfig.java
  15. 4 4
      src/main/java/com/backendsys/controller/Systems/SysAuthController.java
  16. 7 7
      src/main/java/com/backendsys/controller/Systems/SysUserController.java
  17. 3 3
      src/main/java/com/backendsys/controller/Systems/SysUserPointController.java
  18. 3 3
      src/main/java/com/backendsys/controller/TestAuthController.java
  19. 0 11
      src/main/java/com/backendsys/modules/system/annotation/LoginUserId.java
  20. 13 4
      src/main/java/com/backendsys/modules/system/controller/SysUserV2Controller.java
  21. 0 63
      src/main/java/com/backendsys/modules/system/interceptor/LoginUserInterceptor.java
  22. 4 4
      src/main/java/com/backendsys/service/Ai/AiChatServiceImpl.java
  23. 4 4
      src/main/java/com/backendsys/service/Ai/Aizn/AiznModelServiceImpl.java
  24. 3 3
      src/main/java/com/backendsys/service/SDKService/SDKTencent/SDKTencentSMSServiceImpl.java
  25. 21 16
      src/main/java/com/backendsys/service/System/SysAuthServiceImpl.java
  26. 5 5
      src/main/java/com/backendsys/service/System/SysMenuServiceImpl.java
  27. 4 7
      src/main/java/com/backendsys/utils/CommonUtil.java
  28. 3 3
      src/main/java/com/backendsys/utils/LanguageUtil.java
  29. 21 18
      src/main/resources/application.yml

+ 4 - 5
src/main/java/com/backendsys/aspect/HttpRequestAspect.java

@@ -1,9 +1,8 @@
 package com.backendsys.aspect;
 
-import com.backendsys.config.Security.service.TokenService;
+import com.backendsys.config.Security.utils.TokenUtil;
 import io.jsonwebtoken.Claims;
 import jakarta.servlet.http.HttpServletRequest;
-import org.aspectj.lang.JoinPoint;
 import org.aspectj.lang.annotation.Aspect;
 import org.aspectj.lang.annotation.Before;
 import org.aspectj.lang.annotation.Pointcut;
@@ -17,7 +16,7 @@ import org.springframework.web.context.request.ServletRequestAttributes;
 public class HttpRequestAspect {
 
     @Autowired
-    private TokenService tokenService;
+    private TokenUtil tokenUtil;
 
     @Pointcut("execution(public * com.backendsys.service.*.*(..))")
     public void serviceMethods() {}
@@ -39,7 +38,7 @@ public class HttpRequestAspect {
     public Long getUserId() {
         HttpServletRequest request = getRequest();
         if (request != null) {
-            Claims tokenInfo = tokenService.getTokenInfo(request);
+            Claims tokenInfo = tokenUtil.getTokenInfo(request);
             if (tokenInfo != null) {
                 Integer memberId = (Integer) tokenInfo.get("user_id");
                 return memberId.longValue();
@@ -55,7 +54,7 @@ public class HttpRequestAspect {
     public Long getMemberId() {
         HttpServletRequest request = getRequest();
         if (request != null) {
-            Claims tokenInfo = tokenService.getTokenInfo(request);
+            Claims tokenInfo = tokenUtil.getTokenInfo(request);
             if (tokenInfo != null) {
                 Integer memberId = (Integer) tokenInfo.get("member_id");
                 return memberId.longValue();

+ 2 - 2
src/main/java/com/backendsys/config/Interceptor/TranslationInterceptor.java

@@ -1,6 +1,6 @@
 // package com.backendsys.config.Interceptor;
 
-// import com.backendsys.config.Security.service.TokenService;
+// import com.backendsys.config.Security.utils.TokenUtil;
 // import jakarta.servlet.http.Cookie;
 // import jakarta.servlet.http.HttpServletRequest;
 // import jakarta.servlet.http.HttpServletResponse;
@@ -16,7 +16,7 @@
 // public class TranslationInterceptor implements HandlerInterceptor {
 
 //    @Autowired
-//    private TokenService tokenService;
+//    private TokenUtil tokenService;
 
 //    @Autowired
 //    private StringRedisTemplate stringRedisTemplate;

+ 2 - 2
src/main/java/com/backendsys/config/Redis/RedisCache.java → src/main/java/com/backendsys/config/Redis/utils/RedisUtil.java

@@ -1,4 +1,4 @@
-package com.backendsys.config.Redis;
+package com.backendsys.config.Redis.utils;
 
 import lombok.RequiredArgsConstructor;
 import org.springframework.data.redis.core.BoundSetOperations;
@@ -13,7 +13,7 @@ import java.util.concurrent.TimeUnit;
 @SuppressWarnings(value = {"unchecked", "rawtypes"})
 @Component
 @RequiredArgsConstructor
-public class RedisCache {
+public class RedisUtil {
 
     private final RedisTemplate redisTemplate;
 

+ 1 - 5
src/main/java/com/backendsys/config/Security/ApplicationConfig.java

@@ -27,16 +27,12 @@ public class ApplicationConfig {
     */
     @Bean
     public UserDetailsService userDetailsService() throws UsernameNotFoundException {
-        //return username -> {
-        //    Map<String, Object> sysUserSimple = sysUserMapper.queryUserByIdOrName(null, username);
-        //    return new User((String) sysUserSimple.get("username"), (String) sysUserSimple.get("password"), AuthorityUtils.commaSeparatedStringToAuthorityList("admin, normal"));
-        //};
 
-        // 接口每次调用都会执行?(username: 1)
         //return username -> {
         //    System.out.println("UserDetailsService (username): " + username);
         //    return new User(username, "", AuthorityUtils.commaSeparatedStringToAuthorityList("admin, normal"));
         //};
+
         return username -> new User(username, "", AuthorityUtils.commaSeparatedStringToAuthorityList("admin, normal"));
     }
 

+ 0 - 10
src/main/java/com/backendsys/config/Security/CorsConfig.java

@@ -1,8 +1,6 @@
 package com.backendsys.config.Security;
 
-//import com.backendsys.config.Interceptor.TranslationInterceptor;
 import com.backendsys.config.Interceptor.PreAuthorizeInterceptor;
-import com.backendsys.modules.system.interceptor.LoginUserInterceptor;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.web.servlet.FilterRegistrationBean;
 import org.springframework.context.annotation.Bean;
@@ -26,9 +24,6 @@ public class CorsConfig implements WebMvcConfigurer {
 //        registry.addInterceptor(translationInterceptor).addPathPatterns("/**");
 //    }
 
-    @Autowired
-    private LoginUserInterceptor loginUserInterceptor;
-
     @Autowired
     private PreAuthorizeInterceptor preAuthorizeInterceptor;
 
@@ -40,11 +35,6 @@ public class CorsConfig implements WebMvcConfigurer {
                 .excludePathPatterns("/swagger-ui/**")
         ;
 
-        registry.addInterceptor(loginUserInterceptor)
-            .addPathPatterns("/api/**")
-            .excludePathPatterns("/swagger-ui/**", "/api/public/**")
-        ;
-
     }
 
     @Override

+ 0 - 205
src/main/java/com/backendsys/config/Security/__SecurityConfig.java

@@ -1,205 +0,0 @@
-//package com.backendsys.configs;
-//
-//import com.nimbusds.jose.jwk.JWKSet;
-//import com.nimbusds.jose.jwk.RSAKey;
-//import com.nimbusds.jose.jwk.source.ImmutableJWKSet;
-//import com.nimbusds.jose.jwk.source.JWKSource;
-//import com.nimbusds.jose.proc.SecurityContext;
-//import org.springframework.context.aspect.Bean;
-//import org.springframework.context.aspect.Configuration;
-//import org.springframework.core.Ordered;
-//import org.springframework.core.aspect.Order;
-//import org.springframework.jdbc.core.JdbcTemplate;
-//import org.springframework.security.config.Customizer;
-//import org.springframework.security.config.aspect.web.builders.HttpSecurity;
-//import org.springframework.security.config.aspect.web.configuration.EnableWebSecurity;
-//import org.springframework.security.core.userdetails.User;
-//import org.springframework.security.core.userdetails.UserDetails;
-//import org.springframework.security.core.userdetails.UserDetailsService;
-//import org.springframework.security.crypto.factory.PasswordEncoderFactories;
-//import org.springframework.security.crypto.password.PasswordEncoder;
-//import org.springframework.security.oauth2.core.AuthorizationGrantType;
-//import org.springframework.security.oauth2.core.ClientAuthenticationMethod;
-//import org.springframework.security.oauth2.core.oidc.OidcScopes;
-//import org.springframework.security.oauth2.jwt.JwtDecoder;
-//import org.springframework.security.oauth2.server.authorization.client.InMemoryRegisteredClientRepository;
-//import org.springframework.security.oauth2.server.authorization.client.RegisteredClient;
-//import org.springframework.security.oauth2.server.authorization.client.RegisteredClientRepository;
-//import org.springframework.security.oauth2.server.authorization.config.aspect.web.configuration.OAuth2AuthorizationServerConfiguration;
-//import org.springframework.security.oauth2.server.authorization.config.aspect.web.configurers.OAuth2AuthorizationServerConfigurer;
-//import org.springframework.security.oauth2.server.authorization.settings.AuthorizationServerSettings;
-//import org.springframework.security.oauth2.server.authorization.settings.ClientSettings;
-//import org.springframework.security.provisioning.InMemoryUserDetailsManager;
-//import org.springframework.security.web.SecurityFilterChain;
-//import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint;
-//
-//import java.security.KeyPairDTO;
-//import java.security.KeyPairGenerator;
-//import java.security.interfaces.RSAPrivateKey;
-//import java.security.interfaces.RSAPublicKey;
-//import java.util.UUID;
-//
-//@Configuration
-//@EnableWebSecurity
-//public class SecurityConfig {
-//
-//    // https://docs.spring.io/spring-authorization-server/docs/current/reference/html/getting-started.html
-//    // https://github.com/spring-projects/spring-authorization-server/blob/main/samples/default-authorizationserver/src/main/java/sample/config/AuthorizationServerConfig.java
-//
-//    // 协议端点的Spring安全过滤器链
-//    @Bean
-//    @Order(Ordered.HIGHEST_PRECEDENCE)
-//    public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
-//
-//        OAuth2AuthorizationServerConfiguration.applyDefaultSecurity(http);
-//        http.getConfigurer(OAuth2AuthorizationServerConfigurer.class).oidc(Customizer.withDefaults());
-//        // Enable OpenID Connect 1.0
-//        http
-//            // Redirect to the login page when not authenticated from the
-//            // authorization endpoint
-//            .exceptionHandling((exceptions) -> exceptions
-//                .authenticationEntryPoint(
-//                    new LoginUrlAuthenticationEntryPoint("/login"))
-//            )
-//            // Accept access tokens for User Info and/or Client Registration
-//            .oauth2ResourceServer(OAuth2ResourceServerConfigurer::jwt);
-//
-//        return http.build();
-//    }
-//
-//
-//    // 用于身份验证的Spring Security过滤器链。
-//    @Bean
-//    @Order(Ordered.HIGHEST_PRECEDENCE)
-//    public SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http) throws Exception {
-//        http.authorizeRequests(authorizeRequests ->
-//            // 所有请求均放过, spring security 就没有什么用了
-//            // anyRequest() 限定任意的请求
-//            // permitAll() 无条件允许访问
-//            authorizeRequests.anyRequest().permitAll()
-//        );
-//
-//        //http
-//        //    // .csrf().disable()
-//        //    .authorizeHttpRequests(
-//        //        (requests) -> requests
-//        //            // .requestMatchers(new AntPathRequestMatcher("/actuator/**"), ..)
-//        //            .requestMatchers("/", "/api/**").permitAll()
-//        //            .anyRequest().authenticated()
-//        //).formLogin((form) -> form
-//        //        .loginPage("/login")
-//        //        .permitAll()
-//        //).logout((logout) -> logout.permitAll());
-//        return http.build();
-//    }
-//
-//
-//    // UserDetailsService的实例,用于检索要进行身份验证的用户。
-//    @Bean
-//    public UserDetailsService userDetailsService() {
-//        // 密码加密
-//        PasswordEncoder encoder = PasswordEncoderFactories.createDelegatingPasswordEncoder();
-//        String pwd = encoder.encode("123456");
-//        // 用户验证
-//        UserDetails admin = User.withUsername("admin")
-//                .password(pwd)
-//                .roles("ADMIN")
-//                .build();
-//        return new InMemoryUserDetailsManager(admin);
-//    }
-//
-//
-//
-//
-//    // RegisteredClientRepository 的实例,用于管理客户端。
-//    @Bean
-//    public RegisteredClientRepository registeredClientRepository(JdbcTemplate jdbcTemplate) {
-//        RegisteredClient registeredClient = RegisteredClient.withId(UUID.randomUUID().toString())
-//                .clientId("messaging-client")
-//                .clientSecret("{noop}secret")
-//                .clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC)
-//                .authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
-//                .authorizationGrantType(AuthorizationGrantType.REFRESH_TOKEN)
-//                .authorizationGrantType(AuthorizationGrantType.CLIENT_CREDENTIALS)
-//                .redirectUri("http://127.0.0.1:8080/login/oauth2/code/messaging-client-oidc")
-//                .redirectUri("http://127.0.0.1:8080/authorized")
-//                .scope(OidcScopes.OPENID)
-//                .scope(OidcScopes.PROFILE)
-//                .scope("message.read")
-//                .scope("message.write")
-//                .clientSettings(ClientSettings.builder().requireAuthorizationConsent(true).build())
-//                .build();
-//
-//        // Save registered client in db as if in-memory
-//        // JdbcRegisteredClientRepository registeredClientRepository = new JdbcRegisteredClientRepository(jdbcTemplate);
-//        // registeredClientRepository.save(registeredClient);
-//
-//        return new InMemoryRegisteredClientRepository(registeredClient);
-//    }
-//
-//    /*
-//    @Bean
-//	public OAuth2AuthorizationService authorizationService(JdbcTemplate jdbcTemplate, RegisteredClientRepository registeredClientRepository) {
-//		return new JdbcOAuth2AuthorizationService(jdbcTemplate, registeredClientRepository);
-//	}
-//	@Bean
-//	public OAuth2AuthorizationConsentService authorizationConsentService(JdbcTemplate jdbcTemplate, RegisteredClientRepository registeredClientRepository) {
-//		return new JdbcOAuth2AuthorizationConsentService(jdbcTemplate, registeredClientRepository);
-//	}
-//     */
-//
-//    // 用于签署访问令牌的com. nimbuss .jo .jwk.source. jwksource实例。
-//    @Bean
-//    public JWKSource<SecurityContext> jwkSource() {
-//        KeyPairDTO keyPair = generateRsaKey();
-//        RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
-//        RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
-//        RSAKey rsaKey = new RSAKey.Builder(publicKey)
-//                .privateKey(privateKey)
-//                .keyID(UUID.randomUUID().toString())
-//                .build();
-//        JWKSet jwkSet = new JWKSet(rsaKey);
-//        return new ImmutableJWKSet<>(jwkSet);
-//    }
-//
-//    // 一个java.security.KeyPair的实例,它带有在启动时生成的密钥,用于创建上面的JWKSource
-//    private static KeyPairDTO generateRsaKey() {
-//        KeyPairDTO keyPair;
-//        try {
-//            KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
-//            keyPairGenerator.initialize(2048);
-//            keyPair = keyPairGenerator.generateKeyPair();
-//        }
-//        catch (Exception ex) {
-//            throw new IllegalStateException(ex);
-//        }
-//        return keyPair;
-//    }
-//
-//    // JwtDecoder的实例,用于解码已签名的访问令牌。
-//    @Bean
-//    public JwtDecoder jwtDecoder(JWKSource<SecurityContext> jwkSource) {
-//        return OAuth2AuthorizationServerConfiguration.jwtDecoder(jwkSource);
-//    }
-//
-//    // 配置Spring授权服务器的AuthorizationServerSettings实例。
-//    @Bean
-//    public AuthorizationServerSettings authorizationServerSettings() {
-//        return AuthorizationServerSettings.builder().build();
-//    }
-//
-//    /*
-//    @Bean
-//	public EmbeddedDatabase embeddedDatabase() {
-//		// @formatter:off
-//		return new EmbeddedDatabaseBuilder()
-//				.generateUniqueName(true)
-//				.setType(EmbeddedDatabaseType.H2)
-//				.setScriptEncoding("UTF-8")
-//				.addScript("org/springframework/security/oauth2/server/authorization/oauth2-authorization-schema.sql")
-//				.addScript("org/springframework/security/oauth2/server/authorization/oauth2-authorization-consent-schema.sql")
-//				.addScript("org/springframework/security/oauth2/server/authorization/client/oauth2-registered-client-schema.sql")
-//				.build();
-//     */
-//
-//}

+ 22 - 0
src/main/java/com/backendsys/config/Security/entity/SecurityUserInfo.java

@@ -0,0 +1,22 @@
+package com.backendsys.config.Security.entity;
+
+import lombok.Data;
+
+import java.util.List;
+import java.util.Map;
+
+@Data
+public class SecurityUserInfo {
+    private Long id;
+    private Long user_id;
+    private String username;
+    private String last_login_ip;
+    private String last_login_uuid;
+    private String last_login_time;
+    private Integer is_super;
+    private String token_expiration;
+    private String create_time;
+    private String target;
+    private List<Map<String, Object>> roles;
+    private List<String> modules;
+}

+ 27 - 22
src/main/java/com/backendsys/config/Security/filter/JwtAuthenticationFilter.java

@@ -5,6 +5,7 @@ import com.fasterxml.jackson.databind.ObjectMapper;
 import com.backendsys.utils.response.Result;
 import com.backendsys.utils.response.ResultEnum;
 import com.backendsys.config.Security.utils.JwtUtil;
+import io.jsonwebtoken.Claims;
 import io.jsonwebtoken.ExpiredJwtException;
 import io.jsonwebtoken.MalformedJwtException;
 import io.jsonwebtoken.security.SignatureException;
@@ -57,6 +58,9 @@ public class JwtAuthenticationFilter extends OncePerRequestFilter {
     @Value("#{'${whitelist.jwt}'.split(',')}")
     private final String[] JWT_WHITELIST;
 
+    @Value("${REDIS_LOGIN_KEY}")
+    private String REDIS_LOGIN_KEY;
+
     /**
      * 校验路径是否是要忽略鉴权路径
      * @param url
@@ -93,7 +97,6 @@ public class JwtAuthenticationFilter extends OncePerRequestFilter {
 
         // [Header][拦截] 从请求头中获取认证信息
         final String authHeader = request.getHeader("Authorization");
-
         if(authHeader == null || !authHeader.startsWith("Bearer ")) {
             // [TOKEN_EMPTY_ERROR: 请先登录以获取有效的Token]
             handleError(response, ResultEnum.TOKEN_EMPTY_ERROR);
@@ -109,27 +112,21 @@ public class JwtAuthenticationFilter extends OncePerRequestFilter {
                 // 根据jwt解析出来的 username (id),获取数据库中的用户信息,封装UserDetails对象
                 UserDetails userDetails = userDetailsService.loadUserByUsername(username);
 
-                // // 如何区分 [系统用户] 和 [会员用户] 不同的 Token?
-                // //System.out.println("userDetails:");
-                // //System.out.println(userDetails);
-                // // 输出:
-                // // Username=14, Password=[PROTECTED], Enabled=true, AccountNonExpired=true, credentialsNonExpired=true, AccountNonLocked=true, Granted Authorities=[admin, normal]
-                // // 其中 Username 是 member_id
-
-                String userId = userDetails.getUsername();
-                // System.out.println(userId);
-                String tokenRedisKey = "token:id:" + userId;
-
-                //// 区分 [系统用户] 和 [会员用户] 不同的 Token Redis Key 命名
-                //Claims claims = jwtUtil.extractAllClaims(jwt);
-                //String target = (String) claims.get("target");
-                //String redisTag = "";
-                //if ("System".equals(target)) redisTag = "token:suid:";
-                //if ("Member".equals(target)) redisTag = "token:muid:";
-                //String tokenRedisKey = redisTag + userId;
+                // System.out.println(userDetails);
+                // Username=14, Password=[PROTECTED], Enabled=true, AccountNonExpired=true, credentialsNonExpired=true, AccountNonLocked=true, Granted Authorities=[admin, normal]
+
+                // // 区分 [系统用户] 和 [会员用户] 不同的 Token Redis Key 命名
+                // Claims claims = jwtUtil.extractAllClaims(jwt);
+                // System.out.println(claims);
+                // String target = (String) claims.get("target");
+                // String redisTag = "";
+                // if ("System".equals(target)) redisTag = "token:suid:";
+                // if ("Member".equals(target)) redisTag = "token:muid:";
+                // String tokenRedisKey = redisTag + userId;
 
                 // 判断 Redis Token 是否存在
-                Boolean isTokenValid = (stringRedisTemplate.opsForValue().get(tokenRedisKey) != null);
+                String redisKey = REDIS_LOGIN_KEY + userDetails.getUsername();
+                Boolean isTokenValid = (stringRedisTemplate.opsForValue().get(redisKey) != null);
                 if (!isTokenValid) {
                     // [TOKEN_INVALID: Token已失效,请重新登录]
                     handleError(response, ResultEnum.TOKEN_INVALID);
@@ -137,9 +134,17 @@ public class JwtAuthenticationFilter extends OncePerRequestFilter {
                 }
 
                 if (jwtUtil.isTokenValid(jwt, userDetails) && isTokenValid) {
-                    // TODO 如果令牌有效,封装一个UsernamePasswordAuthenticationToken对象
+
+                    // 如果令牌有效,封装一个 UsernamePasswordAuthenticationToken 对象
                     UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
-                    authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
+
+                    // WebAuthenticationDetailsSource: { RemoteIpAddress, SessionId }
+                    // authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
+
+                    // 将 Token 存入 SecurityContextHolder.getContext().getAuthentication() 的 getDetail 中
+                    String token = authHeader.replace("Bearer ", "");
+                    authentication.setDetails(token);
+
                     // 更新安全上下文的持有用户
                     SecurityContextHolder.getContext().setAuthentication(authentication);
                 }

+ 0 - 112
src/main/java/com/backendsys/config/Security/service/__PermissionService.java

@@ -1,112 +0,0 @@
-//package com.backendsys.config.Security.service;
-//
-//
-//import com.backendsys.exception.CustomException;
-//import com.backendsys.utils.response.ResultEnum;
-//import io.jsonwebtoken.Claims;
-//import org.springframework.beans.factory.annotation.Autowired;
-//import org.springframework.stereotype.Service;
-//import org.springframework.util.StringUtils;
-//
-//import java.util.HashSet;
-//import java.util.List;
-//import java.util.Set;
-//
-///**
-// * 自定义权限 @PreAuthorize("@ss.hasPermi('3.2.3') && @ss.isSuper()")
-// */
-//@Service("ss")
-//public class __PermissionService {
-//    //private static final String ALL_PERMISSION = "*:*:*";
-//    @Autowired
-//    private TokenService tokenService;
-//    /**
-//     * 验证用户是否具备权限
-//     * @param permission 权限字符串
-//     * @return boolean
-//     */
-//    public boolean hasPermi(String permission) {
-//        // System.out.println(permission);
-//
-//        if (StringUtils.isEmpty(permission)) return false;
-//        // 获得当前用户的登录信息(包括权限)["xxx", "xxx"]
-//        Claims loginUserInfo = tokenService.getRedisTokenInfo();
-//
-//        // (/public/**) 接口 不要鉴权,否则会报错,会获取不到 loginUserInfo
-//        //  System.out.println("hasPermi - loginUserInfo:");
-//        //  System.out.println(loginUserInfo);
-//
-//        // 没有 modules 即不是系统用户,即没有访问后台的权限
-//        if (loginUserInfo != null) {
-//            Object modules = loginUserInfo.get("modules");
-//            if (modules != null) {
-//                List<String> modulesList = (List<String>) modules;
-//                Set<String> modulesSet = new HashSet<>();
-//                for (String module : modulesList) {
-//                    modulesSet.add(module);
-//                }
-//                return hasPermissions(modulesSet, permission);
-//            }
-//        }
-//        return false;
-//    }
-//    public boolean hasPermissions(Set<String> permissions, String permission) {
-//        return permissions.contains(StringUtils.trimAllWhitespace(permission));
-//    }
-//
-//    // 是否超级管理员
-//    public boolean isSuper() {
-//        Claims loginUserInfo = tokenService.getRedisTokenInfo();
-//        Boolean bool = (Integer) loginUserInfo.get("is_super") == 1;
-//        return bool;
-//    }
-//
-//    // 是否超级管理员 (首位)
-//    public boolean isFirstSuper() {
-//        Claims loginUserInfo = tokenService.getRedisTokenInfo();
-//        Boolean bool = (Integer) loginUserInfo.get("user_id") == 1;
-//        return bool;
-//    }
-//
-//    // 是否会员
-//    public boolean isMember() {
-//        Claims loginUserInfo = tokenService.getRedisTokenInfo();
-//        // System.out.println("(isMember) loginUserInfo:");
-//        // System.out.println(loginUserInfo);
-//        Boolean bool = "Member".equals(loginUserInfo.get("target"));
-//        return bool;
-//    }
-//
-//
-//    /**
-//     * 判断是否匹配当前 {用户ID} 与 {用户权限},不是则抛出错误
-//     * - 匹配,通过
-//     * - 不匹配,再次检查权限
-//     *    - 匹配,通过
-//     *    - 不匹配,抛出错误
-//     * permissionService.checkUserIdAndPermission(sysUserDTO.getUser_id(), "3.2.1");
-//     */
-//    public void checkUserIdAndPermission(long user_id, String permission) {
-//        Claims loginUserInfo = tokenService.getRedisTokenInfo();
-//        Integer current_user_id = (Integer) loginUserInfo.get("user_id");
-//        if (current_user_id != user_id) {
-//            if (!hasPermi(permission)) {
-//                throw new CustomException(ResultEnum.AUTH_ROLE_ERROR.getMessage(), ResultEnum.AUTH_ROLE_ERROR.getCode());
-//            }
-//        }
-//    }
-//
-//    /**
-//     * 判断是否 首位超级管理员 (id:1),不是则抛出错误
-//     */
-//    public void checkSuperAdminOfFirst(long user_id) {
-//        if (user_id == 1) {
-//            Claims loginUserInfo = tokenService.getRedisTokenInfo();
-//            Boolean bool = (Integer) loginUserInfo.get("user_id") == 1;
-//            if (!bool) {
-//                throw new CustomException(ResultEnum.AUTH_USER_ERROR.getMessage(), ResultEnum.AUTH_USER_ERROR.getCode());
-//            }
-//        }
-//    }
-//
-//}

+ 33 - 15
src/main/java/com/backendsys/config/Security/utils/JwtUtil.java

@@ -1,5 +1,9 @@
 package com.backendsys.config.Security.utils;
 
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.convert.Convert;
+import cn.hutool.json.JSONUtil;
+import com.backendsys.config.Security.entity.SecurityUserInfo;
 import io.jsonwebtoken.Claims;
 import io.jsonwebtoken.Jwts;
 import io.jsonwebtoken.SignatureAlgorithm;
@@ -43,37 +47,51 @@ public class JwtUtil {
      */
     // private static final long TOKEN_EXPIRED = 86400000;
 
+
+    /**
+     * 创建 Token (新)
+     * @param securityUserInfo
+     * @return
+     */
+    public String createJwtToken(SecurityUserInfo securityUserInfo) {
+        return Jwts.builder()
+                // subject 代表这个JWT的主体,即它的所有人
+                .subject(securityUserInfo.getLast_login_uuid())
+                .claim("userInfo", securityUserInfo)
+                .claim("target", "System")
+                .signWith(getSignInKey())
+                .expiration(Convert.toDate(securityUserInfo.getToken_expiration()))
+                .compact();
+    }
+
+
     /**
-     * 创建Token (sysUser 系统用户 实体类)
+     * 创建Token (即将弃用)
      */
     public String createSystemToken(Map<String, Object> sysUser) {
+
+        System.out.println("createSystemToken:");
+        System.out.println(sysUser);
+
         Date expiration = (Date) sysUser.get("token_expiration");   // 过期时间由 isRemember 决定
         return Jwts.builder()
-                // 代表这个JWT的主体,即它的所有人 / 主题
-//                .setSubject(String.valueOf(sysUser.get("id")))
-//                .setSubject(String.valueOf(sysUser.get("last_login_uuid")))
+                // subject 代表这个JWT的主体,即它的所有人
                 .subject(String.valueOf(sysUser.get("last_login_uuid")))
-                // .setId("System")
-                // .setAudience("aaaaaaa")
-//                .setSubject("JWT AUTH")
-                // 代表这个JWT的签发主体
-                // .setIssuer("System")
-                // 是一个时间戳,代表这个JWT的签发时间;
-                //.setIssuedAt(new Date())
-                // 代表这个JWT的接收对象
-                // .setAudience(clientId)
                 .claim("user_id", sysUser.get("id"))
                 .claim("username", sysUser.get("username"))
                 .claim("is_super", sysUser.get("is_super"))
                 .claim("modules", sysUser.get("modules"))
                 .claim("target", "System")
-//                .signWith(SignatureAlgorithm.HS256, SECRET_KEY)
+
+                .claim("UserInfo", JSONUtil.toJsonStr(sysUser))
+
                 .signWith(getSignInKey())
-//                .setExpiration(expiration)
                 .expiration(expiration)
                 .compact();
     }
 
+
+
     /**
      * 创建Token (sysMember 会员用户 实体类)
      */

+ 21 - 42
src/main/java/com/backendsys/config/Security/service/PermissionService.java → src/main/java/com/backendsys/config/Security/utils/PermissionUtil.java

@@ -1,11 +1,8 @@
-package com.backendsys.config.Security.service;
-
+package com.backendsys.config.Security.utils;
 
+import com.backendsys.config.Security.entity.SecurityUserInfo;
 import com.backendsys.exception.CustomException;
 import com.backendsys.utils.response.ResultEnum;
-import io.jsonwebtoken.Claims;
-import jakarta.servlet.http.HttpServletRequest;
-
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.util.CollectionUtils;
@@ -17,10 +14,10 @@ import java.util.*;
  * 自定义权限 @PreAuthorize("@ss.hasPermi('3.2.3') && @ss.isSuper()")
  */
 @Service("ss")
-public class PermissionService {
+public class PermissionUtil {
     //private static final String ALL_PERMISSION = "*:*:*";
     @Autowired
-    private TokenService tokenService;
+    private TokenUtil tokenUtil;
     /**
      * 验证用户是否具备权限
      * @param permissions 权限字符串
@@ -30,36 +27,25 @@ public class PermissionService {
     public boolean hasPermi(Collection<String> permissions) {
 
         if (CollectionUtils.isEmpty(permissions)) return false;
-//        if (StringUtils.isEmpty(permission)) return false;
-
-        // 获得当前用户的登录信息(包括权限)["xxx", "xxx"]
-        Claims loginUserInfo = tokenService.getRedisTokenInfo();
 
+        SecurityUserInfo securityUserInfo = SecurityUtil.getUserInfo();
         // 如果是超级管理员,则直接通过
-        Boolean userIsSuper = (Integer) loginUserInfo.get("is_super") == 1;
-        if (userIsSuper) return true;
-
-        // (/public/**) 接口 不要鉴权,否则会报错,会获取不到 loginUserInfo
-        //  System.out.println("hasPermi - loginUserInfo:");
-        //  System.out.println(loginUserInfo);
+        if (securityUserInfo.getIs_super() == 1) return true;
 
         // 没有 modules 即不是系统用户,即没有访问后台的权限
-        if (loginUserInfo != null) {
-            Object modules = loginUserInfo.get("modules");
-            if (modules != null) {
-                List<String> modulesList = (List<String>) modules;
+        if (securityUserInfo != null) {
+            List<String> modules = securityUserInfo.getModules();
+            if (modules != null && !modules.isEmpty()) {
                 Set<String> modulesSet = new HashSet<>();
-                for (String module : modulesList) {
+                for (String module : modules) {
                     modulesSet.add(module);
                 }
-
                 for (String permission : permissions) {
                     if (hasPermissions(modulesSet, permission)) {
                         return true;
                     }
                 }
-                //                return hasPermissions(modulesSet, permission);
-
+                // return hasPermissions(modulesSet, permission);
             }
         }
         return false;
@@ -70,25 +56,20 @@ public class PermissionService {
 
     // 是否超级管理员
     public boolean isSuper() {
-        Claims loginUserInfo = tokenService.getRedisTokenInfo();
-        Boolean bool = (Integer) loginUserInfo.get("is_super") == 1;
-        return bool;
+        SecurityUserInfo securityUserInfo = SecurityUtil.getUserInfo();
+        return securityUserInfo.getIs_super() == 1;
     }
 
     // 是否超级管理员 (首位)
     public boolean isFirstSuper() {
-        Claims loginUserInfo = tokenService.getRedisTokenInfo();
-        Boolean bool = (Integer) loginUserInfo.get("user_id") == 1;
-        return bool;
+        SecurityUserInfo securityUserInfo = SecurityUtil.getUserInfo();
+        return securityUserInfo.getUser_id() == 1;
     }
 
     // 是否会员
     public boolean isMember() {
-        Claims loginUserInfo = tokenService.getRedisTokenInfo();
-        // System.out.println("(isMember) loginUserInfo:");
-        // System.out.println(loginUserInfo);
-        Boolean bool = "Member".equals(loginUserInfo.get("target"));
-        return bool;
+        SecurityUserInfo securityUserInfo = SecurityUtil.getUserInfo();
+        return "Member".equals(securityUserInfo.getTarget());
     }
 
 
@@ -101,9 +82,8 @@ public class PermissionService {
      * permissionService.checkUserIdAndPermission(sysUserDTO.getUser_id(), "3.2.1");
      */
     public void checkUserIdAndPermission(long user_id, Collection<String> permission) {
-        Claims loginUserInfo = tokenService.getRedisTokenInfo();
-        Integer current_user_id = (Integer) loginUserInfo.get("user_id");
-        if (current_user_id != user_id) {
+        SecurityUserInfo securityUserInfo = SecurityUtil.getUserInfo();
+        if (securityUserInfo.getUser_id() != user_id) {
             if (!hasPermi(permission)) {
                 throw new CustomException(ResultEnum.AUTH_ROLE_ERROR.getMessage(), ResultEnum.AUTH_ROLE_ERROR.getCode());
             }
@@ -115,9 +95,8 @@ public class PermissionService {
      */
     public void checkSuperAdminOfFirst(long user_id) {
         if (user_id == 1) {
-            Claims loginUserInfo = tokenService.getRedisTokenInfo();
-            Boolean bool = (Integer) loginUserInfo.get("user_id") == 1;
-            if (!bool) {
+            SecurityUserInfo securityUserInfo = SecurityUtil.getUserInfo();
+            if (securityUserInfo.getUser_id() != 1) {
                 throw new CustomException(ResultEnum.AUTH_USER_ERROR.getMessage(), ResultEnum.AUTH_USER_ERROR.getCode());
             }
         }

+ 68 - 0
src/main/java/com/backendsys/config/Security/utils/SecurityUtil.java

@@ -0,0 +1,68 @@
+package com.backendsys.config.Security.utils;
+
+import cn.hutool.core.convert.Convert;
+import cn.hutool.json.JSONObject;
+import cn.hutool.json.JSONUtil;
+import com.backendsys.config.Security.entity.SecurityUserInfo;
+import io.jsonwebtoken.Claims;
+import io.jsonwebtoken.Jwts;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.support.ClassPathXmlApplicationContext;
+import org.springframework.data.redis.core.StringRedisTemplate;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.context.SecurityContextHolder;
+
+import javax.crypto.SecretKey;
+import javax.crypto.spec.SecretKeySpec;
+import java.nio.charset.StandardCharsets;
+import java.util.Base64;
+import java.util.Map;
+
+public class SecurityUtil {
+
+    private static final String SECRET_KEY = "452948404D635166546A576E5A7134743777217A25432A462D4A614E64526755";
+    private static SecretKey getSignInKey() {
+        byte[] bytes = Base64.getDecoder().decode(SECRET_KEY.getBytes(StandardCharsets.UTF_8));
+        return new SecretKeySpec(bytes, "HmacSHA256");
+    }
+
+
+    /**
+     * 获得当前登录用户ID
+     */
+    public static Long getUserId() {
+        SecurityUserInfo userInfo = getUserInfo();
+        return userInfo.getUser_id();
+    }
+
+    /**
+     * 获得当前登录 Token
+     */
+    public static String getToken() {
+        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
+        return Convert.toStr(authentication.getDetails());
+    }
+
+    /**
+     * 获得当前登录用户基础信息
+     * 此处的用户信息是根据 Token 解析出来的,因此无法实时更新,仅能用于获取一些基本信息 (以下是完整信息,实际信息见 SecurityUserInfo)
+     * {"id":1,"user_id":1,"username":"admin","phone":"13670511519","phone_area_code":"86","nickname":"超人","email":"admin@qq.com","gender":1,"avatar":"/uploads/20240430/20240430143807.png","last_login_ip":"0:0:0:0:0:0:0:1","last_login_uuid":"5b34e58d-c884-4b43-9ce1-1c85b1136dcb","last_login_time":"2024-10-25 17:26:55","is_super":1,"point_balance":9870,"status":1,"audit_status":2,"audit_note":"同意通过备注","create_time":1689734700000,"update_time":1729848415000,"del_flag":-1,"roles":[{"id":1,"role_name":"管理员"}],"token_expiration":1729934998492}
+     */
+    public static SecurityUserInfo getUserInfo(){
+        Claims tokenInfo = Jwts.parser().verifyWith(getSignInKey()).build().parseSignedClaims(getToken()).getPayload();
+        JSONObject userInfo = JSONUtil.parseObj(tokenInfo.get("userInfo"));
+        String target = Convert.toStr(tokenInfo.get("target"));
+        SecurityUserInfo securityUserInfo = JSONUtil.toBean(userInfo, SecurityUserInfo.class);
+        securityUserInfo.setTarget(target);
+        return securityUserInfo;
+    }
+
+
+
+    public static Object getPrincipal() {
+        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
+        Object principal = authentication.getPrincipal();
+        return principal;
+    }
+
+}

+ 16 - 4
src/main/java/com/backendsys/config/Security/service/TokenService.java → src/main/java/com/backendsys/config/Security/utils/TokenUtil.java

@@ -1,8 +1,10 @@
-package com.backendsys.config.Security.service;
+package com.backendsys.config.Security.utils;
 
+import cn.hutool.core.convert.Convert;
 import com.backendsys.config.Security.utils.JwtUtil;
 import io.jsonwebtoken.Claims;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
 import org.springframework.data.redis.core.StringRedisTemplate;
 
 import jakarta.servlet.http.HttpServletRequest;
@@ -12,17 +14,27 @@ import org.springframework.security.core.context.SecurityContextHolder;
 import org.springframework.security.core.userdetails.UserDetails;
 
 @Service
-public class TokenService {
+public class TokenUtil {
     @Autowired
     private JwtUtil jwtUtil;
     @Autowired
     private StringRedisTemplate stringRedisTemplate;
+
+
+    @Value("${REDIS_LOGIN_KEY}")
+    private String REDIS_LOGIN_KEY;
+
+    public Long getUserId() {
+        Claims tokenInfo = getRedisTokenInfo();
+        return Convert.toLong(tokenInfo.get("user_id"));
+    }
+
     /**
      * 获得当前系统登录用户在 Redis 中的信息 (如果想在 token 加字段,要在  JwtUtil.createSystemToken 中增加)
      * @return
      */
     public Claims getRedisTokenInfo() {
-        String token = stringRedisTemplate.opsForValue().get("token:id:" + getLoginUUID());
+        String token = stringRedisTemplate.opsForValue().get(REDIS_LOGIN_KEY + getLoginUUID());
         if (token != null && !token.isEmpty()) {
             Claims tokenInfo = jwtUtil.extractAllClaims(token);
             return tokenInfo;
@@ -34,7 +46,7 @@ public class TokenService {
      * 删除 Redis 中的 Token 信息 (退出登录)
      */
     public void deleteRedisToken() {
-        stringRedisTemplate.delete("token:id:" + getLoginUUID());
+        stringRedisTemplate.delete(REDIS_LOGIN_KEY + getLoginUUID());
     }
 
     /**

+ 0 - 1
src/main/java/com/backendsys/config/WebSocket/WebSocketConfig.java

@@ -1,7 +1,6 @@
 package com.backendsys.config.WebSocket;
 
 import cn.hutool.core.util.StrUtil;
-import com.backendsys.config.Security.service.TokenService;
 import com.backendsys.config.Security.utils.JwtUtil;
 
 import io.jsonwebtoken.Claims;

+ 4 - 4
src/main/java/com/backendsys/controller/Systems/SysAuthController.java

@@ -1,8 +1,8 @@
 package com.backendsys.controller.Systems;
 
 import com.backendsys.aspect.RateLimiting;
-import com.backendsys.config.Redis.RedisCache;
-import com.backendsys.config.Security.service.TokenService;
+import com.backendsys.config.Redis.utils.RedisUtil;
+import com.backendsys.config.Security.utils.TokenUtil;
 import com.backendsys.entity.System.SysUserDTO;
 import com.backendsys.mapper.System.SysUserMapper;
 import com.backendsys.utils.response.Result;
@@ -26,10 +26,10 @@ public class SysAuthController {
     private StringRedisTemplate stringRedisTemplate;
 
     @Autowired
-    private RedisCache redisCache;
+    private RedisUtil redisUtil;
 
     @Autowired
-    private TokenService tokenService;
+    private TokenUtil tokenUtil;
 
     @Autowired
     private SysUserMapper sysUserMapper;

+ 7 - 7
src/main/java/com/backendsys/controller/Systems/SysUserController.java

@@ -2,8 +2,8 @@ package com.backendsys.controller.Systems;
 
 import com.backendsys.aspect.HttpRequestAspect;
 import com.backendsys.aspect.QueryNullCheck;
-import com.backendsys.config.Security.service.PermissionService;
-import com.backendsys.config.Security.service.TokenService;
+import com.backendsys.config.Security.utils.PermissionUtil;
+import com.backendsys.config.Security.utils.TokenUtil;
 import com.backendsys.entity.PageDTO;
 import com.backendsys.entity.System.SysUserDTO;
 import com.backendsys.utils.response.Result;
@@ -34,20 +34,20 @@ public class SysUserController {
     private HttpRequestAspect httpRequestAspect;
 
     @Autowired
-    private PermissionService permissionService;
+    private PermissionUtil permissionUtil;
 
     @Autowired
     private SysUserService sysUserService;
 
     @Autowired
-    private TokenService tokenService;
+    private TokenUtil tokenUtil;
 
 
     // 判断是否 超级管理员(首位)(id:1),仅首位可查看自己的信息
     private Boolean OnlySuperAdmin(SysUserDTO sysUserDTO) {
         Long user_id = sysUserDTO.getUser_id();
         if (user_id == 1) {
-            Claims loginUserInfo = tokenService.getRedisTokenInfo();
+            Claims loginUserInfo = tokenUtil.getRedisTokenInfo();
             Boolean bool = (Integer) loginUserInfo.get("user_id") == 1;
             return bool;
         }
@@ -82,9 +82,9 @@ public class SysUserController {
         // 1.如果 user_id 为空,则查看自己
         if (sysUserDTO.getUser_id() == null) sysUserDTO.setUser_id(user_id);
         // 2.判断是否匹配当前 {用户ID} 与 {用户权限},不是则抛出错误
-        permissionService.checkUserIdAndPermission(sysUserDTO.getUser_id(), Arrays.asList("3.2.1"));
+        permissionUtil.checkUserIdAndPermission(sysUserDTO.getUser_id(), Arrays.asList("3.2.1"));
         // 3.判断是否 首位超级管理员 (id:1),不是则抛出错误
-        permissionService.checkSuperAdminOfFirst(sysUserDTO.getUser_id());
+        permissionUtil.checkSuperAdminOfFirst(sysUserDTO.getUser_id());
 
         return Result.success(sysUserService.queryUserById(sysUserDTO.getUser_id()));
     }

+ 3 - 3
src/main/java/com/backendsys/controller/Systems/SysUserPointController.java

@@ -1,7 +1,7 @@
 package com.backendsys.controller.Systems;
 
 import com.backendsys.aspect.HttpRequestAspect;
-import com.backendsys.config.Security.service.PermissionService;
+import com.backendsys.config.Security.utils.PermissionUtil;
 import com.backendsys.entity.PageDTO;
 import com.backendsys.entity.System.SysUserPointsDTO;
 import com.backendsys.enums.UserPointActivityType;
@@ -30,7 +30,7 @@ public class SysUserPointController {
     private HttpRequestAspect httpRequestAspect;
 
     @Autowired
-    private PermissionService permissionService;
+    private PermissionUtil permissionUtil;
 
     @Autowired
     private SysUserService sysUserService;
@@ -53,7 +53,7 @@ public class SysUserPointController {
             sysUserPointsDTO.setTarget_user_id(user_id);
         }
         // 检查是否为超级管理员
-        boolean isSuper = permissionService.isSuper();
+        boolean isSuper = permissionUtil.isSuper();
         // 如果非超级管理员且目标用户ID与当前用户ID不匹配,则抛出权限异常
         if (!isSuper && !sysUserPointsDTO.getTarget_user_id().equals(user_id)) {
             throw new CustomException("当前用户没有权限查看或操作其他用户积分");

+ 3 - 3
src/main/java/com/backendsys/controller/TestAuthController.java

@@ -1,6 +1,6 @@
 package com.backendsys.controller;
 
-import com.backendsys.config.Security.service.TokenService;
+import com.backendsys.config.Security.utils.TokenUtil;
 import io.jsonwebtoken.Claims;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.GetMapping;
@@ -11,11 +11,11 @@ import org.springframework.web.bind.annotation.RestController;
 @RequestMapping("/api/testAuth")
 public class TestAuthController {
     @Autowired
-    private TokenService tokenService;
+    private TokenUtil tokenUtil;
 
     @GetMapping("testGetLoginUser")
     public Claims testGetSystemUser() {
         System.out.println("testGetSystemUser:");
-        return tokenService.getRedisTokenInfo();
+        return tokenUtil.getRedisTokenInfo();
     }
 }

+ 0 - 11
src/main/java/com/backendsys/modules/system/annotation/LoginUserId.java

@@ -1,11 +0,0 @@
-package com.backendsys.modules.system.annotation;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-@Target(ElementType.PARAMETER)
-@Retention(RetentionPolicy.RUNTIME)
-public @interface LoginUserId {
-}

+ 13 - 4
src/main/java/com/backendsys/modules/system/controller/SysUserV2Controller.java

@@ -1,7 +1,8 @@
 package com.backendsys.modules.system.controller;
 
+import com.backendsys.config.Security.utils.SecurityUtil;
+import com.backendsys.config.Security.utils.TokenUtil;
 import com.backendsys.modules.common.utils.Result;
-import com.backendsys.modules.system.annotation.LoginUserId;
 import com.backendsys.modules.system.service.SysUserV2Service;
 import io.swagger.v3.oas.annotations.Operation;
 import io.swagger.v3.oas.annotations.Parameter;
@@ -19,9 +20,17 @@ public class SysUserV2Controller {
 
     @Operation(summary = "获得系统用户详情")
     @GetMapping("/api/v2/system/user/getUserDetail")
-    public Result getUserDetail(@Parameter(description = "用户ID") Long user_id, @LoginUserId Long login_user_id) {
-        System.out.println("user_id = " + user_id);
-        System.out.println("login_user_id = " + login_user_id);
+    public Result getUserDetail(@Parameter(description = "用户ID") Long user_id) {
+
+//        System.out.println(tokenUtil.getUserId());
+//        System.out.println(SecurityUtil.getPrincipal());
+//        System.out.println(SecurityUtil.getUserInfo());
+//        System.out.println(SecurityUtil.getToken());
+        System.out.println("UserId: " + SecurityUtil.getUserId());
+
+        // 判断是否具备权限,或者是超级管理员
+
+
         return Result.success().put("data", sysUserV2Service.selectUserInfo(user_id));
     }
 

+ 0 - 63
src/main/java/com/backendsys/modules/system/interceptor/LoginUserInterceptor.java

@@ -1,63 +0,0 @@
-package com.backendsys.modules.system.interceptor;
-
-import cn.hutool.core.convert.Convert;
-import com.backendsys.aspect.HttpRequestAspect;
-import com.backendsys.config.Security.service.TokenService;
-import com.backendsys.modules.system.annotation.LoginUserId;
-import io.jsonwebtoken.Claims;
-import jakarta.servlet.http.HttpServletRequest;
-import jakarta.servlet.http.HttpServletResponse;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Component;
-import org.springframework.web.method.HandlerMethod;
-import org.springframework.web.servlet.HandlerInterceptor;
-import java.lang.reflect.Parameter;
-
-@Component
-public class LoginUserInterceptor implements HandlerInterceptor {
-
-    @Autowired
-    private TokenService tokenService;
-
-    @Override
-    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
-        if (handler instanceof HandlerMethod) {
-            HandlerMethod handlerMethod = (HandlerMethod) handler;
-            Parameter[] parameters = handlerMethod.getMethod().getParameters();
-            for (Parameter parameter : parameters) {
-                if (parameter.isAnnotationPresent(LoginUserId.class)) {
-                    // 这里假设你有一个方法可以获取当前登录用户的ID
-                    Long userId = getCurrentUserLoginUserId(request);
-                    if (userId != null) {
-                        // 将登录用户的ID注入到参数中
-                        // 注意:这里只是一个示例,实际上你不能直接修改方法参数的值
-                        // 你需要通过其他方式来传递这个值,例如使用RequestAttribute
-                        request.setAttribute("login_user_id", userId);
-
-                        System.out.println("preHandle login_user_id: " + userId);
-
-//                        // 将登录用户的ID注入到方法参数中
-//                        handlerMethod.getMethod().invoke(handlerMethod.getBean(), userId);
-
-                    }
-                    break; // 假设只有一个参数需要被注解
-                }
-            }
-        }
-        return true;
-    }
-
-    private Long getCurrentUserLoginUserId(HttpServletRequest request) {
-        if (request != null) {
-            Claims tokenInfo = tokenService.getTokenInfo(request);
-            System.out.println("tokenInfo:");
-            System.out.println(tokenInfo);
-            if (tokenInfo != null) {
-                System.out.println("tokenInfo user_id: " + Convert.toLong(tokenInfo.get("user_id")));
-                return Convert.toLong(tokenInfo.get("user_id"));
-            }
-        }
-        return null;
-    }
-
-}

+ 4 - 4
src/main/java/com/backendsys/service/Ai/AiChatServiceImpl.java

@@ -6,7 +6,7 @@ import cn.hutool.json.JSONArray;
 import cn.hutool.json.JSONObject;
 import cn.hutool.json.JSONUtil;
 import com.backendsys.aspect.HttpRequestAspect;
-import com.backendsys.config.Security.service.TokenService;
+import com.backendsys.config.Security.utils.TokenUtil;
 import com.backendsys.entity.Ai.AiChatDTO;
 import com.backendsys.mapper.Ai.AiChatHistoryMapper;
 import com.backendsys.mapper.Ai.AiChatMapper;
@@ -48,7 +48,7 @@ public class AiChatServiceImpl implements AiChatService {
     private String REGION;
 
     @Autowired
-    private TokenService tokenService;
+    private TokenUtil tokenUtil;
 
     private final SimpMessagingTemplate messagingTemplate;
 
@@ -97,7 +97,7 @@ public class AiChatServiceImpl implements AiChatService {
          * 使用 Webstock 将 AI回复的内容 发送回给自己
          */
         // 获得我的用户名
-        Claims loginUserInfo = tokenService.getRedisTokenInfo();
+        Claims loginUserInfo = tokenUtil.getRedisTokenInfo();
         String receiver = (String) loginUserInfo.get("username");
 
         // [发送/接收] 内容
@@ -206,7 +206,7 @@ public class AiChatServiceImpl implements AiChatService {
     private AiChatDTO cheatAiChatDTO(AiChatDTO aiChatDTO, String content) {
 
         // 获得我的用户名
-        Claims loginUserInfo = tokenService.getRedisTokenInfo();
+        Claims loginUserInfo = tokenUtil.getRedisTokenInfo();
         String receiver = (String) loginUserInfo.get("username");
 
         // [查询] 自身 UserId (并加入)

+ 4 - 4
src/main/java/com/backendsys/service/Ai/Aizn/AiznModelServiceImpl.java

@@ -4,7 +4,7 @@ import cn.hutool.core.util.StrUtil;
 import cn.hutool.json.JSONObject;
 import cn.hutool.json.JSONUtil;
 import com.backendsys.aspect.HttpRequestAspect;
-import com.backendsys.config.Redis.RedisCache;
+import com.backendsys.config.Redis.utils.RedisUtil;
 import com.backendsys.entity.Ai.Aizn.AiznImageStyleDTO;
 import com.backendsys.entity.Ai.Aizn.AiznIntelligentClipTaskDTO;
 import com.backendsys.entity.Ai.Aizn.AiznImageTaskVO;
@@ -55,7 +55,7 @@ public class AiznModelServiceImpl implements AiznModelService {
     private SDKTencentCOSService sdkTencentCOSService;
 
     @Autowired
-    private RedisCache redisCache;
+    private RedisUtil redisUtil;
 
     /**
      * [紫鸟] 获取风格/场景配置数据 (https://open.ziniao.com/manage/apiTest/809)
@@ -71,7 +71,7 @@ public class AiznModelServiceImpl implements AiznModelService {
         object.set("type", type);                                       // 类型 1.AI绘图
 
         String redisKey = "getImageStyle-" + type;
-        String redisCacheObject = redisCache.getCacheObject(redisKey);
+        String redisCacheObject = redisUtil.getCacheObject(redisKey);
         if (StrUtil.isNotEmpty(redisCacheObject)) {
             // [缓存存在] 读取缓存
             Map<String, Object> result = new LinkedHashMap<>();
@@ -112,7 +112,7 @@ public class AiznModelServiceImpl implements AiznModelService {
                     ObjectMapper mapper = new ObjectMapper();
                     String respDataStr = mapper.writeValueAsString(respData);
                     System.out.println(respDataStr);
-                    redisCache.setCacheObject(redisKey, respDataStr, 30, TimeUnit.SECONDS);
+                    redisUtil.setCacheObject(redisKey, respDataStr, 30, TimeUnit.SECONDS);
                 } catch (Exception e) {
                     e.printStackTrace();
                 }

+ 3 - 3
src/main/java/com/backendsys/service/SDKService/SDKTencent/SDKTencentSMSServiceImpl.java

@@ -5,7 +5,7 @@ import cn.hutool.core.util.RandomUtil;
 import cn.hutool.json.JSONArray;
 import cn.hutool.json.JSONObject;
 import cn.hutool.json.JSONUtil;
-import com.backendsys.config.Redis.RedisCache;
+import com.backendsys.config.Redis.utils.RedisUtil;
 import com.backendsys.entity.System.SysSMSDTO;
 import com.backendsys.exception.CustomException;
 import com.backendsys.mapper.System.SysMobileSMSHistoryMapper;
@@ -46,7 +46,7 @@ public class SDKTencentSMSServiceImpl implements SDKTencentSMSService {
     private String templateIdOfCommon;
 
     @Autowired
-    private RedisCache redisCache;
+    private RedisUtil redisUtil;
 
     @Autowired
     private SysMobileSMSHistoryMapper sysMobileSMSHistoryMapper;
@@ -125,7 +125,7 @@ public class SDKTencentSMSServiceImpl implements SDKTencentSMSService {
             String[] templateParamSet = {String.valueOf(smsCode), String.valueOf(smsExpire)};
             req.setTemplateParamSet(templateParamSet);
             String redisKey = "sms-" + origin + "-" + phone;
-            redisCache.setCacheObject(redisKey, smsCode, smsExpire, TimeUnit.MINUTES);
+            redisUtil.setCacheObject(redisKey, smsCode, smsExpire, TimeUnit.MINUTES);
 
             /* 下发手机号码,采用 E.164 标准,+[国家或地区码][手机号]
              * 示例如:+8613711112222, 其中前面有一个+号 ,86为国家码,13711112222为手机号,最多不要超过200个手机号 */

+ 21 - 16
src/main/java/com/backendsys/service/System/SysAuthServiceImpl.java

@@ -1,8 +1,10 @@
 package com.backendsys.service.System;
 
+import cn.hutool.json.JSONUtil;
 import com.backendsys.config.Kaptcha.KaptchaUtil;
-import com.backendsys.config.Redis.RedisCache;
-import com.backendsys.config.Security.service.TokenService;
+import com.backendsys.config.Redis.utils.RedisUtil;
+import com.backendsys.config.Security.entity.SecurityUserInfo;
+import com.backendsys.config.Security.utils.TokenUtil;
 import com.backendsys.modules.system.dao.SysUserInfoDao;
 import com.backendsys.entity.System.SysUserDTO;
 import com.backendsys.exception.CustomException;
@@ -12,9 +14,7 @@ import com.backendsys.utils.UserUtils;
 import com.backendsys.utils.response.ResultEnum;
 import com.backendsys.mapper.System.SysUserMapper;
 import com.backendsys.config.Security.utils.JwtUtil;
-import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.google.code.kaptcha.Producer;
-import cn.hutool.core.date.DateUtil;
 import jakarta.servlet.ServletOutputStream;
 import jakarta.servlet.http.HttpServletRequest;
 import jakarta.servlet.http.HttpServletResponse;
@@ -53,10 +53,10 @@ public class SysAuthServiceImpl implements SysAuthService {
     RedissonClient redissonClient;
 
     @Autowired
-    private RedisCache redisCache;
+    private RedisUtil redisUtil;
 
     @Autowired
-    private TokenService tokenService;
+    private TokenUtil tokenUtil;
 
     @Autowired
     private StringRedisTemplate stringRedisTemplate;
@@ -183,10 +183,15 @@ public class SysAuthServiceImpl implements SysAuthService {
 
         // 生成 Token
         sysUserDetail.put("last_login_uuid", uuid);
-        String token = jwtUtil.createSystemToken(sysUserDetail);
+
+//        Map<String, Object> userInfo = new LinkedHashMap<>(sysUserDetail);
+//        userInfo.remove("modules");
+//        String token = jwtUtil.createSystemToken(userInfo);
+
+        SecurityUserInfo securityUserInfo = JSONUtil.toBean(JSONUtil.parseObj(sysUserDetail), SecurityUserInfo.class);
+        String token = jwtUtil.createJwtToken(securityUserInfo);
 
         // 存入 Redis:Token、Token过期时间
-        // String tokenRedisKey = "token:id:" + userId;
         String tokenRedisKey = "token:id:" + uuid;
         stringRedisTemplate.opsForValue().set(tokenRedisKey, token, tokenDuration, TimeUnit.MILLISECONDS);
 
@@ -272,7 +277,7 @@ public class SysAuthServiceImpl implements SysAuthService {
 
         // 判断手机验证码是否正确
         String redisKey = "sms-login-" + phone;
-        Integer smsCode = redisCache.getCacheObject(redisKey);
+        Integer smsCode = redisUtil.getCacheObject(redisKey);
         System.out.println("smsCode: " + smsCode);
 
         // 判断短信验证码是否错误
@@ -288,7 +293,7 @@ public class SysAuthServiceImpl implements SysAuthService {
             throw new CustomException("手机号码不存在", ResultEnum.INVALID_CREDENTIALS.getCode());
         } else {
             // 登录成功,销毁 smsCode
-            redisCache.deleteObject(redisKey);
+            redisUtil.deleteObject(redisKey);
 
             // 登录成功回调
             sysUserDTO.setUser_id((Long) sysUserSimple.get("id"));
@@ -326,7 +331,7 @@ public class SysAuthServiceImpl implements SysAuthService {
                 Integer phoneValidCode = sysUserDTO.getPhone_valid_code();
 
                 String redisKey = "sms-register-" + sysUserDTO.getPhone();
-                Integer smsCode = redisCache.getCacheObject(redisKey);
+                Integer smsCode = redisUtil.getCacheObject(redisKey);
                 // System.out.println("smsCode: " + smsCode);
 
 
@@ -350,7 +355,7 @@ public class SysAuthServiceImpl implements SysAuthService {
                 // .. 待做
 
                 // 注册成功,销毁 smsCode
-                redisCache.deleteObject(redisKey);
+                redisUtil.deleteObject(redisKey);
                 //
             }
 
@@ -397,7 +402,7 @@ public class SysAuthServiceImpl implements SysAuthService {
             Integer phoneValidCode = sysUserDTO.getPhone_valid_code();
 
             String redisKey = "sms-forgotPassword-" + sysUserDTO.getPhone();
-            Integer smsCode = redisCache.getCacheObject(redisKey);
+            Integer smsCode = redisUtil.getCacheObject(redisKey);
 //            System.out.println("smsCode: " + smsCode);
 
             if ("false".equals(SMS_DEBUG) && (smsCode == null || !smsCode.equals(phoneValidCode))) {
@@ -422,7 +427,7 @@ public class SysAuthServiceImpl implements SysAuthService {
             sysUserMapper.updateUserPassword(updateDTO);
 
             // 更改成功,销毁 smsCode
-            redisCache.deleteObject(redisKey);
+            redisUtil.deleteObject(redisKey);
 
             return Map.of("user_id", updateDTO.getUser_id());
 
@@ -435,10 +440,10 @@ public class SysAuthServiceImpl implements SysAuthService {
      */
     @Override
     public Map<String, Object>  logout(HttpServletRequest request) {
-        String token = tokenService.getToken(request);
+        String token = tokenUtil.getToken(request);
         if (token != null && !token.isEmpty()) {
             // 将 Token 作废
-            tokenService.deleteRedisToken();
+            tokenUtil.deleteRedisToken();
             return Map.of("message", "退出成功");
         }
         throw new CustomException(ResultEnum.TOKEN_EMPTY_ERROR.getMessage(), ResultEnum.TOKEN_EMPTY_ERROR.getCode());

+ 5 - 5
src/main/java/com/backendsys/service/System/SysMenuServiceImpl.java

@@ -1,6 +1,6 @@
 package com.backendsys.service.System;
 
-import com.backendsys.config.Redis.RedisCache;
+import com.backendsys.config.Redis.utils.RedisUtil;
 import com.backendsys.entity.System.SysMenuDTO;
 import com.backendsys.mapper.System.SysMenuMapper;
 import com.fasterxml.jackson.core.JsonProcessingException;
@@ -19,7 +19,7 @@ public class SysMenuServiceImpl implements SysMenuService {
     private RedisTemplate redisTemplate;
 
     @Autowired
-    private RedisCache redisCache;
+    private RedisUtil redisUtil;
 
     @Autowired
     private SysMenuMapper sysMenuMapper;
@@ -86,7 +86,7 @@ public class SysMenuServiceImpl implements SysMenuService {
     public Map<String, Object> insertMenu(SysMenuDTO sysMenuDTO) {
         sysMenuMapper.insertMenu(sysMenuDTO);
         // 删除缓存
-        redisCache.deleteObject("catchSysMenu");
+        redisUtil.deleteObject("catchSysMenu");
         //
         return Map.of("menu_id", sysMenuDTO.getId());
     }
@@ -99,7 +99,7 @@ public class SysMenuServiceImpl implements SysMenuService {
     public Map<String, Object> updateMenu(SysMenuDTO sysMenuDTO) {
         sysMenuMapper.updateMenu(sysMenuDTO);
         // 删除缓存
-        redisCache.deleteObject("catchSysMenu");
+        redisUtil.deleteObject("catchSysMenu");
         //
         return Map.of("menu_id", sysMenuDTO.getMenu_id());
     }
@@ -112,7 +112,7 @@ public class SysMenuServiceImpl implements SysMenuService {
     public Map<String, Object> deleteMenu(SysMenuDTO sysMenuDTO) {
         sysMenuMapper.deleteMenu(sysMenuDTO);
         // 删除缓存
-        redisCache.deleteObject("catchSysMenu");
+        redisUtil.deleteObject("catchSysMenu");
         //
         return Map.of("menu_id", sysMenuDTO.getMenu_id());
     }

+ 4 - 7
src/main/java/com/backendsys/utils/CommonUtil.java

@@ -11,26 +11,23 @@ import java.util.Random;
 import java.util.UUID;
 
 import cn.hutool.core.date.DateUtil;
-import com.backendsys.config.Security.service.TokenService;
 import com.backendsys.exception.CustomException;
-import io.jsonwebtoken.Claims;
 import jakarta.servlet.http.HttpServletRequest;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 
 @Component
 public class CommonUtil {
 
     //@Autowired
-    //private static TokenService tokenService;
+    //private static TokenUtil tokenService;
 
     // 以上引用会报错:
-    // Cannot invoke \"com.backendsys.config.Security.service.TokenService.getTokenInfo(jakarta.servlet.http.HttpServletRequest)\" because \"com.backendsys.utils.CommonUtil.tokenService\" is null
+    // Cannot invoke \"com.backendsys.config.Security.utils.TokenUtil.getTokenInfo(jakarta.servlet.http.HttpServletRequest)\" because \"com.backendsys.utils.CommonUtil.tokenService\" is null
     // 工具类无法直接用,得写 set 方法,如下:
 
-    //private static TokenService tokenService;
+    //private static TokenUtil tokenService;
     //@Autowired
-    //public void setTokenService(TokenService tokenService) {
+    //public void setTokenService(TokenUtil tokenService) {
     //    this.tokenService = tokenService;
     //}
 

+ 3 - 3
src/main/java/com/backendsys/utils/LanguageUtil.java

@@ -1,6 +1,6 @@
 package com.backendsys.utils;
 
-import com.backendsys.config.Security.service.TokenService;
+import com.backendsys.config.Security.utils.TokenUtil;
 
 import java.util.ArrayList;
 import java.util.HashMap;
@@ -19,7 +19,7 @@ import org.springframework.stereotype.Component;
 public class LanguageUtil {
 
     @Autowired
-    private TokenService tokenService;
+    private TokenUtil tokenUtil;
     @Autowired
     private StringRedisTemplate stringRedisTemplate;
 
@@ -28,7 +28,7 @@ public class LanguageUtil {
 
     public String getLang() {
         // 配置语言参数
-        String langRedisKey = "lang:" + tokenService.getLoginUUID();
+        String langRedisKey = "lang:" + tokenUtil.getLoginUUID();
         String lang = stringRedisTemplate.opsForValue().get(langRedisKey);
         if (lang.isEmpty()) lang = DEFAULT_LANGUAGE;
         return lang;

+ 21 - 18
src/main/resources/application.yml

@@ -121,24 +121,27 @@ TOKEN_DURATION_MEMBER: 604800000
 # (防止恶意用户同时使用多个会话进行非法操作)
 MAXIMUM_SESSIONS: -1
 
-
-#监控器 Actuator
-management:
-  # 端点开放控制
-  endpoint:
-    # 打开 shutdown 接口,默认的时候仅有它是 false
-    shutdown:
-      enabled: true
-    # 端点全局配置
-    health:
-      show-details: always
-  endpoints:
-    web:
-      # 配置开放所有端点
-      exposure:
-        include: "*"
-      # 修改访问路径 2.0之前默认是/; 2.0及以后默认是/actuator可以通过这个属性值修改
-      base-path: /api/system/actuator
+# [Redis] 登录键
+REDIS_LOGIN_KEY: "token:id:"
+
+
+##监控器 Actuator
+#management:
+#  # 端点开放控制
+#  endpoint:
+#    # 打开 shutdown 接口,默认的时候仅有它是 false
+#    shutdown:
+#      enabled: true
+#    # 端点全局配置
+#    health:
+#      show-details: always
+#  endpoints:
+#    web:
+#      # 配置开放所有端点
+#      exposure:
+#        include: "*"
+#      # 修改访问路径 2.0之前默认是/; 2.0及以后默认是/actuator可以通过这个属性值修改
+#      base-path: /api/system/actuator
 
 
 ## 数据库表唯一值的错误提示配置