springboot借助aop和注解实现权限校验

我们用springboot做后台开发,难免会用到权限校验,比如查看当前用户是否合法,是否是管理员。而spring的面向切面的特效可以帮助我们很好的实现动态的权限校验。这里我们就用到的spring的aop。接下来就带领大家用aop和注解来快速的实现权限校验

一,在pom.xml里引入aop的类库。

<!--aop切面的使用-->

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-aop</artifactId>

</dependency>

二,自定义注解

package com.demo.permission;

import java.lang.annotation.Documented;

import java.lang.annotation.ElementType;

import java.lang.annotation.Retention;

import java.lang.annotation.RetentionPolicy;

import java.lang.annotation.Target;

/**

* Created by qcl on 2019/2/18

* desc:自定义权限管理注解

*/

@Target(ElementType.METHOD)

@Retention(RetentionPolicy.RUNTIME)

@Documented

public @interface Permission {

String authorities() default "我是默认值";

}

三,借助@Aspect实现切面

package com.demo.permission;

import org.aspectj.lang.ProceedingJoinPoint;

import org.aspectj.lang.annotation.Around;

import org.aspectj.lang.annotation.Aspect;

import org.aspectj.lang.annotation.Pointcut;

import org.aspectj.lang.reflect.MethodSignature;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Component;

import org.springframework.util.StringUtils;

import org.springframework.web.bind.annotation.ResponseBody;

import java.lang.reflect.Method;

import javax.security.auth.login.LoginException;

@Aspect

@Component

public class ControllerAspect {

private final static Logger logger = LoggerFactory.getLogger(ControllerAspect.class);

@Autowired

private UserService userService;

/**

* 定义切点

*/

@Pointcut("execution(public * com.demo.permission.controller.*.*(..))")

public void privilege() {

}

/**

* 权限环绕通知

*

* @param joinPoint

* @throws Throwable

*/

@ResponseBody

@Around("privilege()")

public Object isAccessMethod(ProceedingJoinPoint joinPoint) throws Throwable {

//获取访问目标方法

MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();

Method targetMethod = methodSignature.getMethod();

//得到方法的访问权限

final String methodAccess = AnnotationParse.privilegeParse(targetMethod);

//如果该方法上没有权限注解,直接调用目标方法

if (StringUtils.isEmpty(methodAccess)) {

return joinPoint.proceed();

} else {

//获取当前用户

Object[] args = joinPoint.getArgs();

if (args == null) {

throw new LoginException("参数错误");

}

String currentUser = args[0].toString();

logger.info("访问用户,{}", currentUser);

if (!userService.isAdmin(currentUser)) {

throw new LoginException("您不是管理员");

} else {

logger.info("您是管理员");

//是管理员时,才返回所需要的信息

return joinPoint.proceed();

}

}

}

}

四,定义一个简单的管理员名单

package com.demo.permission;

import org.springframework.stereotype.Service;

import java.util.Arrays;

/**

* Created by qcl on 2019/2/18

* desc:

*/

@Service

public class UserService {

private String[] admins = {"qiushi", "weixin", "xiaoshitou"};

//是否是管理员

boolean isAdmin(String name) {

return Arrays.asList(admins).contains(name);

}

}

这里简单起见,就用一个本地的数组来维护管理员,正常应该是把管理员相关信息存到数据库里。

五,获取用户名,@Permission注解进行权限校验

package com.demo.permission.controller;

import com.demo.permission.Permission;

import org.springframework.web.bind.annotation.GetMapping;

import org.springframework.web.bind.annotation.RequestParam;

import org.springframework.web.bind.annotation.RestController;

import lombok.extern.slf4j.Slf4j;

/**

* Created by qcl on 2019/2/18

* desc:

*/

@RestController

@Slf4j

public class UserController {

//带注解,需要校验权限

@GetMapping(value = "/user")

@Permission

public String user(@RequestParam String name) {

return "你好:"+name+",您有管理权限";

}

//不带注解,不需要安全校验

@GetMapping(value = "/user2")

public String user2(@RequestParam String name) {

return "不用检查权限,直接返回的数据";

}

}

然后通过url请求来验证结果

1,http://localhost:8080/user?name=qcl2

由于qcl2不在管理员数组里面,所以抛出异常

2,http://localhost:8080/user?name=qiushi

qiushi是管理员,所以用户邱石可以访问到数据。

3,http://localhost:8080/user2?name=qiushi

由于接口/user2没有添加 @Permission注解,所以不用做安全校验,直接返回数据。

到这里我们就轻松实现通过 @Permission一个注解,就可以实现数据的安全校验。

有任何关于编程的问题都可以私信我,我看到后会及时解答。

码农一枚,非著名全栈开发人员。分享自己的一些经验,学习心得,希望后来人少走弯路,少填坑

相关文章

这篇文章主要介绍了spring的事务传播属性REQUIRED_NESTED的原...
今天小编给大家分享的是一文解析spring中事务的传播机制,相...
这篇文章主要介绍了SpringCloudAlibaba和SpringCloud有什么区...
本篇文章和大家了解一下SpringCloud整合XXL-Job的几个步骤。...
本篇文章和大家了解一下Spring延迟初始化会遇到什么问题。有...
这篇文章主要介绍了怎么使用Spring提供的不同缓存注解实现缓...