diff --git a/pom.xml b/pom.xml index 2c2b8a7..de6c7a6 100644 --- a/pom.xml +++ b/pom.xml @@ -117,6 +117,12 @@ spring-boot-starter-data-redis + + + org.springframework.boot + spring-boot-starter-aop + + @@ -128,6 +134,19 @@ + + + + com.github.whvcse + easy-captcha + 1.6.2 + + + + cn.hutool + hutool-all + 5.8.26 + diff --git a/src/main/java/com/cultural/heritage/annotation/AuthCheck.java b/src/main/java/com/cultural/heritage/annotation/AuthCheck.java new file mode 100644 index 0000000..896fa2b --- /dev/null +++ b/src/main/java/com/cultural/heritage/annotation/AuthCheck.java @@ -0,0 +1,18 @@ +package com.cultural.heritage.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * 权限校验 + */ +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +public @interface AuthCheck { + /** + * 必须有某个角色 + */ + String mustRole() default ""; +} diff --git a/src/main/java/com/cultural/heritage/aop/AuthInterceptor.java b/src/main/java/com/cultural/heritage/aop/AuthInterceptor.java new file mode 100644 index 0000000..a4cf04f --- /dev/null +++ b/src/main/java/com/cultural/heritage/aop/AuthInterceptor.java @@ -0,0 +1,69 @@ +package com.cultural.heritage.aop; + +import com.cultural.heritage.annotation.AuthCheck; +import com.cultural.heritage.common.ErrorCode; +import com.cultural.heritage.constant.UserConstant; +import com.cultural.heritage.exception.BusinessException; +import com.cultural.heritage.model.entity.User; +import com.cultural.heritage.model.enums.UserRoleEnum; +import com.cultural.heritage.service.userinfo.UserService; +import io.micrometer.common.util.StringUtils; +import jakarta.annotation.Resource; +import jakarta.servlet.http.HttpServletRequest; +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.annotation.Around; +import org.aspectj.lang.annotation.Aspect; +import org.springframework.stereotype.Component; +import org.springframework.web.context.request.RequestAttributes; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; + +/** + * 权限校验AOP + */ +@Aspect +@Component +public class AuthInterceptor { + + @Resource + private UserService userService; + + /** + * 执行拦截 + */ + @Around("@annotation(authCheck)") + public Object doInterceptor(ProceedingJoinPoint joinPoint, AuthCheck authCheck) throws Throwable { + String mustRole = authCheck.mustRole(); + RequestAttributes requestAttributes = RequestContextHolder.currentRequestAttributes(); + HttpServletRequest request = ((ServletRequestAttributes) requestAttributes).getRequest(); + + //当前登录用户 + User loginUser = userService.getLoginUser(request); + //必须有该权限才通过 + if (StringUtils.isNotBlank(mustRole)) { + UserRoleEnum mustUserRoleEnum = UserRoleEnum.getEnumByValues(mustRole); + if(mustUserRoleEnum == null) { + throw new BusinessException(ErrorCode.NO_AUTH_ERROR); + } + String userRole = loginUser.getUserRole(); + //如果被封号,直接拒绝 + if (UserRoleEnum.BAN.equals(mustUserRoleEnum)) { + throw new BusinessException(ErrorCode.NO_AUTH_ERROR); + } + //必须有BOSS权限 + if (UserRoleEnum.BOSS.equals(mustUserRoleEnum)) { + if (!mustRole.equals(userRole)) { + throw new BusinessException(ErrorCode.NO_AUTH_ERROR); + } + } + //必须有管理员权限 + if (UserRoleEnum.ADMIN.equals(mustUserRoleEnum)) { + if (!mustRole.equals(userRole) && !userRole.equals(UserConstant.BOSS_ROLE)) { + throw new BusinessException(ErrorCode.NO_AUTH_ERROR); + } + } + } + //通过权限校验,放行 + return joinPoint.proceed(); + } +} diff --git a/src/main/java/com/cultural/heritage/aopTest/AopConfig.java b/src/main/java/com/cultural/heritage/aopTest/AopConfig.java new file mode 100644 index 0000000..ad7cbef --- /dev/null +++ b/src/main/java/com/cultural/heritage/aopTest/AopConfig.java @@ -0,0 +1,61 @@ +package com.cultural.heritage.aopTest; + +import jakarta.servlet.http.HttpServletRequest; +import lombok.extern.log4j.Log4j; +import lombok.extern.slf4j.Slf4j; +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.aspectj.lang.reflect.MethodSignature; +import org.springframework.stereotype.Component; +import org.springframework.web.context.request.RequestAttributes; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; + +import java.lang.reflect.Method; +import java.util.Set; + +@Component +@Aspect +@Slf4j +public class AopConfig { + + @Pointcut("@annotation(com.cultural.heritage.aopTest.HasRole)") + public void pointcut(){} + + @Before("pointcut()") + public void before(JoinPoint joinPoint) { + System.out.println("before-----------------"); + + //获取到HttpServletRequest + RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes(); + ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) requestAttributes; + HttpServletRequest request = servletRequestAttributes.getRequest(); + + String username = request.getParameter("username"); + + //获取当前用户角色的集合 + Set userRoles = CacheManager.USER_ROLE_MAP.get(username); + + //获取当前请求的方法的签名 + MethodSignature signature = (MethodSignature) joinPoint.getSignature(); + + //反射获取当前被调用的方法 + Method method = signature.getMethod(); + + //判断当前方法是否有hasRole注解 + //如果有,判断用户是否具有注解属性中要求的角色 + //如果没有hasRole注解,那么说明方法不需要判断用户的角色,可以匿名访问 + + HasRole hasRole = method.getDeclaredAnnotation(HasRole.class); + System.out.println("hasRole:" + hasRole.value()); + System.out.println("userRoles:" + userRoles); + log.info("----------------"); + + if(!userRoles.contains(hasRole.value())) { + throw new RuntimeException("用户没有访问的权限"); + } + + } +} diff --git a/src/main/java/com/cultural/heritage/aopTest/AopController.java b/src/main/java/com/cultural/heritage/aopTest/AopController.java new file mode 100644 index 0000000..93ba456 --- /dev/null +++ b/src/main/java/com/cultural/heritage/aopTest/AopController.java @@ -0,0 +1,31 @@ +package com.cultural.heritage.aopTest; + +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/aop") +public class AopController { + + + //调用这个方法需要用户具有admin的角色 + @HasRole("admin") + @GetMapping("query1") + public String query1() { + return "query1 需要 admin 角色"; + } + + //调用这个方法需要用户具有user的角色 + @HasRole("user") + @GetMapping("query2") + public String query2() { + return "query2 需要 user 角色"; + } + + // 任何用户都可以访问 + @GetMapping("query3") + public String query3() { + return "query3 可以匿名访问"; + } +} diff --git a/src/main/java/com/cultural/heritage/aopTest/CacheManager.java b/src/main/java/com/cultural/heritage/aopTest/CacheManager.java new file mode 100644 index 0000000..64454f3 --- /dev/null +++ b/src/main/java/com/cultural/heritage/aopTest/CacheManager.java @@ -0,0 +1,22 @@ +package com.cultural.heritage.aopTest; + +import com.google.common.collect.Sets; + +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +public class CacheManager { + + public static final Map> USER_ROLE_MAP = new HashMap<>(); + + static { + //用户zhangsan具有user和admin两个角色 + Set roleSet1 = Sets.newHashSet("admin", "user"); + USER_ROLE_MAP.put("zhangsan", roleSet1); + + + Set roleSet2 = Sets.newHashSet("user"); + USER_ROLE_MAP.put("lisi", roleSet2); + } +} diff --git a/src/main/java/com/cultural/heritage/aopTest/HasRole.java b/src/main/java/com/cultural/heritage/aopTest/HasRole.java new file mode 100644 index 0000000..b1f7e62 --- /dev/null +++ b/src/main/java/com/cultural/heritage/aopTest/HasRole.java @@ -0,0 +1,12 @@ +package com.cultural.heritage.aopTest; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +public @interface HasRole { + String value(); +} diff --git a/src/main/java/com/cultural/heritage/common/ErrorCode.java b/src/main/java/com/cultural/heritage/common/ErrorCode.java index d94470a..d6f135b 100644 --- a/src/main/java/com/cultural/heritage/common/ErrorCode.java +++ b/src/main/java/com/cultural/heritage/common/ErrorCode.java @@ -8,6 +8,7 @@ public enum ErrorCode { SUCCESS(1,"ok"), PARAMS_ERROR(40000,"请求参数错误"), NOT_LOGIN_ERROR(40100,"未登录"), + NO_AUTH_ERROR(40101, "无权限"), NOT_FOUND_ERROR(40400,"请求数据不存在"), FORBIDDEN_ERROR(40300,"禁止访问"), SYSTEM_ERROR(50000,"系统内部异常"), diff --git a/src/main/java/com/cultural/heritage/constant/UserConstant.java b/src/main/java/com/cultural/heritage/constant/UserConstant.java index 7e95657..bae6171 100644 --- a/src/main/java/com/cultural/heritage/constant/UserConstant.java +++ b/src/main/java/com/cultural/heritage/constant/UserConstant.java @@ -16,4 +16,26 @@ public interface UserConstant { * 用户登录键 */ String USER_LOGIN_STATE = "feiyi"; + + + /** + * 默认角色 + */ + String DEFAULT_ROLE = "user"; + + /** + * 管理员角色 + */ + String ADMIN_ROLE = "admin"; + + /** + * Boss + */ + String BOSS_ROLE = "boss"; + + /** + * 被封号 + */ + String BAN_ROLE = "ban"; + } diff --git a/src/main/java/com/cultural/heritage/controller/userinfo/UserController.java b/src/main/java/com/cultural/heritage/controller/userinfo/UserController.java index 0aa8669..3345dc1 100644 --- a/src/main/java/com/cultural/heritage/controller/userinfo/UserController.java +++ b/src/main/java/com/cultural/heritage/controller/userinfo/UserController.java @@ -1,22 +1,42 @@ package com.cultural.heritage.controller.userinfo; +import cn.hutool.core.util.IdUtil; import com.cultural.heritage.common.BaseResponse; import com.cultural.heritage.common.ErrorCode; import com.cultural.heritage.common.ResultUtils; +import com.cultural.heritage.constant.CommonConstant; +import com.cultural.heritage.constant.UserConstant; import com.cultural.heritage.exception.BusinessException; +import com.cultural.heritage.exception.ThrowUtils; +import com.cultural.heritage.model.dto.CommonRequest; +import com.cultural.heritage.model.dto.user.UserAddRequest; import com.cultural.heritage.model.dto.user.UserLoginRequest; +import com.cultural.heritage.model.dto.user.UserUpdateMyRequest; +import com.cultural.heritage.model.dto.user.UserUpdateRequest; import com.cultural.heritage.model.entity.User; import com.cultural.heritage.model.vo.UserVO; import com.cultural.heritage.service.userinfo.UserService; +import com.wf.captcha.SpecCaptcha; import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.annotation.Resource; import jakarta.servlet.http.HttpServletRequest; import lombok.extern.slf4j.Slf4j; +import org.apache.catalina.webresources.ExtractingRoot; import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.BeanUtils; +import org.springframework.context.annotation.Bean; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.util.DigestUtils; import org.springframework.web.bind.annotation.*; +import javax.xml.transform.Result; +import java.util.HashMap; import java.util.List; +import java.util.Map; +import java.util.concurrent.TimeUnit; + +import static com.cultural.heritage.constant.UserConstant.SALT; /** * 用户接口 @@ -32,6 +52,8 @@ public class UserController { @Resource private UserService userService; + @Resource + private RedisTemplate redisTemplate; @GetMapping("/test") public String test(){ @@ -66,6 +88,8 @@ public class UserController { /** * 退出登录 + * @param request http + * @return 是否退出登录成功 */ @PostMapping("/logout") public BaseResponse userLogout(HttpServletRequest request) { @@ -78,6 +102,118 @@ public class UserController { + /** + * 更新个人信息 + * @param userUpdateMyRequest 更新请求体 + * @param request http + * @return 是否更新成功 + */ + @PostMapping("/update/my") + public BaseResponse updateMyUser(@RequestBody UserUpdateMyRequest userUpdateMyRequest, HttpServletRequest request) { + if (userUpdateMyRequest == null) { + throw new BusinessException(ErrorCode.PARAMS_ERROR); + } + User loginUser = userService.getLoginUser(request); + User user = new User(); + BeanUtils.copyProperties(userUpdateMyRequest, user); + user.setId(loginUser.getId()); + boolean result = userService.updateById(user); + ThrowUtils.throwIf(!result, ErrorCode.OPERATION_ERROR); + return ResultUtils.success(true); + } + + + /** + * 创建用户 + * @param userAddRequest 用户添加请求体 + * @return 添加用户的id + */ + @PostMapping("/add") + public BaseResponse addUser(@RequestBody UserAddRequest userAddRequest) { + if (userAddRequest == null) { + throw new BusinessException(ErrorCode.PARAMS_ERROR); + } + User user = new User(); + BeanUtils.copyProperties(userAddRequest, user); + String encryptPassword = DigestUtils.md5DigestAsHex((SALT + user.getUserPassword()).getBytes()); + user.setUserPassword(encryptPassword); + boolean save = userService.save(user); + if (!save) { + throw new BusinessException(ErrorCode.SYSTEM_ERROR); + } + return ResultUtils.success(user, "添加用户成功"); + } + + + /** + * 删除用户 + * @param deleteRequest 用户删除请求体 + * @return 是否删除 + */ + @PostMapping("/delete") + public BaseResponse deleteUser(@RequestBody CommonRequest deleteRequest) { + if (deleteRequest == null || deleteRequest.getId() <= 0) { + throw new BusinessException(ErrorCode.PARAMS_ERROR); + } + boolean result = userService.removeById(deleteRequest.getId()); + ThrowUtils.throwIf(!result, ErrorCode.OPERATION_ERROR); + return ResultUtils.success(true); + } + + + /** + * 更新用户 + * @param userUpdateRequest 用户更新请求体 + * @return 是否更新成功 + */ + @PostMapping("/update") + public BaseResponse updateUser(@RequestBody UserUpdateRequest userUpdateRequest) { + if (userUpdateRequest == null || userUpdateRequest.getId() == null) { + throw new BusinessException(ErrorCode.PARAMS_ERROR); + } + User user = new User(); + BeanUtils.copyProperties(userUpdateRequest, user); + boolean result = userService.updateById(user); + ThrowUtils.throwIf(!result, ErrorCode.OPERATION_ERROR); + return ResultUtils.success(true); + } + + + /** + * 根据 id 获取用户(仅管理员) + * @param id + * @return 用户信息 + */ + @GetMapping("/get") + public BaseResponse getUserById(long id) { + if (id <= 0) { + throw new BusinessException(ErrorCode.PARAMS_ERROR); + } + User user = userService.getById(id); + ThrowUtils.throwIf(user == null, ErrorCode.NOT_FOUND_ERROR); + return ResultUtils.success(user); + } + + + + + /** + * 图形验证码 + * @return + */ + @GetMapping("/captcha") + public BaseResponse getCapthca(){ + //设置生成的长宽还有数字位数 + SpecCaptcha specCaptcha = new SpecCaptcha(130, 48, 4); + String code = specCaptcha.text().toLowerCase(); + String uuid = IdUtil.simpleUUID(); + redisTemplate.opsForValue().set(uuid,code,120, TimeUnit.SECONDS); + HashMap map = new HashMap<>(3); + map.put("uuid",uuid); + map.put("code",code); + map.put("captcha",specCaptcha.toBase64()); + return ResultUtils.success(map,"成功"); + } diff --git a/src/main/java/com/cultural/heritage/model/dto/CommonRequest.java b/src/main/java/com/cultural/heritage/model/dto/CommonRequest.java new file mode 100644 index 0000000..eaac3ec --- /dev/null +++ b/src/main/java/com/cultural/heritage/model/dto/CommonRequest.java @@ -0,0 +1,18 @@ +package com.cultural.heritage.model.dto; + +import lombok.Data; + +import java.io.Serial; +import java.io.Serializable; + +@Data +public class CommonRequest implements Serializable { + + /** + * id + */ + private Long id; + + @Serial + private static final long serialVersionUID = -719221507292362303L; +} diff --git a/src/main/java/com/cultural/heritage/model/dto/user/UserAddRequest.java b/src/main/java/com/cultural/heritage/model/dto/user/UserAddRequest.java new file mode 100644 index 0000000..ef5ae7e --- /dev/null +++ b/src/main/java/com/cultural/heritage/model/dto/user/UserAddRequest.java @@ -0,0 +1,50 @@ +package com.cultural.heritage.model.dto.user; + +import lombok.Data; + +import java.io.Serial; +import java.io.Serializable; + +/** + * 用户创建请求 + */ + +@Data +public class UserAddRequest implements Serializable { + + + /** + * 用户昵称 + */ + private String userName; + + /** + * 账号 + */ + private String userAccount; + + /** + * 密码 + */ + private String userPassword; + + + /** + * 用户头像 + */ + private String userAvatar; + + /** + * 手机号 + */ + private String phone; + + /** + * 用户角色 user, admin + */ + private String userRole; + + @Serial + private static final long serialVersionUID = 1L; + +} diff --git a/src/main/java/com/cultural/heritage/model/dto/user/UserUpdateMyRequest.java b/src/main/java/com/cultural/heritage/model/dto/user/UserUpdateMyRequest.java new file mode 100644 index 0000000..0cd490e --- /dev/null +++ b/src/main/java/com/cultural/heritage/model/dto/user/UserUpdateMyRequest.java @@ -0,0 +1,32 @@ +package com.cultural.heritage.model.dto.user; + +import lombok.Data; + +import java.io.Serial; +import java.io.Serializable; + +/** + * 用户更新个人信息请求 + */ +@Data +public class UserUpdateMyRequest implements Serializable { + + /** + * 用户昵称 + */ + private String userName; + + /** + * 用户头像 + */ + private String userAvatar; + + /** + * 手机号 + */ + private String phone; + + + @Serial + private static final long serialVersionUID = 1L; +} diff --git a/src/main/java/com/cultural/heritage/model/dto/user/UserUpdateRequest.java b/src/main/java/com/cultural/heritage/model/dto/user/UserUpdateRequest.java new file mode 100644 index 0000000..25f87a4 --- /dev/null +++ b/src/main/java/com/cultural/heritage/model/dto/user/UserUpdateRequest.java @@ -0,0 +1,45 @@ +package com.cultural.heritage.model.dto.user; + +import lombok.Data; + +import java.io.Serial; +import java.io.Serializable; + +@Data +public class UserUpdateRequest implements Serializable { + + + /** + * id + */ + private Long id; + + /** + * 密码 + */ + private String userPassword; + + /** + * 用户名 + */ + private String userName; + + /** + * 头像 + */ + private String userAvatar; + + /** + * 手机号 + */ + private String phone; + + /** + * 用户角色 + */ + private String userRole; + + @Serial + private static final long serialVersionUID = -5057503930700700941L; + +} diff --git a/src/main/java/com/cultural/heritage/model/enums/UserRoleEnum.java b/src/main/java/com/cultural/heritage/model/enums/UserRoleEnum.java new file mode 100644 index 0000000..823f96b --- /dev/null +++ b/src/main/java/com/cultural/heritage/model/enums/UserRoleEnum.java @@ -0,0 +1,52 @@ +package com.cultural.heritage.model.enums; + +import lombok.Getter; +import org.springframework.util.ObjectUtils; + +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +/** + * 用户角色枚举 + */ +@Getter +public enum UserRoleEnum { + + USER("用户", "user"), + ADMIN("管理员", "admin"), + BOSS("Boss", "boss"), + BAN("被封号", "ban"); + + + private final String text; + + private final String value; + + UserRoleEnum(String text, String value) { + this.text = text; + this.value = value; + } + + /** + * 获取值列表 + */ + public static List getValues() { + return Arrays.stream(values()).map(item -> item.value).collect(Collectors.toList()); + } + + /** + * 获取值列表 + */ + public static UserRoleEnum getEnumByValues(String value) { + if (ObjectUtils.isEmpty(value)) { + return null; + } + for (UserRoleEnum anEnum : UserRoleEnum.values()) { + if(anEnum.value.equals(value)) { + return anEnum; + } + } + return null; + } +} diff --git a/src/main/java/com/cultural/heritage/service/userinfo/UserService.java b/src/main/java/com/cultural/heritage/service/userinfo/UserService.java index ff566b0..2d25978 100644 --- a/src/main/java/com/cultural/heritage/service/userinfo/UserService.java +++ b/src/main/java/com/cultural/heritage/service/userinfo/UserService.java @@ -25,4 +25,9 @@ public interface UserService extends IService { * @return 是否退出成功 */ boolean userLogout(HttpServletRequest request); + + /** + * 获取当前登录用户 + */ + User getLoginUser(HttpServletRequest request); } diff --git a/src/main/java/com/cultural/heritage/service/userinfo/impl/UserServiceImpl.java b/src/main/java/com/cultural/heritage/service/userinfo/impl/UserServiceImpl.java index be3618e..bed1fc3 100644 --- a/src/main/java/com/cultural/heritage/service/userinfo/impl/UserServiceImpl.java +++ b/src/main/java/com/cultural/heritage/service/userinfo/impl/UserServiceImpl.java @@ -7,6 +7,7 @@ import com.cultural.heritage.constant.UserConstant; import com.cultural.heritage.exception.BusinessException; import com.cultural.heritage.mapper.UserMapper; import com.cultural.heritage.model.entity.User; +import com.cultural.heritage.model.enums.UserRoleEnum; import com.cultural.heritage.model.vo.UserVO; import com.cultural.heritage.service.userinfo.UserService; import jakarta.annotation.Resource; @@ -30,7 +31,9 @@ import static com.cultural.heritage.constant.UserConstant.USER_LOGIN_STATE; public class UserServiceImpl extends ServiceImpl implements UserService { - + /** + * 用户登录 + */ @Override public UserVO userLogin(String userAccount, String userPassword, HttpServletRequest request) { if(userAccount.length() < 4) { @@ -53,6 +56,7 @@ public class UserServiceImpl extends ServiceImpl implements Us return this.getUserVO(user); } + @Override public UserVO getUserVO(User user) { if (user == null) { @@ -61,14 +65,9 @@ public class UserServiceImpl extends ServiceImpl implements Us UserVO userVO = new UserVO(); BeanUtils.copyProperties(user, userVO); return userVO; - } - /** - * - * @param request - * @return - */ + @Override public boolean userLogout(HttpServletRequest request) { HttpSession session = request.getSession(); @@ -79,4 +78,29 @@ public class UserServiceImpl extends ServiceImpl implements Us return true; } + /** + * 获取当前登录用户 + */ + @Override + public User getLoginUser(HttpServletRequest request) { + HttpSession session = request.getSession(); + Object userObj = session.getAttribute(USER_LOGIN_STATE); + User currentUser = (User) userObj; + if (currentUser == null || currentUser.getId() == null) { + throw new BusinessException(ErrorCode.NOT_LOGIN_ERROR); + } + + //根据id进行查询 + Long userId = currentUser.getId(); + currentUser = this.getById(userId); + if (currentUser == null) { + throw new BusinessException(ErrorCode.NOT_LOGIN_ERROR); + } + //被封号 + if (UserRoleEnum.BAN.getValue().equals(currentUser.getUserRole())) { + throw new BusinessException(ErrorCode.FORBIDDEN_ERROR); + } + return currentUser; + } + } diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 6d35d53..9f28e7c 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -4,6 +4,12 @@ spring: url: jdbc:mysql://123.249.108.160:3306/feiyi?serverTimezone=Asia/Shanghai username: feiyi password: 123456asd + data: + redis: + port: 6379 + host: localhost + database: 0 + diff --git a/src/test/java/com/cultural/heritage/aop/AopConfig.java b/src/test/java/com/cultural/heritage/aop/AopConfig.java new file mode 100644 index 0000000..9149de7 --- /dev/null +++ b/src/test/java/com/cultural/heritage/aop/AopConfig.java @@ -0,0 +1,54 @@ +package com.cultural.heritage.aop; + +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.aspectj.lang.reflect.MethodSignature; +import org.springframework.stereotype.Component; +import org.springframework.web.context.request.RequestAttributes; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; + +import java.lang.reflect.Method; +import java.util.Set; + +@Component +@Aspect +public class AopConfig { + + @Pointcut("@annotation(com.cultural.heritage.aop.HasRole)") + public void pointcut(){} + + @Before("pointcut()") + public void before(JoinPoint joinPoint) { + System.out.println("before-----------------"); + + //获取到HttpServletRequest + RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes(); + ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) requestAttributes; + HttpServletRequest request = servletRequestAttributes.getRequest(); + + String username = request.getParameter("username"); + + //获取当前用户角色的集合 + Set userRoles = CacheManager.USER_ROLE_MAP.get(username); + + //获取当前请求的方法的签名 + MethodSignature signature = (MethodSignature) joinPoint.getSignature(); + + //反射获取当前被调用的方法 + Method method = signature.getMethod(); + + //判断当前方法是否有hasRole注解 + //如果有,判断用户是否具有注解属性中要求的角色 + //如果没有hasRole注解,那么说明方法不需要判断用户的角色,可以匿名访问 + + HasRole hasRole = method.getDeclaredAnnotation(HasRole.class); + if (hasRole != null && (userRoles != null || !userRoles.contains(hasRole.value()))) { + throw new RuntimeException("用户没有访问的权限"); + } + + } +} diff --git a/src/test/java/com/cultural/heritage/aop/AopController.java b/src/test/java/com/cultural/heritage/aop/AopController.java new file mode 100644 index 0000000..313af66 --- /dev/null +++ b/src/test/java/com/cultural/heritage/aop/AopController.java @@ -0,0 +1,31 @@ +package com.cultural.heritage.aop; + +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/aop") +public class AopController { + + + //调用这个方法需要用户具有admin的角色 + @HasRole("admin") + @GetMapping("query1") + public String query1() { + return "query1 需要 admin 角色"; + } + + //调用这个方法需要用户具有user的角色 + @HasRole("user") + @GetMapping("query2") + public String query2() { + return "query2 需要 user 角色"; + } + + // 任何用户都可以访问 + @GetMapping("query3") + public String query3() { + return "query3 可以匿名访问"; + } +} diff --git a/src/test/java/com/cultural/heritage/aop/CacheManager.java b/src/test/java/com/cultural/heritage/aop/CacheManager.java new file mode 100644 index 0000000..9cef35c --- /dev/null +++ b/src/test/java/com/cultural/heritage/aop/CacheManager.java @@ -0,0 +1,22 @@ +package com.cultural.heritage.aop; + +import com.google.common.collect.Sets; + +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +public class CacheManager { + + public static final Map> USER_ROLE_MAP = new HashMap<>(); + + static { + //用户zhangsan具有user和admin两个角色 + Set roleSet1 = Sets.newHashSet("admin", "user"); + USER_ROLE_MAP.put("zhangsan", roleSet1); + + + Set roleSet2 = Sets.newHashSet("user"); + USER_ROLE_MAP.put("lisi", roleSet2); + } +} diff --git a/src/test/java/com/cultural/heritage/aop/HasRole.java b/src/test/java/com/cultural/heritage/aop/HasRole.java new file mode 100644 index 0000000..6f4f99b --- /dev/null +++ b/src/test/java/com/cultural/heritage/aop/HasRole.java @@ -0,0 +1,12 @@ +package com.cultural.heritage.aop; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +public @interface HasRole { + String value(); +}