mirror of
https://gitee.com/dromara/sa-token.git
synced 2025-06-28 13:34:18 +08:00
v.1.12.0新特性:路由拦截式鉴权
This commit is contained in:
parent
ac4ac37175
commit
c3bedaef99
@ -5,7 +5,7 @@ import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||
|
||||
import cn.dev33.satoken.config.SaTokenConfig;
|
||||
import cn.dev33.satoken.interceptor.SaCheckInterceptor;
|
||||
import cn.dev33.satoken.interceptor.SaAnnotationInterceptor;
|
||||
|
||||
/**
|
||||
* sa-token代码方式进行配置
|
||||
@ -30,7 +30,8 @@ public class MySaTokenConfig implements WebMvcConfigurer {
|
||||
// 注册sa-token的拦截器,打开注解式鉴权功能
|
||||
@Override
|
||||
public void addInterceptors(InterceptorRegistry registry) {
|
||||
registry.addInterceptor(new SaCheckInterceptor()).addPathPatterns("/**"); // 全局拦截器
|
||||
// 注册注解拦截器
|
||||
registry.addInterceptor(new SaAnnotationInterceptor()).addPathPatterns("/**"); // 全局拦截器
|
||||
}
|
||||
|
||||
|
||||
|
@ -234,8 +234,14 @@ public class TestController {
|
||||
// 测试 浏览器访问: http://localhost:8081/test/test
|
||||
@RequestMapping("test")
|
||||
public AjaxJson test() {
|
||||
StpUtil.getTokenSession().logout();
|
||||
StpUtil.logoutByLoginId(10001);
|
||||
// StpUtil.getTokenSession().logout();
|
||||
// StpUtil.logoutByLoginId(10001);
|
||||
return AjaxJson.getSuccess();
|
||||
}
|
||||
|
||||
// 测试 浏览器访问: http://localhost:8081/test/test2
|
||||
@RequestMapping("test2")
|
||||
public AjaxJson test2() {
|
||||
return AjaxJson.getSuccess();
|
||||
}
|
||||
|
||||
|
@ -16,6 +16,7 @@
|
||||
- [多账号验证](/use/many-account)
|
||||
- [同端互斥登录](/use/mutex-login)
|
||||
- [注解式鉴权](/use/at-check)
|
||||
- [路由拦截式鉴权](/use/route-check)
|
||||
- [花式token](/use/token-style)
|
||||
- [框架配置](/use/config)
|
||||
- [会话治理](/use/search-session)
|
||||
|
@ -13,10 +13,10 @@
|
||||
``` java
|
||||
@Configuration
|
||||
public class MySaTokenConfig implements WebMvcConfigurer {
|
||||
// 注册sa-token的拦截器,打开注解式鉴权功能
|
||||
// 注册sa-token的注解拦截器,打开注解式鉴权功能
|
||||
@Override
|
||||
public void addInterceptors(InterceptorRegistry registry) {
|
||||
registry.addInterceptor(new SaCheckInterceptor()).addPathPatterns("/**"); // 全局拦截器
|
||||
registry.addInterceptor(new SaAnnotationInterceptor()).addPathPatterns("/**");
|
||||
}
|
||||
}
|
||||
```
|
||||
@ -119,22 +119,3 @@ public class UserService {
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- ## 3、扩展
|
||||
- 其实在注册拦截器时,我们也可以根据路由前缀设置不同 `StpLogic`, 从而达到不同模块不同鉴权方式的目的
|
||||
- 以下为参考示例:
|
||||
``` java
|
||||
@Configuration
|
||||
public class MySaTokenConfig implements WebMvcConfigurer {
|
||||
// 注册sa-token的拦截器,打开注解式鉴权功能
|
||||
@Override
|
||||
public void addInterceptors(InterceptorRegistry registry) {
|
||||
registry.addInterceptor(new SaCheckInterceptor(StpUtil.stpLogic)).addPathPatterns("/admin/**");
|
||||
registry.addInterceptor(new SaCheckInterceptor(StpUserUtil.stpLogic)).addPathPatterns("/user/**");
|
||||
}
|
||||
}
|
||||
``` -->
|
||||
|
||||
|
||||
|
||||
|
80
sa-token-doc/doc/use/route-check.md
Normal file
80
sa-token-doc/doc/use/route-check.md
Normal file
@ -0,0 +1,80 @@
|
||||
# 路由拦截式鉴权
|
||||
---
|
||||
|
||||
假设我们有如下需求:
|
||||
> 项目中所有接口均需要登录验证,只有'登录接口'本身对外开放
|
||||
|
||||
我们怎么实现呢?给每个接口加上鉴权注解?手写全局拦截器?似乎都不是非常方便。<br/>
|
||||
在这个需求中我们真正需要的是一种基于路由拦截的鉴权模式, 那么在sa-token怎么实现路由拦截鉴权呢?
|
||||
|
||||
|
||||
|
||||
## 1、注册路由拦截器
|
||||
以`springboot2.0`为例, 新建配置类`MySaTokenConfig.java`
|
||||
``` java
|
||||
@Configuration
|
||||
public class MySaTokenConfig implements WebMvcConfigurer {
|
||||
// 注册sa-token的登录拦截器
|
||||
@Override
|
||||
public void addInterceptors(InterceptorRegistry registry) {
|
||||
// 注册登录拦截器,并排除登录接口地址
|
||||
registry.addInterceptor(new SaRouteInterceptor()).addPathPatterns("/**").excludePathPatterns("/user/doLogin");
|
||||
}
|
||||
}
|
||||
```
|
||||
以上代码,我们注册了一个登录验证拦截器,并且排除了`/user/doLogin`接口用来开放登录 <br>
|
||||
那么我们如何进行权限认证拦截呢,且往下看
|
||||
|
||||
|
||||
## 2、所有拦截器示例
|
||||
``` java
|
||||
@Configuration
|
||||
public class MySaTokenConfig implements WebMvcConfigurer {
|
||||
// 注册sa-token的所有拦截器
|
||||
@Override
|
||||
public void addInterceptors(InterceptorRegistry registry) {
|
||||
|
||||
// 注册一个登录验证拦截器
|
||||
registry.addInterceptor(SaRouteInterceptor.createLoginVal()).addPathPatterns("/**").excludePathPatterns("/user/doLogin");
|
||||
|
||||
// 注册一个角色认证拦截器
|
||||
registry.addInterceptor(SaRouteInterceptor.createRoleVal("super-admin")).addPathPatterns("/**");
|
||||
|
||||
// 注册一个权限认证拦截器
|
||||
registry.addInterceptor(SaRouteInterceptor.createPermissionVal("user:add", "user:deelete")).addPathPatterns("/UserController/**");
|
||||
|
||||
// 注册一个自定义认证拦截器 (可以写任意认证代码)
|
||||
registry.addInterceptor(new SaRouteInterceptor(new SaFunction() {
|
||||
@Override
|
||||
public void run() {
|
||||
// 你可以写任意认证代码, 例如: StpUtil.checkLogin();
|
||||
System.out.println("---------- 进入自定义认证 --------------- ");
|
||||
}
|
||||
})).addPathPatterns("/**");
|
||||
|
||||
/** ------ 如果你使用的JDK版本是1.8或以上,上面那一坨可以简写为以下形式 ------ */
|
||||
|
||||
// 注册一个自定义认证拦截器 (可以写任意认证代码)
|
||||
registry.addInterceptor(new SaRouteInterceptor(()->{
|
||||
// 你可以写任意认证代码, 例如: StpUtil.checkLogin();
|
||||
System.out.println("---------- 进入自定义认证2 --------------- ");
|
||||
})).addPathPatterns("/**");
|
||||
|
||||
}
|
||||
}
|
||||
```
|
||||
(你不必像上面的示例一样注册所有拦截器,只要按需注册即可 )
|
||||
|
||||
|
||||
## 3、所有拦截器示例
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -15,7 +15,7 @@ import cn.dev33.satoken.stp.StpUtil;
|
||||
* 注解式鉴权 - 拦截器
|
||||
* @author kong
|
||||
*/
|
||||
public class SaCheckInterceptor implements HandlerInterceptor {
|
||||
public class SaAnnotationInterceptor implements HandlerInterceptor {
|
||||
|
||||
|
||||
/**
|
||||
@ -24,23 +24,32 @@ public class SaCheckInterceptor implements HandlerInterceptor {
|
||||
public StpLogic stpLogic = null;
|
||||
|
||||
/**
|
||||
* 创建,并指定一个默认的 StpLogic
|
||||
* @return 底层的 StpLogic 对象
|
||||
*/
|
||||
public SaCheckInterceptor() {
|
||||
this(StpUtil.stpLogic);
|
||||
public StpLogic getStpLogic() {
|
||||
if(stpLogic == null) {
|
||||
stpLogic = StpUtil.stpLogic;
|
||||
}
|
||||
return stpLogic;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建,并指定一个的 StpLogic
|
||||
* @param stpLogic 指定的StpLogic
|
||||
*/
|
||||
public SaCheckInterceptor(StpLogic stpLogic) {
|
||||
this.stpLogic = stpLogic;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 每次请求之前触发
|
||||
* @param stpLogic 底层的 StpLogic 对象
|
||||
*/
|
||||
public SaAnnotationInterceptor setStpLogic(StpLogic stpLogic) {
|
||||
this.stpLogic = stpLogic;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 创建,并指定一个默认的 StpLogic
|
||||
*/
|
||||
public SaAnnotationInterceptor() {
|
||||
}
|
||||
|
||||
/**
|
||||
* 每次请求之前触发的方法
|
||||
*/
|
||||
@Override
|
||||
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
|
||||
@ -53,7 +62,7 @@ public class SaCheckInterceptor implements HandlerInterceptor {
|
||||
Method method = ((HandlerMethod) handler).getMethod();
|
||||
|
||||
// 进行验证
|
||||
stpLogic.checkMethodAnnotation(method);
|
||||
getStpLogic().checkMethodAnnotation(method);
|
||||
|
||||
// 通过验证
|
||||
return true;
|
||||
@ -61,5 +70,4 @@ public class SaCheckInterceptor implements HandlerInterceptor {
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,15 @@
|
||||
package cn.dev33.satoken.interceptor;
|
||||
|
||||
/**
|
||||
* 执行验证方法的辅助类
|
||||
* @author kong
|
||||
*
|
||||
*/
|
||||
public interface SaFunction {
|
||||
|
||||
/**
|
||||
* 执行验证的方法
|
||||
*/
|
||||
public void run();
|
||||
|
||||
}
|
@ -0,0 +1,250 @@
|
||||
package cn.dev33.satoken.interceptor;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.springframework.web.servlet.HandlerInterceptor;
|
||||
|
||||
import cn.dev33.satoken.annotation.SaMode;
|
||||
import cn.dev33.satoken.stp.StpLogic;
|
||||
import cn.dev33.satoken.stp.StpUtil;
|
||||
|
||||
/**
|
||||
* sa-token基于路由的拦截式鉴权
|
||||
* @author kong
|
||||
*/
|
||||
public class SaRouteInterceptor implements HandlerInterceptor {
|
||||
|
||||
|
||||
// ----------------- 属性 -----------------
|
||||
|
||||
/**
|
||||
* 底层的 StpLogic 对象
|
||||
*/
|
||||
private StpLogic stpLogic;
|
||||
|
||||
/**
|
||||
* 验证类型 (1=登录验证, 2=角色验证, 3=权限验证, 4=自定义验证)
|
||||
*/
|
||||
private int type;
|
||||
|
||||
/**
|
||||
* 验证模式 AND | OR
|
||||
*/
|
||||
private SaMode mode;
|
||||
|
||||
/**
|
||||
* 标识码数组
|
||||
*/
|
||||
private String[] codes;
|
||||
|
||||
/**
|
||||
* 自定义模式下的执行函数
|
||||
*/
|
||||
private SaFunction function;
|
||||
|
||||
|
||||
/**
|
||||
* 表示登录验证
|
||||
*/
|
||||
public static final int LOGIN = 1;
|
||||
|
||||
/**
|
||||
* 表示角色验证
|
||||
*/
|
||||
public static final int ROLE = 2;
|
||||
|
||||
/**
|
||||
* 表示权限验证
|
||||
*/
|
||||
public static final int PERMISSION = 3;
|
||||
|
||||
/**
|
||||
* 表示自定义验证
|
||||
*/
|
||||
public static final int CUSTOM = 4;
|
||||
|
||||
|
||||
/**
|
||||
* @return 底层的 StpLogic 对象
|
||||
*/
|
||||
public StpLogic getStpLogic() {
|
||||
if(stpLogic == null) {
|
||||
stpLogic = StpUtil.stpLogic;
|
||||
}
|
||||
return stpLogic;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param stpLogic 底层的 StpLogic 对象
|
||||
*/
|
||||
public SaRouteInterceptor setStpLogic(StpLogic stpLogic) {
|
||||
this.stpLogic = stpLogic;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return 验证类型 (1=登录验证, 2=角色验证, 3=权限验证, 4=自定义验证)
|
||||
*/
|
||||
public int getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param type 验证类型 (1=登录验证, 2=角色验证, 3=权限验证, 4=自定义验证)
|
||||
*/
|
||||
public SaRouteInterceptor setType(int type) {
|
||||
this.type = type;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return 验证模式 AND | OR
|
||||
*/
|
||||
public SaMode getMode() {
|
||||
return mode;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mode 验证模式 AND | OR
|
||||
*/
|
||||
public SaRouteInterceptor setMode(SaMode mode) {
|
||||
this.mode = mode;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return 标识码数组
|
||||
*/
|
||||
public String[] getCodes() {
|
||||
return codes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param codes 标识码数组
|
||||
*/
|
||||
public SaRouteInterceptor setCodes(String... codes) {
|
||||
this.codes = codes;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return 自定义模式下的执行函数
|
||||
*/
|
||||
public SaFunction getFunction() {
|
||||
return function;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param function 设置自定义模式下的执行函数
|
||||
*/
|
||||
public SaRouteInterceptor setFunction(SaFunction function) {
|
||||
this.type = SaRouteInterceptor.CUSTOM;
|
||||
this.function = function;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
// ----------------- 构建相关 -----------------
|
||||
|
||||
/**
|
||||
* 创建 (全参数)
|
||||
* @param type 验证类型 (1=登录验证, 2=角色验证, 3=权限验证, 4=自定义验证)
|
||||
* @param mode 验证模式 AND | OR
|
||||
* @param codes 标识码数组
|
||||
*/
|
||||
public SaRouteInterceptor(int type, SaMode mode, String... codes) {
|
||||
super();
|
||||
this.type = type;
|
||||
this.mode = mode;
|
||||
this.codes = codes;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建 (默认为登录验证)
|
||||
*/
|
||||
public SaRouteInterceptor() {
|
||||
this(SaRouteInterceptor.LOGIN, null, new String[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建 (默认为自定义认证)
|
||||
* @param function 自定义模式下的执行函数
|
||||
*/
|
||||
public SaRouteInterceptor(SaFunction function) {
|
||||
this(SaRouteInterceptor.CUSTOM, null, new String[0]);
|
||||
setFunction(function);
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建一个模式为登录认证的sa路由拦截器
|
||||
* @return sa拦截器
|
||||
*/
|
||||
public static SaRouteInterceptor createLoginVal() {
|
||||
return new SaRouteInterceptor();
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建一个模式为角色认证的sa路由拦截器
|
||||
* @param roles 需要验证的数组标识列表
|
||||
* @return sa拦截器
|
||||
*/
|
||||
public static SaRouteInterceptor createRoleVal(String... roles) {
|
||||
return new SaRouteInterceptor(SaRouteInterceptor.ROLE, SaMode.AND, roles);
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建一个模式为权限认证的sa路由拦截器
|
||||
* @param permissions 需要验证的数组权限列表
|
||||
* @return sa拦截器
|
||||
*/
|
||||
public static SaRouteInterceptor createPermissionVal(String... permissions) {
|
||||
return new SaRouteInterceptor(SaRouteInterceptor.PERMISSION, SaMode.AND, permissions);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建一个模式为自定义认证的sa路由拦截器
|
||||
* @param function 自定义模式下的执行函数
|
||||
* @return sa拦截器
|
||||
*/
|
||||
public static SaRouteInterceptor createCustomVal(SaFunction function) {
|
||||
return new SaRouteInterceptor(function);
|
||||
}
|
||||
|
||||
|
||||
// ----------------- 验证方法 -----------------
|
||||
|
||||
/**
|
||||
* 每次请求之前触发的方法
|
||||
*/
|
||||
@Override
|
||||
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
|
||||
throws Exception {
|
||||
|
||||
// 根据模式进行验证
|
||||
if(this.type == SaRouteInterceptor.LOGIN) {
|
||||
getStpLogic().checkLogin();
|
||||
} else if(this.type == SaRouteInterceptor.ROLE) {
|
||||
if(mode == SaMode.AND) {
|
||||
getStpLogic().checkRoleAnd(codes);
|
||||
} else {
|
||||
getStpLogic().checkRoleOr(codes);
|
||||
}
|
||||
} else if(this.type == SaRouteInterceptor.PERMISSION) {
|
||||
if(mode == SaMode.AND) {
|
||||
getStpLogic().checkPermissionAnd(codes);
|
||||
} else {
|
||||
getStpLogic().checkPermissionOr(codes);
|
||||
}
|
||||
} else if(this.type == SaRouteInterceptor.CUSTOM) {
|
||||
function.run();
|
||||
}
|
||||
|
||||
// 通过验证
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user