侧边栏壁纸
博主头像
ZHD的小窝博主等级

行动起来,活在当下

  • 累计撰写 79 篇文章
  • 累计创建 53 个标签
  • 累计收到 1 条评论

目 录CONTENT

文章目录

Springboot 通过注解鉴权

江南的风
2018-06-21 / 0 评论 / 0 点赞 / 23 阅读 / 6167 字 / 正在检测是否收录...

Springboot 通过注解鉴权有两种方式: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 AuthRequired {
    String role() default ""; // 你可以定义角色或其他参数
}

AOP 方式

在有该注解的方法上进行切面编程,判断用户是否有这个接口的权限

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.ControllerAdvice;

import java.lang.reflect.Method;

@Aspect
@Component
public class AuthAspect {
    
    @Before("@annotation(AuthRequired)") // 拦截有 @AuthRequired 注解的方法
    public void checkAuth() throws Throwable {
        // 这里可以获取当前用户的角色
        String currentUserRole = getCurrentUserRole(); // 自己实现该方法获取当前用户的角色
        
        // 获取拦截的方法
        MethodSignature signature = (MethodSignature) ((org.aspectj.lang.JoinPoint) joinPoint).getSignature();
        Method method = signature.getMethod();
        
        AuthRequired authRequired = method.getAnnotation(AuthRequired.class);
        String requiredRole = authRequired.role();
        
        // 检查用户角色与方法要求的角色
        if (!currentUserRole.equals(requiredRole)) {
            throw new AccessDeniedException("权限不足"); // 抛出异常或返回错误响应
        }
    }

    private String getCurrentUserRole() {
        // 实现获取当前用户角色的逻辑
        // 这可能涉及到 SecurityContextHolder 或其他方式
        return "USER"; // 示例返回角色
    }
}

使用Interceptor方式

import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@Component
public class AuthInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        if (handler instanceof HandlerMethod) {
            HandlerMethod handlerMethod = (HandlerMethod) handler;
            AuthRequired authRequired = handlerMethod.getMethodAnnotation(AuthRequired.class);

            if (authRequired != null) {
                String requiredRole = authRequired.role();
                String currentUserRole = getCurrentUserRole(); // 自己实现该方法获取当前用户的角色

                // 检查用户角色与方法要求的角色
                if (!currentUserRole.equals(requiredRole)) {
                    sendUnauthorizedResponse(response);
                    return false; // 拦截请求
                }
            }
        }
        return true; // 继续处理请求
    }

    private String getCurrentUserRole() {
        // 实现获取当前用户角色的逻辑
        // 这部分代码通常涉及到 SecurityContextHolder 或者从请求中获取用户信息
        return "USER"; // 示例返回角色
    }

    private void sendUnauthorizedResponse(HttpServletResponse response) throws IOException {
        response.setContentType("application/json");
        response.setStatus(HttpServletResponse.SC_OK);
        String jsonResponse = "{\"code\":401,\"message\":\"未登录\",\"data\":null}";
        response.getWriter().write(jsonResponse);
    }
}

AOP和拦截器的区别

拦截器和 AOP(面向切面编程)是不同的概念,虽然它们在某些方面有相似之处,但它们的设计目的和应用场景是不同的。

拦截器

  • 定义:拦截器主要用于拦截特定的请求和响应,通常是处理 HTTP 请求的生命周期。它可以在请求到达 Controller 之前和响应返回之前,进行一些预处理或后处理。

  • 应用场景:拦截器常用于权限校验、日志记录、请求参数的统一处理等。它主要关注的是处理请求的全局行为。

  • 使用:在 Spring MVC 中,拦截器实现 HandlerInterceptor 接口,并在 WebMvcConfigurer 中注册。

AOP(面向切面编程)

  • 定义:AOP 是一种编程范式,用于将横切关注点(如日志、安全、事务管理等)从核心业务逻辑中分离出来。AOP 通过定义切面、切点和通知来实现这些功能。

  • 应用场景:AOP 常用于日志记录、异常处理、性能监控、事务管理等,它可以在方法调用的前后执行特定的逻辑。

  • 使用:在 Spring 中,AOP 通常通过注解(如 @Aspect, @Before, @After 等)实现,切面类会针对被指定的切点定义对应的通知。

对比

  1. 关注点

    • 拦截器主要面向 HTTP 请求的生命周期。

    • AOP 关注于方法的调用和相关行为,比如日志、事务等。

  2. 实现方式

    • 拦截器是通过实现 HandlerInterceptor 接口,关注于具体的请求和响应上下文。

    • AOP 是通过切面(Aspect)和通知(Advice)来实现的。

  3. 适用范围

    • 拦截器适用于 Web 应用程序的请求处理。

    • AOP 适用于任何 Java 方法的横切逻辑,不限于 Web 应用。

总结

尽管拦截器和 AOP 都能实现某种程度的横切关注点处理,但它们并不是同一种概念。你可以根据业务需求选择合适的工具和设计模式来实现所需的功能。

0

评论区