tsurumure 5 kuukautta sitten
vanhempi
commit
a9deca73d7

+ 3 - 1
src/main/java/com/backendsys/controller/B2c/B2cGoodController.java

@@ -4,6 +4,7 @@ import com.backendsys.aspect.QueryNullCheck;
 import com.backendsys.aspect.QueryNullCheckAspect;
 import com.backendsys.entity.B2c.B2cGoodDTO;
 import com.backendsys.entity.PageDTO;
+import com.backendsys.modules.common.aspect.AppUserLogin;
 import com.backendsys.service.B2c.B2cGoodService;
 import com.backendsys.utils.response.Result;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -27,7 +28,8 @@ public class B2cGoodController {
         return Result.success(b2cGoodService.queryGoodList(pageDTO.getPage_num(), pageDTO.getPage_size(), b2cGoodDTO));
     }
 
-    @PreAuthorize("@ss.isMember")
+//    @PreAuthorize("@ss.isMember")
+    @AppUserLogin
     @GetMapping("/api/front/b2c/good/getGood")
     public Result getFrontGood(@Validated PageDTO pageDTO, @Validated B2cGoodDTO b2cGoodDTO) {
         return Result.success(b2cGoodService.queryGoodList(pageDTO.getPage_num(), pageDTO.getPage_size(), b2cGoodDTO));

+ 5 - 0
src/main/java/com/backendsys/modules/app/entity/AppUser.java

@@ -15,6 +15,8 @@ public class AppUser {
 
     @TableId(type = IdType.AUTO)
     private Long id;
+    @TableField(exist = false)
+    private Long user_id;
     private String wechat_open_id;
     private String nickname;
 
@@ -33,6 +35,9 @@ public class AppUser {
     private String update_time;
     private Integer del_flag;
 
+    @TableField(exist = false)
+    private String role;
+
     @TableField(exist = false)
     private String token_expiration;
     @TableField(exist = false)

+ 5 - 0
src/main/java/com/backendsys/modules/app/service/impl/AppAuthServiceImpl.java

@@ -91,6 +91,7 @@ public class AppAuthServiceImpl implements AppAuthService {
 
         // 设置 最后一次的登录信息 (uuid, ip, 登录时间)
         String uuid = Convert.toStr(UUID.randomUUID());
+        appUser.setUser_id(appUser.getId());
         appUser.setLast_login_uuid(uuid);
         appUser.setLast_login_ip(httpRequestUtil.getIpAddr());
         appUser.setLast_login_time(DateUtil.format(new Date(), "yyyy-MM-dd HH:mm:ss"));
@@ -105,9 +106,13 @@ public class AppAuthServiceImpl implements AppAuthService {
 
         Date token_expiration = new Date((new Date()).getTime() + DEFAULT_MILLISECONDS);
         appUser.setToken_expiration(DateUtil.format(token_expiration, "yyyy-MM-dd HH:mm:ss"));
+        appUser.setRole("APP_USER");
 
         // 生成 Token
         SecurityAppUserInfo securityUserInfo = JSONUtil.toBean(JSONUtil.parseObj(appUser), SecurityAppUserInfo.class);
+
+        System.out.println("securityUserInfo = " + securityUserInfo);
+
         String token = jwtUtil.createAppJwtToken(securityUserInfo);
         String token_redis_key = REDIS_LOGIN_TOKEN_PREFIX + uuid;
         appUser.setToken(token);

+ 9 - 0
src/main/java/com/backendsys/modules/common/aspect/AppUserLogin.java

@@ -0,0 +1,9 @@
+package com.backendsys.modules.common.aspect;
+
+import java.lang.annotation.*;
+
+@Target(ElementType.METHOD)
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+public @interface AppUserLogin {
+}

+ 49 - 0
src/main/java/com/backendsys/modules/common/aspect/AppUserLoginAspect.java

@@ -0,0 +1,49 @@
+package com.backendsys.modules.common.aspect;
+
+import cn.hutool.core.convert.Convert;
+import com.backendsys.exception.CustException;
+import com.backendsys.modules.common.config.security.entity.SecurityAppUserInfo;
+import com.backendsys.modules.common.config.security.entity.SecurityUserInfo;
+import com.backendsys.modules.common.config.security.utils.JwtUtil;
+import com.backendsys.modules.common.config.security.utils.SecurityUtil;
+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;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+
+/**
+ * [AOP] APP用户登录鉴权
+ */
+@Aspect
+@Component
+public class AppUserLoginAspect {
+
+    @Pointcut("@annotation(AppUserLogin)")
+    public void checkLogin() {}
+
+    @Before("checkLogin()")
+    public void doCheckLogin(JoinPoint joinPoint) throws Throwable {
+        // 获取请求信息
+        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
+
+//        // 获取Token
+//        String token = request.getHeader("Authorization");
+//        System.out.println("(AppUserLoginAspect) token = " + token);
+//        jwtUtil.extractAllClaims(token);
+        SecurityAppUserInfo userInfo = SecurityUtil.getAppUserInfo();
+        String tokenRole = Convert.toStr(userInfo.getRole());
+        if (!"APP_USER".equals(tokenRole)) {
+            throw new CustException("当前接口与 Token 的类型不匹配");
+        }
+        System.out.println(userInfo);
+
+//        if (token == null) throw new CustException("未登录或Token无效");
+
+
+    }
+}

+ 2 - 1
src/main/java/com/backendsys/modules/common/config/WebConfig.java

@@ -13,8 +13,9 @@ public class WebConfig implements WebMvcConfigurer {
 
     @Value("${API_LOG}")
     private Boolean API_LOG;
+
     @Autowired
-    private ApiLogInterceptor apiLogInterceptor;
+    private ApiLogInterceptor apiLogInterceptor;        // 日志拦截器
 
     @Override
     public void addInterceptors(InterceptorRegistry registry) {

+ 1 - 2
src/main/java/com/backendsys/modules/common/config/security/SecurityConfig.java

@@ -2,6 +2,7 @@ package com.backendsys.modules.common.config.security;
 
 import cn.hutool.core.util.ArrayUtil;
 //import com.backendsys.modules.common.config.security.filter.AnonymousFilter;
+import com.backendsys.modules.common.config.security.annotations.AnonymousProperties;
 import com.backendsys.modules.common.config.security.filter.CaptchaVerficationFilter;
 import com.backendsys.modules.common.config.security.filter.JwtAuthenticationFilter;
 import lombok.RequiredArgsConstructor;
@@ -19,8 +20,6 @@ import org.springframework.security.crypto.password.PasswordEncoder;
 import org.springframework.security.web.SecurityFilterChain;
 import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
 
-import java.util.Arrays;
-
 @Configuration
 @EnableWebSecurity
 @RequiredArgsConstructor

+ 0 - 1
src/main/java/com/backendsys/modules/common/config/security/annotations/Anonymous.java

@@ -5,7 +5,6 @@ import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.lang.annotation.Target;
 
-//@Target(ElementType.METHOD)
 @Target({ ElementType.METHOD, ElementType.TYPE })
 @Retention(RetentionPolicy.RUNTIME)
 public @interface Anonymous {

+ 3 - 2
src/main/java/com/backendsys/modules/common/config/security/AnonymousProperties.java → src/main/java/com/backendsys/modules/common/config/security/annotations/AnonymousProperties.java

@@ -1,4 +1,4 @@
-package com.backendsys.modules.common.config.security;
+package com.backendsys.modules.common.config.security.annotations;
 
 import cn.hutool.core.convert.Convert;
 import cn.hutool.core.util.StrUtil;
@@ -22,13 +22,14 @@ import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 import cn.hutool.core.util.ReUtil;
 
+// 编辑注释权限
+// src/main/java/com/backendsys/modules/common/config/security/filter/JwtAuthenticationFilter.java
 @Configuration
 public class AnonymousProperties implements InitializingBean, ApplicationContextAware {
 
     private static final Pattern PATTERN = Pattern.compile("\\{(.*?)\\}");
     private ApplicationContext applicationContext;
     private List<String> urls = new ArrayList<>();
-
     public String ASTERISK = "*";
 
     @Override

+ 1 - 0
src/main/java/com/backendsys/modules/common/config/security/entity/SecurityAppUserInfo.java

@@ -12,4 +12,5 @@ public class SecurityAppUserInfo {
     private String phone;
     private String last_login_uuid;
     private String token_expiration;
+    private String role;
 }

+ 0 - 50
src/main/java/com/backendsys/modules/common/config/security/filter/AnonymousFilter.java

@@ -1,50 +0,0 @@
-//package com.backendsys.modules.common.config.security.filter;
-//
-//import com.backendsys.modules.common.config.security.annotations.Anonymous;
-//import jakarta.servlet.http.HttpServletRequest;
-//import jakarta.servlet.http.HttpServletResponse;
-//import jakarta.servlet.FilterChain;
-//import jakarta.servlet.ServletException;
-//
-//import org.springframework.stereotype.Component;
-//import org.springframework.web.filter.OncePerRequestFilter;
-//
-//
-//import java.io.IOException;
-//import java.util.Map;
-//
-//@Component
-//public class AnonymousFilter extends OncePerRequestFilter {
-//
-//    @Override
-//    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
-//        throws ServletException, IOException {
-//
-//        // 检查是否有@Anonymous注解,如果有,则允许访问
-//        if (hasAnonymousAnnotation(request)) {
-//            filterChain.doFilter(request, response);
-//        } else {
-//            // 继续执行Spring Security的过滤器链
-//            filterChain.doFilter(request, response);
-//        }
-//    }
-//
-//
-//    private boolean hasAnonymousAnnotation(HttpServletRequest request) {
-//
-////        Anonymous method = AnnotationUtils.findAnnotation(handlerMethod.getMethod(), Anonymous.class);
-//
-////        RequestAttributes attributes = RequestContextHolder.getRequestAttributes();
-////        HandlerMethod handlerMethod = (HandlerMethod) attributes.getAttribute(HandlerMethod.class.getName(), RequestAttributes.SCOPE_REQUEST);
-////
-////        // 获取当前请求的 HandlerMethod
-////        System.out.println("handlerMethod: " + handlerMethod);
-////        System.out.println("------------------------------------");
-////        if (handlerMethod != null) {
-////            // 检查方法是否有@Anonymous注解
-////            return handlerMethod.getMethodAnnotation(Anonymous.class) != null;
-////        }
-//        return false;
-//    }
-//
-//}

+ 1 - 3
src/main/java/com/backendsys/modules/common/config/security/filter/JwtAuthenticationFilter.java

@@ -1,9 +1,7 @@
 package com.backendsys.modules.common.config.security.filter;
 
-import cn.hutool.core.convert.Convert;
 import cn.hutool.core.util.ArrayUtil;
-import cn.hutool.core.util.StrUtil;
-import com.backendsys.modules.common.config.security.AnonymousProperties;
+import com.backendsys.modules.common.config.security.annotations.AnonymousProperties;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.backendsys.utils.response.Result;
 import com.backendsys.utils.response.ResultEnum;

+ 0 - 3
src/main/java/com/backendsys/modules/common/config/security/utils/HttpRequestUtil.java

@@ -37,9 +37,6 @@ public class HttpRequestUtil {
             Claims tokenInfo = tokenUtil.getTokenInfo(request);
             if (tokenInfo != null) {
                 Map<String, Object> userInfo = (Map<String, Object>) tokenInfo.get("userInfo");
-
-                System.out.println("userInfo: " + userInfo);
-
                 return Convert.toLong(userInfo.get("user_id"));
             }
         }

+ 122 - 0
src/main/java/com/backendsys/modules/common/config/security/utils/PermissionUtil.java

@@ -0,0 +1,122 @@
+//package com.backendsys.modules.common.config.security.utils;
+//
+//import com.backendsys.exception.CustException;
+//import com.backendsys.modules.common.config.redis.utils.RedisUtil;
+//import com.backendsys.modules.common.config.security.entity.SecurityUserInfo;
+//import com.backendsys.utils.response.ResultEnum;
+//import org.springframework.beans.factory.annotation.Autowired;
+//import org.springframework.beans.factory.annotation.Value;
+//import org.springframework.stereotype.Service;
+//import org.springframework.util.CollectionUtils;
+//import org.springframework.util.StringUtils;
+//
+//import java.util.*;
+//
+///**
+// * 即将弃用
+// * 自定义权限 @PreAuthorize("@sr.hasPermission('3.2.3') && @ss.isSuper()")
+// */
+//@Service("ss")
+//public class PermissionUtil {
+//    //private static final String ALL_PERMISSION = "*:*:*";
+//
+//    @Value("${REDIS_LOGIN_TOKEN_PREFIX}")
+//    private String REDIS_LOGIN_TOKEN_PREFIX;
+//    @Value("${REDIS_LOGIN_PERMISSION_PREFIX}")
+//    private String REDIS_LOGIN_PERMISSION_PREFIX;
+//
+//    @Autowired
+//    private RedisUtil redisUtil;
+//
+//    /**
+//     * 验证用户是否具备权限
+//     * @param permi 权限字符串
+//     * @return boolean
+//     */
+////    public boolean hasPermi(String permi) {
+//    public boolean hasPermi(Collection<String> permi) {
+//
+//        if (CollectionUtils.isEmpty(permi)) return false;
+//
+//        SecurityUserInfo securityUserInfo = SecurityUtil.getUserInfo();
+//        // 如果是超级管理员,则直接通过
+//        if (securityUserInfo.getIs_super() == 1) return true;
+//
+//        // 没有 permission_ids 即不是系统用户,即没有访问后台的权限
+//        if (securityUserInfo != null) {
+//
+////            String uuid = securityUserInfo.getLast_login_uuid();
+////            String redis_key = REDIS_LOGIN_PERMISSION_PREFIX + uuid;
+////            String permission_ids_str = redisUtil.getCacheObject(redis_key);
+////            List<String> permission_ids = Arrays.asList(permission_ids_str.split(","));
+//
+//            List<String> permission_ids = securityUserInfo.getPermission_ids();
+//
+//            if (permission_ids != null && !permission_ids.isEmpty()) {
+//                Set<String> dataSet = new HashSet<>();
+//                for (String permission_id : permission_ids) {
+//                    dataSet.add(permission_id);
+//                }
+//                for (String permission : permi) {
+//                    if (hasPermissions(dataSet, permission)) {
+//                        return true;
+//                    }
+//                }
+//                // return hasPermissions(modulesSet, permission);
+//            }
+//        }
+//        return false;
+//    }
+//    public boolean hasPermissions(Set<String> permi, String permission) {
+//        return permi.contains(StringUtils.trimAllWhitespace(permission));
+//    }
+//
+//    // 是否超级管理员
+//    public boolean isSuper() {
+//        SecurityUserInfo securityUserInfo = SecurityUtil.getUserInfo();
+//        return securityUserInfo.getIs_super() == 1;
+//    }
+//
+//    // 是否超级管理员 (首位)
+//    public boolean isFirstSuper() {
+//        SecurityUserInfo securityUserInfo = SecurityUtil.getUserInfo();
+//        return securityUserInfo.getUser_id() == 1;
+//    }
+//
+//    // 是否会员
+//    public boolean isMember() {
+//        SecurityUserInfo securityUserInfo = SecurityUtil.getUserInfo();
+//        return "Member".equals(securityUserInfo.getTarget());
+//    }
+//
+//
+//    /**
+//     * 判断是否匹配当前 {用户ID} 与 {用户权限},不是则抛出错误
+//     * - 匹配,通过
+//     * - 不匹配,再次检查权限
+//     *    - 匹配,通过
+//     *    - 不匹配,抛出错误
+//     * permissionService.checkUserIdAndPermission(sysUserDTO.getUser_id(), "3.2.1");
+//     */
+//    public void checkUserIdAndPermission(long user_id, Collection<String> permis) {
+//        SecurityUserInfo securityUserInfo = SecurityUtil.getUserInfo();
+//        if (securityUserInfo.getUser_id() != user_id) {
+//            if (!hasPermi(permis)) {
+//                throw new CustException(ResultEnum.AUTH_ROLE_ERROR.getMessage(), ResultEnum.AUTH_ROLE_ERROR.getCode());
+//            }
+//        }
+//    }
+//
+//    /**
+//     * 判断是否 首位超级管理员 (id:1),不是则抛出错误
+//     */
+//    public void checkSuperAdminOfFirst(long user_id) {
+//        if (user_id == 1) {
+//            SecurityUserInfo securityUserInfo = SecurityUtil.getUserInfo();
+//            if (securityUserInfo.getUser_id() != 1) {
+//                throw new CustException(ResultEnum.AUTH_USER_ERROR.getMessage(), ResultEnum.AUTH_USER_ERROR.getCode());
+//            }
+//        }
+//    }
+//
+//}

+ 13 - 0
src/main/java/com/backendsys/modules/common/config/security/utils/SecurityUtil.java

@@ -6,6 +6,7 @@ import cn.hutool.json.JSONObject;
 import cn.hutool.json.JSONUtil;
 import com.backendsys.exception.CustException;
 import com.backendsys.modules.common.config.redis.utils.RedisUtil;
+import com.backendsys.modules.common.config.security.entity.SecurityAppUserInfo;
 import com.backendsys.modules.common.config.security.entity.SecurityUserInfo;
 import com.backendsys.modules.common.enums.MatchType;
 import com.backendsys.modules.system.entity.TokenCatch;
@@ -84,6 +85,18 @@ public class SecurityUtil {
         securityUserInfo.setTarget(target);
         return securityUserInfo;
     }
+
+    public static SecurityAppUserInfo getAppUserInfo(){
+        String token = getToken();
+        if (StrUtil.isEmpty(token)) throw new CustException("getUserInfo() token is empty.");
+        if (token.contains("SessionId") || token.contains("RemoteIpAddress")) throw new CustException("getUserInfo() need token.");
+        Claims tokenInfo = Jwts.parser().verifyWith(getSignInKey()).build().parseSignedClaims(token).getPayload();
+        JSONObject userInfo = JSONUtil.parseObj(tokenInfo.get("userInfo"));
+        SecurityAppUserInfo securityAppUserInfo = JSONUtil.toBean(userInfo, SecurityAppUserInfo.class);
+        return securityAppUserInfo;
+    }
+
+
     /**
      * 判断是否超级管理员
      */