目 录CONTENT

文章目录

基于SpringBoot的自定义注解 实现权限控制

Sir丶雨轩
2020-06-09 / 0 评论 / 2 点赞 / 457 阅读 / 0 字 / 正在检测是否收录...

应一位朋友邀请写下此篇文章,不足之处请多多指教

首先我们定义一个注解 传入一个参数(传递权限的编码)

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * @author Sir丶雨轩
 * @date 2019/06/09
 */
@Target({ ElementType.METHOD,ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
public @interface Auth {
    
    /**
     * 权限校验编码
     * @return 校验编码
     */
    String value() default "";

}

假设我们的项目是拥有web环境的项目 本demo的权限缓存至session中,如果是纯api项目可以将权限缓存至redis或其他缓存中

    /**
     * 模拟登录方法
     */
    public void login(){

        // 我们在这里模拟一个登录方法,具体请修改为业务代码

        // 获取权限列表 存入session中
        List<String> permissionList = new ArrayList<>();

        // 获取request对象
        HttpServletRequest request = null;

        // 缓存权限列表
        request.getSession().setAttribute("permissionList",permissionList);

    }

然后我们的重点来了,写一个拦截器使自定义注解开始工作

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.km66.repair.support.auth.Auth;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
import java.lang.reflect.Method;
import java.nio.charset.Charset;
import java.util.List;

/**
 * @author Sir丶雨轩
 * @date 2019/06/09
 */
@Slf4j
public class DemoAuthInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {

        HandlerMethod handlerMethod = null;

        // 如果请求的不是方法 则直接跳过当前拦截器
        if (!(handler instanceof HandlerMethod)) {
            return true;
        }
        handlerMethod = (HandlerMethod) handler;

        // 获取当前请求的方法
        Method method = handlerMethod.getMethod();

        // 获取方法上注解
        Auth auth = method.getAnnotation(Auth.class);

        // 如果方法没有注解,则去类上去获取 如果方法有则使用方法的注解,方法的注解优先级高于类的注解
        if (auth == null) {
            auth = handlerMethod.getBeanType().getAnnotation(Auth.class);
        }

        // 如果没有Auth 注解 则跳过鉴权
        if (auth == null) {
            return true;
        }

        String authorityCode = auth.value();

        // 如果不包含权限编码,则表示这个接口登录就可以访问
        if (StrUtil.isBlank(authorityCode)) {

            Object user = request.getSession().getAttribute("user");

            // 用户还没有登录
            if (user == null) {
                noPermission(request, response);
                return false;
            }

            // 当前用户已经登录 完成鉴权流程
            return true;
        }

        List<String> permissionList = (List<String>) request.getSession().getAttribute("permissionList");

        assert permissionList != null;

        // 当前用户没有这个地址的访问权限
        if (!permissionList.contains(authorityCode)) {
            noPermission(request, response);
            return false;
        }

        return true;

    }

    /**
     * 没有权限的处理方式
     *
     * @param request  HttpServletRequest
     * @param response HttpServletResponse
     */
    public void noPermission(HttpServletRequest request, HttpServletResponse response) {
        if (isAjax(request)) {
            try {
                OutputStream out = response.getOutputStream();

                JSONObject errRet = new JSONObject();

                errRet.put("code", 1);
                errRet.put("msg", "您没有访问权限");

                out.write(errRet.toJSONString().getBytes(Charset.defaultCharset()));
                out.flush();
                out.close();

            } catch (IOException e) {
                log.error("error", e);
            }
        } else {
            try {
                response.sendRedirect("error/noPermission");
            } catch (IOException e) {
                log.error("error", e);
            }

        }
    }

    /**
     * 判断请求是否为ajax请求
     *
     * @param request HttpServletRequest
     * @return Boolean
     */
    public boolean isAjax(HttpServletRequest request) {
        return request.getHeader("x-requested-with") != null
                && "XMLHttpRequest".equalsIgnoreCase(request.getHeader("x-requested-with"));
    }

}

然后最后一步,我们把拦截器加到配置中就可以了

/**
 *
 * @author Sir丶雨轩
 * @date 2020-06-09
 */
@Configuration
public class AppConfig implements WebMvcConfigurer {


    @Override
    public void addInterceptors(InterceptorRegistry registry) {

        // 权限校验拦截器,判断登录状态
        registry.addInterceptor(new DemoAuthInterceptor());

    }


}
2
广告 广告

评论区