mirror of
https://gitee.com/dromara/sa-token.git
synced 2025-09-19 10:08:07 +08:00
v1.11.0 新特性:AOP注解鉴权
This commit is contained in:
12
sa-token-aop/.gitignore
vendored
Normal file
12
sa-token-aop/.gitignore
vendored
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
target/
|
||||||
|
|
||||||
|
node_modules/
|
||||||
|
bin/
|
||||||
|
.settings/
|
||||||
|
unpackage/
|
||||||
|
.classpath
|
||||||
|
.project
|
||||||
|
|
||||||
|
.factorypath
|
||||||
|
|
||||||
|
.idea/
|
35
sa-token-aop/pom.xml
Normal file
35
sa-token-aop/pom.xml
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
<?xml version='1.0' encoding='utf-8'?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<parent>
|
||||||
|
<groupId>cn.dev33</groupId>
|
||||||
|
<artifactId>sa-token-parent</artifactId>
|
||||||
|
<version>1.10.0</version>
|
||||||
|
</parent>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
|
<name>sa-token-aop</name>
|
||||||
|
<artifactId>sa-token-aop</artifactId>
|
||||||
|
<description>sa-token authentication by spring-aop</description>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<!-- sa-token-spring-boot-starter -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>cn.dev33</groupId>
|
||||||
|
<artifactId>sa-token-spring-boot-starter</artifactId>
|
||||||
|
<version>1.10.0</version>
|
||||||
|
</dependency>
|
||||||
|
<!-- spring-boot-starter-aop -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-aop</artifactId>
|
||||||
|
<version>2.0.0.RELEASE</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</project>
|
@@ -0,0 +1,67 @@
|
|||||||
|
package cn.dev33.satoken.aop;
|
||||||
|
|
||||||
|
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.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import cn.dev33.satoken.stp.StpLogic;
|
||||||
|
import cn.dev33.satoken.stp.StpUtil;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* sa-token 基于 Spring Aop 的注解鉴权
|
||||||
|
* @author kong
|
||||||
|
*/
|
||||||
|
@Aspect
|
||||||
|
@Component
|
||||||
|
public class SaCheckAspect {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 底层的 StpLogic 对象
|
||||||
|
*/
|
||||||
|
public StpLogic stpLogic = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建,并指定一个默认的 StpLogic
|
||||||
|
*/
|
||||||
|
public SaCheckAspect() {
|
||||||
|
this.stpLogic = StpUtil.stpLogic;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 定义AOP签名 --> (切入所有使用sa-token鉴权注解的方法)
|
||||||
|
*/
|
||||||
|
public static final String POINTCUT_SIGN = "@within(cn.dev33.satoken.annotation.SaCheckLogin) || @annotation(cn.dev33.satoken.annotation.SaCheckLogin) || "
|
||||||
|
+ "@within(cn.dev33.satoken.annotation.SaCheckRole) || @annotation(cn.dev33.satoken.annotation.SaCheckRole) || "
|
||||||
|
+ "@within(cn.dev33.satoken.annotation.SaCheckPermission) || @annotation(cn.dev33.satoken.annotation.SaCheckPermission)";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 声明AOP签名
|
||||||
|
*/
|
||||||
|
@Pointcut(POINTCUT_SIGN)
|
||||||
|
public void pointcut() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 环绕切入
|
||||||
|
* @param joinPoint 切面对象
|
||||||
|
* @return 底层方法执行后的返回值
|
||||||
|
* @throws Throwable
|
||||||
|
*/
|
||||||
|
@Around("pointcut()")
|
||||||
|
public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
|
||||||
|
// 注解鉴权
|
||||||
|
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
|
||||||
|
stpLogic.checkMethodAnnotation(signature.getMethod());
|
||||||
|
try {
|
||||||
|
// 执行原有逻辑
|
||||||
|
Object obj = joinPoint.proceed();
|
||||||
|
return obj;
|
||||||
|
} catch (Throwable e) {
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -0,0 +1 @@
|
|||||||
|
org.springframework.boot.autoconfigure.EnableAutoConfiguration=cn.dev33.satoken.aop.SaCheckAspect
|
@@ -1,5 +1,6 @@
|
|||||||
package cn.dev33.satoken.stp;
|
package cn.dev33.satoken.stp;
|
||||||
|
|
||||||
|
import java.lang.reflect.Method;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -9,6 +10,10 @@ import javax.servlet.http.Cookie;
|
|||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
import cn.dev33.satoken.SaTokenManager;
|
import cn.dev33.satoken.SaTokenManager;
|
||||||
|
import cn.dev33.satoken.annotation.SaCheckLogin;
|
||||||
|
import cn.dev33.satoken.annotation.SaCheckPermission;
|
||||||
|
import cn.dev33.satoken.annotation.SaCheckRole;
|
||||||
|
import cn.dev33.satoken.annotation.SaMode;
|
||||||
import cn.dev33.satoken.config.SaTokenConfig;
|
import cn.dev33.satoken.config.SaTokenConfig;
|
||||||
import cn.dev33.satoken.dao.SaTokenDao;
|
import cn.dev33.satoken.dao.SaTokenDao;
|
||||||
import cn.dev33.satoken.exception.NotLoginException;
|
import cn.dev33.satoken.exception.NotLoginException;
|
||||||
@@ -1041,8 +1046,66 @@ public class StpLogic {
|
|||||||
return SaTokenManager.getConfig();
|
return SaTokenManager.getConfig();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// =================== 注解鉴权 ===================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 对一个Method对象进行注解检查(注解鉴权内部实现)
|
||||||
|
* @param method Method对象
|
||||||
|
*/
|
||||||
|
public void checkMethodAnnotation(Method method) {
|
||||||
|
|
||||||
|
// ----------- 验证登录
|
||||||
|
if(method.isAnnotationPresent(SaCheckLogin.class) || method.getDeclaringClass().isAnnotationPresent(SaCheckLogin.class)) {
|
||||||
|
this.checkLogin();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------- 验证角色
|
||||||
|
// 验证方法上的
|
||||||
|
SaCheckRole scr = method.getAnnotation(SaCheckRole.class);
|
||||||
|
if(scr != null) {
|
||||||
|
String[] roleArray = scr.value();
|
||||||
|
if(scr.mode() == SaMode.AND) {
|
||||||
|
this.checkRoleAnd(roleArray);
|
||||||
|
} else {
|
||||||
|
this.checkRoleOr(roleArray);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 验证类上的
|
||||||
|
scr = method.getDeclaringClass().getAnnotation(SaCheckRole.class);
|
||||||
|
if(scr != null) {
|
||||||
|
String[] roleArray = scr.value();
|
||||||
|
if(scr.mode() == SaMode.AND) {
|
||||||
|
this.checkRoleAnd(roleArray);
|
||||||
|
} else {
|
||||||
|
this.checkRoleOr(roleArray);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------- 验证权限
|
||||||
|
// 验证方法上的
|
||||||
|
SaCheckPermission scp = method.getAnnotation(SaCheckPermission.class);
|
||||||
|
if(scp != null) {
|
||||||
|
String[] permissionArray = scp.value();
|
||||||
|
if(scp.mode() == SaMode.AND) {
|
||||||
|
this.checkPermissionAnd(permissionArray);
|
||||||
|
} else {
|
||||||
|
this.checkPermissionOr(permissionArray);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 验证类上的
|
||||||
|
scp = method.getDeclaringClass().getAnnotation(SaCheckPermission.class);
|
||||||
|
if(scp != null) {
|
||||||
|
String[] permissionArray = scp.value();
|
||||||
|
if(scp.mode() == SaMode.AND) {
|
||||||
|
this.checkPermissionAnd(permissionArray);
|
||||||
|
} else {
|
||||||
|
this.checkPermissionOr(permissionArray);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 验证通过
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@@ -51,6 +51,13 @@
|
|||||||
<groupId>org.apache.commons</groupId>
|
<groupId>org.apache.commons</groupId>
|
||||||
<artifactId>commons-pool2</artifactId>
|
<artifactId>commons-pool2</artifactId>
|
||||||
</dependency> -->
|
</dependency> -->
|
||||||
|
|
||||||
|
<!-- sa-token整合SpringAop实现注解鉴权 -->
|
||||||
|
<!-- <dependency>
|
||||||
|
<groupId>cn.dev33</groupId>
|
||||||
|
<artifactId>sa-token-aop</artifactId>
|
||||||
|
<version>1.10.0</version>
|
||||||
|
</dependency> -->
|
||||||
|
|
||||||
<!-- @ConfigurationProperties -->
|
<!-- @ConfigurationProperties -->
|
||||||
<dependency>
|
<dependency>
|
||||||
|
@@ -3,6 +3,7 @@ package com.pj.test;
|
|||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestParam;
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
@@ -218,7 +219,19 @@ public class TestController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// 测试 浏览器访问: http://localhost:8081/test/test
|
@Autowired
|
||||||
|
TestService TestService;
|
||||||
|
|
||||||
|
// 测试AOP注解鉴权: http://localhost:8081/test/testAOP
|
||||||
|
@RequestMapping("testAOP")
|
||||||
|
public AjaxJson testAOP() {
|
||||||
|
System.out.println("testAOP");
|
||||||
|
TestService.getList();
|
||||||
|
return AjaxJson.getSuccess();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 测试 浏览器访问: http://localhost:8081/test/test
|
||||||
@RequestMapping("test")
|
@RequestMapping("test")
|
||||||
public AjaxJson test() {
|
public AjaxJson test() {
|
||||||
StpUtil.getTokenSession().logout();
|
StpUtil.getTokenSession().logout();
|
||||||
|
@@ -0,0 +1,26 @@
|
|||||||
|
package com.pj.test;
|
||||||
|
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import cn.dev33.satoken.annotation.SaCheckLogin;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用来测试AOP注解鉴权
|
||||||
|
* @author kong
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
//@SaCheckLogin
|
||||||
|
public class TestService {
|
||||||
|
|
||||||
|
@SaCheckLogin
|
||||||
|
public List<String> getList() {
|
||||||
|
System.out.println("getList");
|
||||||
|
return new ArrayList<String>();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -2,11 +2,11 @@
|
|||||||
<html lang="zh">
|
<html lang="zh">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<title>sa-token 官方文档</title>
|
<title>sa-token</title>
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
|
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
|
||||||
<meta name="description" content="Description">
|
<meta name="description" content="Description">
|
||||||
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
|
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
|
||||||
<meta name="keywords" content="sa-token|sa-token框架|sa-token文档|sa-token在线文档|权限认证框架">
|
<meta name="keywords" content="sa-token|sa-token框架|sa-token文档|sa-token在线文档|sa-token官方文档|权限认证框架">
|
||||||
<meta name="description" content="sa-token是一个JavaWeb权限认证框架,功能全面,上手简单,登录验证、权限验证、Session会话、踢人下线、集成Redis、前后台分离、模拟他人账号、多账号体系、注解式鉴权、花式token、自动续签、同端互斥登录、会话治理、Spring集成...,零配置开箱即用,覆盖所有应用场景,你所需要的功能,这里都有">
|
<meta name="description" content="sa-token是一个JavaWeb权限认证框架,功能全面,上手简单,登录验证、权限验证、Session会话、踢人下线、集成Redis、前后台分离、模拟他人账号、多账号体系、注解式鉴权、花式token、自动续签、同端互斥登录、会话治理、Spring集成...,零配置开箱即用,覆盖所有应用场景,你所需要的功能,这里都有">
|
||||||
<link rel="stylesheet" href="https://unpkg.zhimg.com/docsify@4.11.3/lib/themes/vue.css">
|
<link rel="stylesheet" href="https://unpkg.zhimg.com/docsify@4.11.3/lib/themes/vue.css">
|
||||||
<link rel="stylesheet" href="./lib/index.css">
|
<link rel="stylesheet" href="./lib/index.css">
|
||||||
|
@@ -1,15 +1,13 @@
|
|||||||
package cn.dev33.satoken.interceptor;
|
package cn.dev33.satoken.interceptor;
|
||||||
|
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
import org.springframework.web.method.HandlerMethod;
|
import org.springframework.web.method.HandlerMethod;
|
||||||
import org.springframework.web.servlet.HandlerInterceptor;
|
import org.springframework.web.servlet.HandlerInterceptor;
|
||||||
|
|
||||||
import cn.dev33.satoken.annotation.SaCheckLogin;
|
|
||||||
import cn.dev33.satoken.annotation.SaCheckPermission;
|
|
||||||
import cn.dev33.satoken.annotation.SaCheckRole;
|
|
||||||
import cn.dev33.satoken.annotation.SaMode;
|
|
||||||
import cn.dev33.satoken.stp.StpLogic;
|
import cn.dev33.satoken.stp.StpLogic;
|
||||||
import cn.dev33.satoken.stp.StpUtil;
|
import cn.dev33.satoken.stp.StpUtil;
|
||||||
|
|
||||||
@@ -52,56 +50,10 @@ public class SaCheckInterceptor implements HandlerInterceptor {
|
|||||||
if (handler instanceof HandlerMethod == false) {
|
if (handler instanceof HandlerMethod == false) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
HandlerMethod method = (HandlerMethod ) handler;
|
Method method = ((HandlerMethod) handler).getMethod();
|
||||||
|
|
||||||
// ----------- 验证登录
|
// 进行验证
|
||||||
if(method.hasMethodAnnotation(SaCheckLogin.class) || method.getBeanType().isAnnotationPresent(SaCheckLogin.class)) {
|
stpLogic.checkMethodAnnotation(method);
|
||||||
stpLogic.checkLogin();
|
|
||||||
}
|
|
||||||
|
|
||||||
// ----------- 验证角色
|
|
||||||
// 验证方法上的
|
|
||||||
SaCheckRole scr = method.getMethodAnnotation(SaCheckRole.class);
|
|
||||||
if(scr != null) {
|
|
||||||
String[] roleArray = scr.value();
|
|
||||||
if(scr.mode() == SaMode.AND) {
|
|
||||||
stpLogic.checkRoleAnd(roleArray); // 必须全部都有
|
|
||||||
} else {
|
|
||||||
stpLogic.checkRoleOr(roleArray); // 有一个就行了
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// 验证类上的
|
|
||||||
scr = method.getBeanType().getAnnotation(SaCheckRole.class);
|
|
||||||
if(scr != null) {
|
|
||||||
String[] roleArray = scr.value();
|
|
||||||
if(scr.mode() == SaMode.AND) {
|
|
||||||
stpLogic.checkRoleAnd(roleArray); // 必须全部都有
|
|
||||||
} else {
|
|
||||||
stpLogic.checkRoleOr(roleArray); // 有一个就行了
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ----------- 验证权限
|
|
||||||
// 验证方法上的
|
|
||||||
SaCheckPermission scp = method.getMethodAnnotation(SaCheckPermission.class);
|
|
||||||
if(scp != null) {
|
|
||||||
String[] permissionArray = scp.value();
|
|
||||||
if(scp.mode() == SaMode.AND) {
|
|
||||||
stpLogic.checkPermissionAnd(permissionArray); // 必须全部都有
|
|
||||||
} else {
|
|
||||||
stpLogic.checkPermissionOr(permissionArray); // 有一个就行了
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// 验证类上的
|
|
||||||
scp = method.getBeanType().getAnnotation(SaCheckPermission.class);
|
|
||||||
if(scp != null) {
|
|
||||||
String[] permissionArray = scp.value();
|
|
||||||
if(scp.mode() == SaMode.AND) {
|
|
||||||
stpLogic.checkPermissionAnd(permissionArray); // 必须全部都有
|
|
||||||
} else {
|
|
||||||
stpLogic.checkPermissionOr(permissionArray); // 有一个就行了
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 通过验证
|
// 通过验证
|
||||||
return true;
|
return true;
|
||||||
|
Reference in New Issue
Block a user