016-从零搭建微服务-认证中心(七)

写在最前

如果这个项目让你有所收获,记得 Star 关注哦,这对我是非常不错的鼓励与支持。

源码地址(后端):https://gitee.com/csps/mingyue

源码地址(前端):https://gitee.com/csps/mingyue-ui

文档地址:https://gitee.com/csps/mingyue/wikisapplication-common.yml

前情回顾

截止目前我们的系统并未增加拦截鉴权,都是直接放行。接下来我列举两个接口,测试一下未加拦截鉴权的访问,结果都是直接返回。

用户信息接口

非网关:http://mingyue-gateway:8000/sysUser/getSysUserInfoByUsername?username=mingyue

网关:http://mingyue-gateway:9100/system/sysUser/getSysUserInfoByUsername?username=mingyue

{"code": 200,"msg": "操作成功","data": [{"userId": 1,"username": "mingyue","nickname": "明月","sex": "0","password": "123456","phone": "13260718262","email": null,"avatar": null,"lockFlag": "0","delFlag": "0","createTime": null,"updateTime": null,"createBy": null,"updateBy": null}]
}

登录接口

非网关:http://mingyue-gateway:9000/login

网关:http://mingyue-gateway:9100/auth/login

curl -X 'POST' \'http://mingyue-gateway:9100/auth/login' \-H 'accept: */*' \-H 'Content-Type: application/json' \-d '{"username": "mingyue","password": "123456"
}'

响应

{"code": 200,"msg": "登录成功","data": "pVMCmkG1Q320sbKOJxzxjBXOOYNOT1MH"
}

网关注册权限认证拦截器

项目中所有接口均需要登录认证,只有 “登录接口” 本身对外开放

我们怎么实现呢?给每个接口加上鉴权注解?手写全局拦截器?似乎都不是非常方便。

在这个需求中我们真正需要的是一种基于路由拦截的鉴权模式,那么在 Sa-Token 怎么实现路由拦截鉴权呢?

白名单

import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.context.annotation.Configuration;import java.util.ArrayList;
import java.util.List;/*** 放行白名单配置** @author Strive*/
@Data
@NoArgsConstructor
@Configuration
@RefreshScope
@ConfigurationProperties(prefix = "security.ignore")
public class IgnoreWhiteProperties {/*** 放行白名单配置,网关不校验此处的白名单*/private List<String> whites = new ArrayList<>();}

mingyue-gateway.yml Nacos 增加白名单配置

# 安全配置
security:# 不校验白名单ignore:whites:- /**/v3/api-docs- /v3/api-docs/**- /webjars/**- /auth/oauth2/**- /auth/logout- /auth/login

网关统一鉴权

import cn.dev33.satoken.reactor.filter.SaReactorFilter;
import cn.dev33.satoken.router.SaRouter;
import cn.dev33.satoken.stp.StpUtil;
import cn.dev33.satoken.util.SaResult;
import com.csp.mingyue.common.core.constant.HttpStatus;
import com.csp.mingyue.gateway.support.IgnoreWhiteProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;/*** [Sa-Token 权限认证] 拦截器** @author Strive*/
@Configuration
public class AuthFilter {/*** 注册 Sa-Token 全局过滤器*/@Beanpublic SaReactorFilter getSaReactorFilter(IgnoreWhiteProperties ignoreWhite) {return new SaReactorFilter()// 拦截地址.addInclude("/**")// 开放地址.addExclude("/favicon.ico", "/actuator/**")// 鉴权方法:每次访问进入.setAuth(obj -> {// 登录校验 -- 拦截所有路由SaRouter.match("/**").notMatch(ignoreWhite.getWhites()).check(r -> {// 检查是否登录 是否有tokenStpUtil.checkLogin();});}).setError(e -> SaResult.error("认证失败,无法访问系统资源").setCode(HttpStatus.UNAUTHORIZED));}}

启动测试

访问接口:网关:http://mingyue-gateway:9100/system/sysUser/getSysUserInfoByUsername?username=mingyue,响应如下:

{
"code": 401,
"msg": "认证失败,无法访问系统资源",
"data": null
}

网关拦截成功,此时我们直接通过非网关访问,发现接口是可以取到数据的。测试:http://mingyue-gateway:8000/sysUser/getSysUserInfoByUsername?username=mingyue,响应如下:

{"code": 200,"msg": "操作成功","data": [{"userId": 1,...}]
}

这肯定是不可以的,接下来我们需要给非网关的服务增加拦截器~~~,防止直接访问!

微服务(非网关)拦截鉴权

注册 Sa-Token 路由拦截器

mingyue-common-security 模块注册 Sa-Token 路由拦截器

import cn.dev33.satoken.filter.SaServletFilter;
import cn.dev33.satoken.interceptor.SaInterceptor;
import cn.dev33.satoken.same.SaSameUtil;
import cn.dev33.satoken.util.SaResult;
import com.csp.mingyue.common.core.constant.HttpStatus;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;/*** 权限安全配置** @author Strive*/
@AutoConfiguration
public class SecurityConfiguration implements WebMvcConfigurer {/*** 注册 sa-token 的拦截器*/@Overridepublic void addInterceptors(InterceptorRegistry registry) {// 注册路由拦截器,自定义验证规则registry.addInterceptor(new SaInterceptor()).addPathPatterns("/**");}/*** 校验是否从网关转发*/@Beanpublic SaServletFilter getSaServletFilter() {return new SaServletFilter().addInclude("/**").addExclude("/actuator/**").setAuth(obj -> {SaSameUtil.checkCurrentRequestToken();}).setError(e -> SaResult.error("认证失败,无法访问系统资源").setCode(HttpStatus.UNAUTHORIZED));}}

自动装配导入添加:org.springframework.boot.autoconfigure.AutoConfiguration.imports

com.csp.mingyue.common.security.config.SecurityConfiguration

微服务引入 mingyue-common-security

非网关服务直接引入 mingyue-common-security 即可

<!-- 认证工具类 -->
<dependency><groupId>com.csp.mingyue</groupId><artifactId>mingyue-common-security</artifactId>
</dependency>

启动测试

测试 【前情回顾】中的接口,如:http://mingyue-gateway:8000/sysUser/getSysUserInfoByUsername?username=mingyue,返回如下

{
"code": 401,
"msg": "认证失败,无法访问系统资源",
"data": null
}

Feign 调用鉴权处理

此时网关服务、系统服务、认证中心都已经增加了权限拦截,此时我们打开接口文档,页面打印错误如下:

Unable to render this definition
The provided definition does not specify a valid version field.Please indicate a valid Swagger or OpenAPI version field. Supported version fields are swagger: "2.0" and those that match openapi: 3.0.n (for example, openapi: 3.0.0).

这是因为【网关服务】虽然放行了接口文档,但是【系统服务、认证中心】并未放行,所以出现错误。我们需要转发认证过滤器(内部服务外网隔离) 为请求添加 Same-Token

转发认证过滤器

为请求追加 Same-Token 参数

import cn.dev33.satoken.same.SaSameUtil;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;/*** 转发认证过滤器(内部服务外网隔离) 为请求添加 Same-Token** @author Strive*/
@Component
public class ForwardAuthFilter implements GlobalFilter, Ordered {@Overridepublic Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {ServerHttpRequest newRequest = exchange.getRequest().mutate()// 为请求追加 Same-Token 参数.header(SaSameUtil.SAME_TOKEN, SaSameUtil.getToken()).build();ServerWebExchange newExchange = exchange.mutate().request(newRequest).build();return chain.filter(newExchange);}@Overridepublic int getOrder() {return -100;}}

此时我们再打开接口文档,查看是否展示正常即可。

获取所有用户信息

接口下演示调用【获取所有用户信息】,看看增加了拦截器后如何访问该接口

1. 直接调用

返回:认证失败

image-20230710201308146

2. 登录接口获取 Token

data: hiSTb6JAQrA9LTOhYuA27UD2LhGBI40x

image-20230710201415086

3. 切换 system 进行 Authorize 认证

点击 Authorize 按钮,Value 中录入登录接口获取的 Token,再次点击 Authorize 按钮确定即可。

image-20230710201455331

4. 再次访问获取所有用户信息接口

接口正常返回,输出如下:

{"code": 200,"msg": "操作成功","data": [{"userId": 1,"username": "mingyue","nickname": "明月","sex": "0","password": "123456","phone": "13260718262","email": null,"avatar": null,"lockFlag": "0","delFlag": "0","createTime": null,"updateTime": null,"createBy": null,"updateBy": null}]
}

小结

登录认证算是完成一小半了,没错才一小半,路漫漫其修远兮~

接下来我们设计一下数据库权限模型,也就是用户、角色、菜单的关系。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/28392.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

回归预测 | MATLAB实现基于BiGRU-AdaBoost双向门控循环单元结合AdaBoost多输入单输出回归预测

回归预测 | MATLAB实现基于BiGRU-AdaBoost双向门控循环单元结合AdaBoost多输入单输出回归预测 目录 回归预测 | MATLAB实现基于BiGRU-AdaBoost双向门控循环单元结合AdaBoost多输入单输出回归预测预测效果基本介绍模型描述程序设计参考资料 预测效果 基本介绍 1.MATLAB实现基于B…

【软件测试面试】腾讯数据平台笔试题-接口-自动化-数据库

数据库题 答案&#xff1a; Python编程题 答案&#xff1a; 接口参数化题 答案&#xff1a; 接口自动化题 答案&#xff1a; 以下是我收集到的比较好的学习教程资源&#xff0c;虽然不是什么很值钱的东西&#xff0c;如果你刚好需要&#xff0c;可以评论区&#…

spring复习:(40)全注解的spring AOP

零、需要的依赖&#xff1a; <dependency><groupId>org.aspectj</groupId><artifactId>aspectjrt</artifactId><version>1.8.9</version></dependency><dependency><groupId>org.aspectj</groupId><arti…

第一百零八天学习记录:C++基础:文件操作

C中对文件操作需要包含头文件<fstream> 操作文件的三大类&#xff1a; 1、ofstream:写擦破自评 2、ifstream:读操作 3、fstream:读写操作 文本文件 写文件 写文件步骤如下&#xff1a; 1、包含头文件 #include <fstream>2、创建流对象 ofstream ofs; 3、打开文…

TCP四次挥手过程

TCP 断开连接是通过四次挥手方式。 双方都可以主动断开连接&#xff0c;断开连接后主机中的「资源」将被释放&#xff0c; 刚开始双方都处于 establised 状态&#xff0c;假如是客户端先发起关闭请求&#xff0c;过程如下图&#xff1a; 第一次挥手&#xff1a;客户端打算关闭…

SpringSecurity(6.1.x版本) 认证,授权,自定义登录,内部机制探讨

SpringSecurity 文章目录 SpringSecurityCSRF跨站请求伪造攻击SFA会话固定攻击XSS跨站脚本攻击开发环境搭建认证直接认证使用数据库认证自定义验证 其他配置自定义登录界面记住我功能 授权基于角色授权基于权限授权使用注解权限判断 内部机制探究授权校验流程安全上下文安全上下…

智能电表远程抄表系统原理

智能电表远程抄表系统是现代智能电网建设的重要组成部分&#xff0c;它利用物联网技术实现电表数据的远程采集、传输和处理&#xff0c;提高了电力公司的抄表效率&#xff0c;同时也为用户提供了更加便捷、准确的用电服务。本文将从远程智能电表抄表系统的工作原理、特点、应用…

10_SPI_Flash 连续写实验

10_SPI_Flash 连续写实验 1. 实验目标2. 连续写方法3. 操作时序4. 流程框图4.1 顶层模块4.2 连续写模块 5. 波形图6. RTL6.1 flash_seq_wr_ctrl6.2 spi_flash_seq_wr 7. Testbench 1. 实验目标 使用页写指令&#xff0c;将串口发送过来的连续不定量数据写入 Flash。本实验中&a…

配置uprof环境

AMD uprof 1/从AMD μProf | AMD处下载两个文档 2/解压 tar jxvf filename 3/将.rpm转换成deb Ubuntu的软件包格式是deb&#xff0c;如果要安装rpm的包&#xff0c;则要先用alien把rpm转换成deb。 sudo apt-get install alien #alien默认没有安装&#xff0c;所以首先要安…

SpringBoot整合SpringSecurity+JWT

SpringBoot整合SpringSecurityJWT 整合SpringSecurity步骤 编写拦截链配置类&#xff0c;规定security参数拦截登录请求的参数&#xff0c;对该用户做身份认证。通过登录验证的予以授权&#xff0c;这里根据用户对应的角色作为授权标识。 整合JWT步骤 编写JWTUtils&#xf…

修复git diff正文中文乱码

Linux git diff正文中文乱码 在命令行下输入以下命令&#xff1a; $ git config --global core.quotepath false # 显示 status 编码 $ git config --global gui.encoding utf-8 # 图形界面编码 $ git config --global i18n.commit.encoding utf-8 # …

状态模式:游戏、工作流引擎中常用的状态机是如何实现的?

从今天起&#xff0c;我们开始学习状态模式。在实际的软件开发中&#xff0c;状态模式并不是很常用&#xff0c;但是在能够用到的场景里&#xff0c;它可以发挥很大的作用。从这一点上来看&#xff0c;它有点像我们之前讲到的组合模式。 可以简短的回顾一下组合模式&#xff1a…