SpringBoot 使用 Sa-Token 完成路由拦截鉴权

这篇具有很好参考价值的文章主要介绍了SpringBoot 使用 Sa-Token 完成路由拦截鉴权。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、需求分析

在前文,我们详细的讲述了在 Sa-Token 如何使用注解进行权限认证,注解鉴权虽然方便,却并不适合所有鉴权场景。

假设有如下需求:项目中所有接口均需要登录认证校验,只有 “登录接口” 本身对外开放。

如果我们对项目所有接口都加上 @SaCheckLogin 注解,会显得非常冗余且没有必要,在这个需求中我们真正需要的是一种基于路由拦截的鉴权模式,那么在 Sa-Token 怎么实现路由拦截鉴权呢?

Sa-Token 是一个轻量级 java 权限认证框架,主要解决登录认证、权限认证、单点登录、OAuth2、微服务网关鉴权 等一系列权限相关问题。
Gitee 开源地址:https://gitee.com/dromara/sa-token

二、注册 Sa-Token 路由拦截器

首先在项目中引入 Sa-Token 依赖:

<!-- Sa-Token 权限认证 -->
<dependency>
    <groupId>cn.dev33</groupId>
    <artifactId>sa-token-spring-boot-starter</artifactId>
    <version>1.34.0</version>
</dependency>

注:如果你使用的是 SpringBoot 3.x,只需要将 sa-token-spring-boot-starter 修改为 sa-token-spring-boot3-starter 即可。

新建配置类SaTokenConfigure.java

@Configuration
public class SaTokenConfigure implements WebMvcConfigurer {
	// 注册拦截器
	@Override
	public void addInterceptors(InterceptorRegistry registry) {
		// 注册 Sa-Token 拦截器,校验规则为 StpUtil.checkLogin() 登录校验。
		registry.addInterceptor(new SaInterceptor(handle -> StpUtil.checkLogin()))
				.addPathPatterns("/**")
				.excludePathPatterns("/user/doLogin"); 
	}
}

以上代码,我们注册了一个基于 StpUtil.checkLogin() 的登录校验拦截器,并且排除了/user/doLogin接口用来开放登录(除了/user/doLogin以外的所有接口都需要登录才能访问)。

SaInterceptor 是新版本提供的拦截器,点此 查看旧版本代码迁移示例。

三、校验函数详解

自定义认证规则:new SaInterceptor(handle -> StpUtil.checkLogin()) 是最简单的写法,代表只进行登录校验功能。

我们可以往构造函数塞一个完整的 lambda 表达式,来定义详细的校验规则,例如:

@Configuration
public class SaTokenConfigure implements WebMvcConfigurer {
	@Override
	public void addInterceptors(InterceptorRegistry registry) {
		// 注册 Sa-Token 拦截器,定义详细认证规则 
		registry.addInterceptor(new SaInterceptor(handler -> {
			// 指定一条 match 规则
			SaRouter
				.match("/**")	// 拦截的 path 列表,可以写多个 */
				.notMatch("/user/doLogin")		// 排除掉的 path 列表,可以写多个 
				.check(r -> StpUtil.checkLogin());		// 要执行的校验动作,可以写完整的 lambda 表达式
				
			// 根据路由划分模块,不同模块不同鉴权 
			SaRouter.match("/user/**", r -> StpUtil.checkPermission("user"));
			SaRouter.match("/admin/**", r -> StpUtil.checkPermission("admin"));
			SaRouter.match("/goods/**", r -> StpUtil.checkPermission("goods"));
			SaRouter.match("/orders/**", r -> StpUtil.checkPermission("orders"));
			SaRouter.match("/notice/**", r -> StpUtil.checkPermission("notice"));
			SaRouter.match("/comment/**", r -> StpUtil.checkPermission("comment"));
		})).addPathPatterns("/**");
	}
}

SaRouter.match() 匹配函数有两个参数:

  • 参数一:要匹配的path路由。
  • 参数二:要执行的校验函数。

在校验函数内不只可以使用 StpUtil.checkPermission("xxx") 进行权限校验,你还可以写任意代码,例如:

@Configuration
public class SaTokenConfigure implements WebMvcConfigurer {
	// 注册 Sa-Token 的拦截器
	@Override
	public void addInterceptors(InterceptorRegistry registry) {
		// 注册路由拦截器,自定义认证规则 
		registry.addInterceptor(new SaInterceptor(handler -> {
			
			// 登录校验 -- 拦截所有路由,并排除/user/doLogin 用于开放登录 
			SaRouter.match("/**", "/user/doLogin", r -> StpUtil.checkLogin());

			// 角色校验 -- 拦截以 admin 开头的路由,必须具备 admin 角色或者 super-admin 角色才可以通过认证 
			SaRouter.match("/admin/**", r -> StpUtil.checkRoleOr("admin", "super-admin"));

			// 权限校验 -- 不同模块校验不同权限 
			SaRouter.match("/user/**", r -> StpUtil.checkPermission("user"));
			SaRouter.match("/admin/**", r -> StpUtil.checkPermission("admin"));
			SaRouter.match("/goods/**", r -> StpUtil.checkPermission("goods"));
			SaRouter.match("/orders/**", r -> StpUtil.checkPermission("orders"));
			SaRouter.match("/notice/**", r -> StpUtil.checkPermission("notice"));
			SaRouter.match("/comment/**", r -> StpUtil.checkPermission("comment"));
			
			// 甚至你可以随意的写一个打印语句
			SaRouter.match("/**", r -> System.out.println("----啦啦啦----"));

            // 连缀写法
            SaRouter.match("/**").check(r -> System.out.println("----啦啦啦----"));
			
		})).addPathPatterns("/**");
	}
}

四、匹配特征详解

除了上述示例的 path 路由匹配,还可以根据很多其它特征进行匹配,以下是所有可匹配的特征:

// 基础写法样例:匹配一个path,执行一个校验函数 
SaRouter.match("/user/**").check(r -> StpUtil.checkLogin());

// 根据 path 路由匹配   ——— 支持写多个path,支持写 restful 风格路由 
// 功能说明: 使用 /user , /goods 或者 /art/get 开头的任意路由都将进入 check 方法
SaRouter.match("/user/**", "/goods/**", "/art/get/{id}").check( /* 要执行的校验函数 */ );

// 根据 path 路由排除匹配 
// 功能说明: 使用 .html , .css 或者 .js 结尾的任意路由都将跳过, 不会进入 check 方法
SaRouter.match("/**").notMatch("*.html", "*.css", "*.js").check( /* 要执行的校验函数 */ );

// 根据请求类型匹配 
SaRouter.match(SaHttpMethod.GET).check( /* 要执行的校验函数 */ );

// 根据一个 boolean 条件进行匹配 
SaRouter.match( StpUtil.isLogin() ).check( /* 要执行的校验函数 */ );

// 根据一个返回 boolean 结果的lambda表达式匹配 
SaRouter.match( r -> StpUtil.isLogin() ).check( /* 要执行的校验函数 */ );

// 多个条件一起使用 
// 功能说明: 必须是 Get 请求 并且 请求路径以 `/user/` 开头 
SaRouter.match(SaHttpMethod.GET).match("/user/**").check( /* 要执行的校验函数 */ );

// 可以无限连缀下去 
// 功能说明: 同时满足 Get 方式请求, 且路由以 /admin 开头, 路由中间带有 /send/ 字符串, 路由结尾不能是 .js 和 .css
SaRouter
	.match(SaHttpMethod.GET)
	.match("/admin/**")
	.match("/**/send/**") 
	.notMatch("/**/*.js")
	.notMatch("/**/*.css")
	// ....
	.check( /* 只有上述所有条件都匹配成功,才会执行最后的check校验函数 */ );

五、提前退出匹配链

使用 SaRouter.stop() 可以提前退出匹配链,例:

registry.addInterceptor(new SaInterceptor(handler -> {
	SaRouter.match("/**").check(r -> System.out.println("进入1"));
	SaRouter.match("/**").check(r -> System.out.println("进入2")).stop();
	SaRouter.match("/**").check(r -> System.out.println("进入3"));
	SaRouter.match("/**").check(r -> System.out.println("进入4"));
	SaRouter.match("/**").check(r -> System.out.println("进入5"));
})).addPathPatterns("/**");

如上示例,代码运行至第2条匹配链时,会在stop函数处提前退出整个匹配函数,从而忽略掉剩余的所有match匹配

除了stop()函数,SaRouter还提供了 back() 函数,用于:停止匹配,结束执行,直接向前端返回结果

// 执行back函数后将停止匹配,也不会进入Controller,而是直接将 back参数 作为返回值输出到前端
SaRouter.match("/user/back").back("要返回到前端的内容");

stop() 与 back() 函数的区别在于:

  • SaRouter.stop() 会停止匹配,进入Controller。
  • SaRouter.back() 会停止匹配,直接返回结果到前端。

六、使用free打开一个独立的作用域

// 进入 free 独立作用域 
SaRouter.match("/**").free(r -> {
	SaRouter.match("/a/**").check(/* --- */);
	SaRouter.match("/b/**").check(/* --- */).stop();
	SaRouter.match("/c/**").check(/* --- */);
});
// 执行 stop() 函数跳出 free 后继续执行下面的 match 匹配 
SaRouter.match("/**").check(/* --- */);

free() 的作用是:打开一个独立的作用域,使内部的 stop() 不再一次性跳出整个 Auth 函数,而是仅仅跳出当前 free 作用域。

七、使用注解忽略掉路由拦截校验

我们可以使用 @SaIgnore 注解,忽略掉路由拦截认证:

1、先配置好了拦截规则:

@Override
public void addInterceptors(InterceptorRegistry registry) {
	registry.addInterceptor(new SaInterceptor(handler -> {
		// 根据路由划分模块,不同模块不同鉴权 
		SaRouter.match("/user/**", r -> StpUtil.checkPermission("user"));
		SaRouter.match("/admin/**", r -> StpUtil.checkPermission("admin"));
		SaRouter.match("/goods/**", r -> StpUtil.checkPermission("goods"));
		// ... 
	})).addPathPatterns("/**");
}

2、然后在 Controller 里又添加了忽略校验的注解

@SaIgnore
@RequestMapping("/user/getList")
public SaResult getList() {
	System.out.println("------------ 访问进来方法"); 
	return SaResult.ok(); 
}

请求将会跳过拦截器的校验,直接进入 Controller 的方法中。

注意点:此注解的忽略效果只针对 SaInterceptor拦截器 和 AOP注解鉴权 生效,对自定义拦截器与过滤器不生效。

八、关闭注解校验

SaInterceptor 只要注册到项目中,默认就会打开注解校验,如果要关闭此能力,需要:文章来源地址https://www.toymoban.com/news/detail-454015.html

@Override
public void addInterceptors(InterceptorRegistry registry) {
	registry.addInterceptor(
		new SaInterceptor(handle -> {
			SaRouter.match("/**").check(r -> StpUtil.checkLogin());
		}).isAnnotation(false)  // 指定关闭掉注解鉴权能力,这样框架就只会做路由拦截校验了 
	).addPathPatterns("/**");
}

参考资料

  • Sa-Token 文档:https://sa-token.cc
  • Gitee 仓库地址:https://gitee.com/dromara/sa-token
  • GitHub 仓库地址:https://github.com/dromara/sa-token

到了这里,关于SpringBoot 使用 Sa-Token 完成路由拦截鉴权的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 前后端分离架构下使用 Sa-Token 完成登录认证

    目前绝大多数系统都已经采用 “前后端分离” 架构来设计了,传统的Session模式鉴权也不再适合这种架构(或者需要额外写很多的代码来专门适配)。 Sa-Token 是一个 java 轻量级权限认证框架,专为前后端分离架构打造,主要解决登录认证、权限认证、单点登录、OAuth2、微服务

    2024年02月07日
    浏览(46)
  • spring boot +Sa-Token优雅的实现项目鉴权!

    最近在做登录、授权的功能,一开始考虑到的是spring boot + spring security,但spring security太重,而我们是轻量级的项目,所以,spring security不适合我们。 而后考虑spring boot + shiro,但shiro自带的aop会影响spring boot的aop,所以,shiro也不适合我们。 后来浏览github时,发现Sa-Token这个框

    2024年02月06日
    浏览(50)
  • Sa-Token 多账号认证:同时为系统的 Admin 账号和 User 账号提供鉴权操作

    Sa-Token 是一个轻量级 java 权限认证框架,主要解决登录认证、权限认证、单点登录、OAuth2、微服务网关鉴权 等一系列权限相关问题。 Gitee 开源地址:https://gitee.com/dromara/sa-token 本篇将介绍 Sa-Token 中的多账号认证操作。 有的时候,我们会在一个项目中设计两套账号体系,比如

    2024年02月16日
    浏览(32)
  • 【Sa-Token】SpringBoot 整合 Sa-Token 快速实现 API 接口签名安全校验

    在涉及跨系统接口调用时,我们容易碰到以下安全问题: 请求身份被伪造 请求参数被篡改 请求被抓包,然后重放攻击 sa-token api-sign 模块将帮你轻松解决以上难题。(此插件是内嵌到 sa-token-core 核心包中的模块,开发者无需再次引入其它依赖,插件直接可用) 假设我们有如

    2024年02月17日
    浏览(48)
  • Sa-Token v.1.31.0 新增拦截器 SaInterceptor 功能说明,以及旧代码迁移示例

    前言 如果你的项目没有使用旧写法,可以忽略本篇文章 移步官网,本文只针对旧版本到新版本的迁移提供示例。 1、旧版本 Sa-Token 在 1.30.0 及以下版本中使用两个拦截器: SaAnnotationInterceptor :负责提供注解鉴权能力。 SaRouteInterceptor :负责提供路由拦截鉴权能力。 这次新增

    2024年02月07日
    浏览(116)
  • springboot整合Sa-Token实现登录认证和权限校验(万字长文)

    目前在国内的后端开发中,常用的安全框架有spring security、shiro。现在,介绍一款由国人开发的安全框架Sa-Token。这个框架完全由国人开发,所提供的Api文档和一些设置都是比较符合国人的开发习惯的,本次就来介绍一下如何在spring boot框架中整合Sa-Token框架,以实现我们最常

    2024年04月27日
    浏览(44)
  • springboot解决sa-token报未能获取有效的上下文处理器

    我的springboot版本3.2.3,引入的是这个依赖sa-token-spring-boot-starter就会报未能获取有效的上下文处理器 看了官方文档就是spring boot 版本的问题,引入依赖sa-token-spring-boot3-starter 解决问题 官方地址:https://sa-token.cc/doc.html#/more/common-questions?id=q%ef%bc%9a%e6%8a%a5%e9%94%99%ef%bc%9a%e6%9c%aa%e8%83

    2024年04月26日
    浏览(35)
  • 使用 Sa-Token 实现 [记住我] 模式登录、七天免登录

    如图所示,一般网站的登录界面都会有一个 [记住我] 按钮,当你勾选它登录后,即使你关闭浏览器再次打开网站,也依然会处于登录状态,无须重复验证密码: 本文将详细介绍在 Sa-Token中,如何做到以下登录模式: 记住我登录:登录后关闭浏览器,再次打开网站登录状态依

    2024年02月09日
    浏览(42)
  • Sa-Token浅谈

    主要介绍Sa-Token的鉴权使用以及实现原理。 官网介绍的非常详细,主要突出这是一个轻量级鉴权框架的特点,详情可自行访问:https://sa-token.dev33.cn/doc.html#/ 旨在简单使用,大部分功能均可以在一行代码内实现,这里举几个官网示例: 首先添加依赖: yaml配置文件: 功能图如下

    2024年02月09日
    浏览(56)
  • 使用 Sa-Token 实现不同的登录模式:单地登录、多地登录、同端互斥登录

    如果你经常使用腾讯QQ,就会发现它的登录有如下特点:它可以手机电脑同时在线,但是不能在两个手机上同时登录一个账号。 同端互斥登录,指的就是:像腾讯QQ一样,在同一类型设备上只允许单地点登录,在不同类型设备上允许同时在线。 动态演示图: Sa-Token 是一个轻量

    2024年02月13日
    浏览(48)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包