前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >基于自定义注解手写权限控制

基于自定义注解手写权限控制

原创
作者头像
code-x
修改2022-08-17 11:50:30
3850
修改2022-08-17 11:50:30
举报
文章被收录于专栏:code-x

方法一: AOP

方法二: 拦截器

项目结构
1.png
1.png
项目依赖
代码语言:html
复制
<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-aop</artifactId>
    </dependency>
</dependencies>
配置
代码语言:yaml
复制
spring:
  aop:
    proxy-target-class: true
定义注解
代码语言:java
复制
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Role {
    /**
     * 角色名 默认值:游客
     * @return
     */
    String value() default "NORMAL";
}
控制层
代码语言:java
复制
package com.github.controller;


import com.github.annotations.Role;
import com.github.entity.Result;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpSession;


@RestController
@RequestMapping("/user")
public class UserController {

    @Autowired
    private HttpSession session;

    /**
     * 登录
     *
     * @param username
     * @param password
     */
    @Role
    @PostMapping("/login")
    public Result login(String username, String password) {

        if ("admin".equals(username)) {
            session.setAttribute(username, "ADMIN");
        } else {
            session.setAttribute(username, "USER");
        }

        return Result.resultFactory("登录成功", 200);
    }

    @Role("USER")
    @GetMapping("/user")
    public Result user() {
        return Result.resultFactory("访问成功", 200, "USER权限");
    }

    @Role("ADMIN")
    @GetMapping("/admin")
    public Result admin() {
        return Result.resultFactory("访问成功", 200, "ADMIN权限");
    }


}
响应信息类
代码语言:java
复制
package com.github.entity;

import com.fasterxml.jackson.annotation.JsonInclude;

import java.util.Date;

@JsonInclude(JsonInclude.Include.NON_NULL)
public class Result {
    private Date timestamp;
    private Integer status;
    private String error;
    private String message;
    private String path;
    private Object data;

    private Result() {
    }

    @Override
    public String toString() {
        return "Result{" +
                "timestamp=" + timestamp +
                ", status=" + status +
                ", error='" + error + '\'' +
                ", message='" + message + '\'' +
                ", path='" + path + '\'' +
                ", data=" + data +
                '}';
    }

    getter&setter...

    public static Result resultFactory(String message, Integer status, Object data) {
        Result result = new Result();
        result.setTimestamp(new Date());
        result.setMessage(message);
        result.setStatus(status);
        result.setData(data);
        return result;
    }

    public static Result resultFactory(String message, Integer status) {
        Result result = new Result();
        result.setTimestamp(new Date());
        result.setMessage(message);
        result.setStatus(status);
        return result;
    }
}
切面类
代码语言:java
复制
package com.github.aop;


import com.github.annotations.Role;
import com.github.controller.UserController;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
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.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.lang.reflect.Method;


@Aspect
@Component
public class UserAspect {

    @Autowired
    private HttpSession session;

    @Autowired
    private HttpServletRequest request;

    @Pointcut("execution(public * com.github.controller.*.*(..))")
    public void LogAspect() {
        System.out.println("切入点");
    }

    @Before("LogAspect()")
    public void doBefore(JoinPoint joinPoint) {
        Signature signature = joinPoint.getSignature();
        MethodSignature methodSignature = (MethodSignature)signature;
        Method targetMethod = methodSignature.getMethod();
        Role roleAnnotation = targetMethod.getAnnotation(Role.class);
        String nameKey = request.getHeader("name");
        String role = (String)session.getAttribute(nameKey);

        if (roleAnnotation.value().equals("NORMAL")) {
            System.out.println("游客访问");
        } else if (roleAnnotation.value().equals(role)) {
            System.out.println("权限校验通过");
        } else {
            throw new RuntimeException("权限不足");
        }

    }

}
启动测试
  • 登录
2.png
2.png
  • 访问user接口
3.png
3.png
  • 访问admin接口
4.png
4.png
  • 用admin登录后再次访问admin接口
5.png
5.png
但要注意此项目定义的aop发生在SpringMVC的参数注入之后, 即前端传入的json参数被转为java对象后, 才会执行aop内的逻辑, 在一些场景下并不适用

方法二:

使用org.springframework.web.servlet.HandlerInterceptor这个接口

实现这个方法

代码语言:txt
复制
boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception

其中handler参数可以强转为org.springframework.web.method.HandlerMethod, 该对象提供这个方法

代码语言:txt
复制
Role role = ((HandlerMethod) handler).getMethodAnnotation(Role.class);

也能实现权限判断

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 项目结构
  • 项目依赖
  • 配置
  • 定义注解
  • 控制层
  • 响应信息类
  • 切面类
  • 启动测试
  • 但要注意此项目定义的aop发生在SpringMVC的参数注入之后, 即前端传入的json参数被转为java对象后, 才会执行aop内的逻辑, 在一些场景下并不适用
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档