当前位置: 首页 > 图灵资讯 > 技术篇> 使用AOP来进行权限鉴定

使用AOP来进行权限鉴定

来源:图灵教育
时间:2023-06-11 09:12:56

  • AOP是什么?

aop是面向切面的编程,是oop的补充,可以统一管理某些事务,如(权限验证、日志、事务管理),通过配置提取共同需求的代码,声明这些代码何时调用,无需修改原始代码。

  • 为什么要进行权限鉴定?

当我们开发一个系统时,我们将对不同的用户有不同的操作权限,如管理员和普通用户。普通用户不能调用一些只能由管理员调用的接口。那么系统的安全性就很低了。一般来说,如果需要提高系统的安全性,则需要权限验证。

  • 为什么要使用AOP进行权限鉴定?

或者我们在aop的解释中说,aop可以在不修改原始代码的情况下,将共性代码抽离,并通过配置声明何时调用。

  • 如何使用AOP进行权限鉴定?

pom.aop依赖于xml导入aop

<dependency>            <groupId>org.springframework.boot</groupId>            <artifactId>spring-boot-starter-aop</artifactId>        </dependency>

这次我们通过注释来实现aop

首先定义一个权限验证解释

AuthCheck

package com.xc.project.annotation;import java.lang.annotation.ElementType;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;/** * 权限校验 * @author xc */// 这个注释意味着我们可以在哪些地方使用自定义的注释,ElementType.METHOD表示可以使用该方法@Target(ElementType.METHOD)// 表示注释的生命周期在运行过程中是有效的,因此,可以通过反射获得@Retention(RetentionPolicy.RUNTIME)public @interface AuthCheck {    /**     * 必须有一定的权限     *     * @return     */    String mustRole() default "";}

定义权限为UserRoleenum

package com.xc.project.model.enums;import org.apache.commons.lang3.ObjectUtils;import java.util.Arrays;import java.util.List;import java.util.stream.Collectors;/** * 枚举用户角色 * @author xc */public enum UserRoleEnum {    USER(用户”, "user"),    ADMIN(管理员”, "admin"),    BAN(“被封号”, "ban");    private final String text;    private final String value;    UserRoleEnum(String text, String value) {        this.text = text;        this.value = value;    }    /**     * 获取值列表     *     * @return     */    public static List<String> getValues() {        return Arrays.stream(values()).map(item -> item.value).collect(Collectors.toList());    }    /**     * 根据 value 获取枚举     *     * @param value     * @return     */    public static UserRoleEnum getEnumByValue(String value) {        if (ObjectUtils.isEmpty(value)) {            return null;        }        for (UserRoleEnum anEnum : UserRoleEnum.values()) {            if (anEnum.value.equals(value)) {                return anEnum;            }        }        return null;    }    public String getValue() {        return value;    }    public String getText() {        return text;    }}

重新定义权限验证aop类

AuthInterceptor

package com.xc.project.aop;import com.xc.project.annotation.AuthCheck;import com.xc.project.common.ErrorCode;import com.xc.project.exception.BusinessException;import com.xc.project.model.enums.UserRoleEnum;import com.xc.project.service.UserService;import com.xc.xcapicommon.model.entity.User;import org.apache.commons.lang3.StringUtils;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;import javax.annotation.Resource;import javax.servlet.http.HttpServletRequest;/** * 权限校验 AOP * @author xc */// 用于定义一个切面。它将通知编织到目标对象的指定连接点@Aspect// 注册为spring管理的组件@Componentpublic class AuthInterceptor {    @Resource    private UserService userService;    /**     * 执行拦截     *     * @param joinPoint     * @param authCheck     * @return     */    // 注解Authcheck调用前后完成权限鉴定    @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.getEnumByValue(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);            }            // 必须有管理员的权限            if (UserRoleEnum.ADMIN.equals(mustUserRoleEnum)) {                if (!mustRole.equals(userRole)) {                    throw new BusinessException(ErrorCode.NO_AUTH_ERROR);                }            }        }        // 通过权限验证,放行        return joinPoint.proceed();    }}