springboot接口访问权限AOP实现
场景
现在有个系统,很多接口只需要登录就可以访问,但是有些接口需要授予并验证权限。如果用注解controller的方式控制接口的权限呢?
1、注解声明代码
这个注解是要装饰在controller接口上的。
按照一般权限的设计,有用户(user)-角色(role)-权限(permission)三种实体,他们之间都是多对多关系。
注解声明的时候,可以配置要验证的角色(role)或权限(menu)。所以我这里有两个变量。
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target; /**
* @Author: ivan
* @Description:
* @Date: Created in 19:58 18/5/28
* @Modified By:
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Authentication {
long[] role() default {};
long[] menu() default {}; }
2、Authentication权限验证Advice
我们以验证角色为例。
第一步,先从controller参数的request cookie里拿到用户登录信息,获取userId,我这里是card。
第二步,查询用户角色数据库,获取该user拥有哪些权限。
第三部,跟@Authentication里配置的权限进行比较,校验成功返回数据,校验失败返回错误码。
使用localthread记录了权限验证处理时间,用来进行监控。
/**
* @Author: ivan
* @Description:
* @Date: Created in 20:00 18/5/28
* @Modified By:
*/
@Aspect
@Component
@Order(-10)
public class AuthenticationAspect { private static Logger logger = LoggerFactory.getLogger(AuthenticationAspect.class); @Autowired
private AuthDao authDao; ThreadLocal<Long> beginTime = new ThreadLocal<Long>(); @Pointcut("@annotation(authentication)")
public void AuthenticationService(Authentication authentication) {
} @Around("AuthenticationService(authentication)")
public Object doAround(ProceedingJoinPoint joinPoint, Authentication authentication) throws Throwable{
beginTime.set(System.currentTimeMillis());
String card = null;
List<Long> roleList = new ArrayList<>();
for (Object arg : joinPoint.getArgs()) {
if (arg != null && arg.getClass() == RequestFacade.class) {
RequestFacade request = (RequestFacade) arg;
card = CookieUtils.getCardFromCookie(request);
if (StringUtils.isEmpty(card)) {
return JsonResult.buildFailResult(-1, 1000, "权限验证未通过", null);
}
List<Role> roles = authDao.getRolesByCard(card);
for (Role role : roles) {
roleList.add(role.getId());
}
break;
}
}
logger.info("[authentication] user={}, roles={}", card, roleList);
long[] aims = authentication.role();
boolean isPass = false;
for (long aim : aims) {
if (roleList.contains(aim)) {
isPass = true;
}
}
if (isPass) {
logger.info("[authentication] authentication pass, cost time: {}", System.currentTimeMillis() - beginTime.get());
return joinPoint.proceed();
} else {
beginTime.set(System.currentTimeMillis());
logger.info("[authentication] authentication reject, cost time: {}", System.currentTimeMillis() - beginTime.get());
return JsonResult.buildFailResult(-1, 1000, "权限验证未通过", null);
} } }
3、使用方法
1、Authentication直接装饰在controller接口上,参数是role={2},即用户拥有2这个角色的时候拥有访问这个接口的权限。
2、controller第一个参数要是HttpServletRequest request,不然上面从request里面拿用户信息会失败。(这个地方确实不方便)
/**
* 审核接口
*
* @author ivan
* @date 2018/08/02
*/
@Controller
@RequestMapping("/audit")
public class AuditController {
private static final Logger LOGGER = LoggerFactory.getLogger(AuditController.class);
@Resource
private AuditService auditService; @ResponseBody
@PostMapping(value = "/review")
@Authentication(role = {2})
public JsonResult review(HttpServletRequest request, @RequestBody AduitDTO aduitDTO) {
LOGGER.info("[aduitDTO] video service aduitDTO={}" + aduitDTO);
UserInfo userInfo = CookieUtils.getLoginInfoFromCookie(request);
aduitDTO.setCard(userInfo.getCard());
int status = 0;
aduitDTO.setAuditor(userInfo.getCard());
JsonResult jsonResult = null;
if (ListEnum.ZERO.toString().equals(aduitDTO.getType())) {
if (null != aduitDTO.getStatus() && ListEnum.ONE.toString().equals(aduitDTO.getStatus())) {
status = auditService.review(aduitDTO);
jsonResult = JsonResult.buildSuccessResult("审核通过");
}
if (null != aduitDTO.getStatus() && ListEnum.TWO.toString().equals(aduitDTO.getStatus())) {
if(StringUtils.isEmpty(aduitDTO.getReason())){
return JsonResult.buildFailResult(1, 102, "请添加不通过原因!", null);
}
aduitDTO.setAuditTime(DateUtils.parseDateToStr(new Date() ,"yyyy-MM-dd HH:mm:ss"));
status = auditService.updateAduit(aduitDTO);
jsonResult = JsonResult.buildSuccessResult("审核不通过");
}
} return jsonResult;
}
}
springboot接口访问权限AOP实现的更多相关文章
- go 基础 结构体 接口 访问权限
package School type SchoolModel struct { Name string Address string StudentCount int Is985 bool } ty ...
- Java编程思想学习(四) 访问权限
几种访问权限修饰词 public,protected,private,friendly(Java中并无该修饰词,即包访问权限,不提供任何访问修饰词) 使用时,放置在类中成员(域或方法)的定义之前的,仅 ...
- thinkinginjava学习笔记05_访问权限
Java中访问权限等级从大到小依次为:public.protected.包访问权限(没有关键词).private: 以包访问权限为界限,public.protected分别可以被任意对象和继承的对象访 ...
- 初读"Thinking in Java"读书笔记之第六章 --- 访问权限控制
包:库单元 包内包含有一组类,他们在单一的名字空间下被组织在一起. 通过import ***.***.*可以将某个包下的所有类导入到当前文件中. 每个Java源文件最多只能有一个public类,且名称 ...
- Chapter6_访问权限控制_访问权限修饰词
Java中有四种访问权限,public,private,protected和包访问权限,它们是置于类中每一个成员之前的定义,无论是一个域还是一个方法,下面一一介绍. 一.包访问权限 如果不提供任何访问 ...
- ThinkingInJava 学习 之 0000005 访问权限控制
1. 包:库单元 1. 代码组织 2. 创建独一无二的包名 3. 定制工具库 4. 用import改变行为 5. 对使用包的忠告 2. Java访问权限修饰词 1. 包访问权限 2. public : ...
- Java访问权限控制
访问权限控制 java提供了访问权限修饰词,以供类库开发人员向客户端程序员指明哪些是可用的,哪些是不可用的.访问权限控制的等级,从最大权限到最小权限依次是:public.prote ...
- Java之路(五) 访问权限控制
在Java中,所有事物都具有某种形式的访问权限控制. 访问权限的控制等级从最大到最小依次为:public,protected,包访问权限(无关键词)和private. public,protected ...
- Java编程思想学习笔记——访问权限修饰词
几种访问权限修饰词 public,protected,private,friendly(Java中并无该修饰词,即包访问权限,不提供任何访问修饰词) 使用时,放置在类中成员(域或方法)的定义之前的,仅 ...
随机推荐
- Education CodeForces Round 63 Div.2
A. Reverse a Substring 代码: #include <bits/stdc++.h> using namespace std; int N; string s; int ...
- centos下安装Vmware-tools时出现的问题
今天装了centos,想共享一个文件,需要安装Vmware-tools. 正常的步骤: 安装Vmware-tools 1.挂载VMwareTools光驱.虚拟机选项栏中选[虚拟机]-->[安装v ...
- mysql-笔记-控制语句/string方法
1 case case value when [compare_value] then result [when[compare_value] then result....] [else resul ...
- Auto Layout Masonry
1. Auto layout 1.1 NSLayoutConstraint 1.1.1 约束类 ios6.0可用 为了更好的适配各个尺寸 1.1.2 constraintWithItem:attrib ...
- codeforces960G. Bandit Blues
题目链接:codeforces960G 来看看三倍经验:hdu4372 luogu4609 某蒟蒻的关于第一类斯特林数的一点理解QAQ:https://www.cnblogs.com/zhou2003 ...
- [SDOI2017]苹果树
题目描述 https://www.luogu.org/problemnew/show/P3780 题解 一道思路巧妙的背包题. 对于那个奇怪的限制,我们对此稍加分析就可以发现它最后选择的区域是一个包含 ...
- 【洛谷P1090 合并果子】
题目描述 在一个果园里,多多已经将所有的果子打了下来,而且按果子的不同种类分成了不同的堆.多多决定把所有的果子合成一堆. 每一次合并,多多可以把两堆果子合并到一起,消耗的体力等于两堆果子的重量之和.可 ...
- ORA-00923: FROM keyword not found where expected(单双引号)
1.前提 在学习oracel的过程中遇到的一个关于单双引号的问题 备注一下 2.学习过程中创建表语句是这样的 create table DEPT_DML --部门表( DEPT_NO NUMBER(8 ...
- 构建之法助教园地第一次作业--点评<西北师范大学|李晓婷>
一 博客点评 第一次作业--准备篇:https://www.cnblogs.com/Mookiepiece/p/10464606.html#4192515 点评内容: 首先,你对电脑很感兴趣,兴趣就是 ...
- 01-oracle学习环境配置
1.安装oracle与SQL Developer oracle10g安装教程 2.创建表空间以及用户 表空间是存储数据文件的容器,由数据文件组成,数据库的所有系统数据和用户数据都必须存储在数据文件中. ...