首页 最新 热门 推荐

  • 首页
  • 最新
  • 热门
  • 推荐

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

  • 23-07-18 12:52
  • 1425
  • 5763
juejin.cn

写在最前

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

源码地址(后端):gitee.com/csps/mingyu…

源码地址(前端):gitee.com/csps/mingyu…

文档地址:gitee.com/csps/mingyu…

前情回顾

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

用户信息接口

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

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

json
复制代码
{    "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

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

响应

css
复制代码
{  "code": 200,  "msg": "登录成功",  "data": "pVMCmkG1Q320sbKOJxzxjBXOOYNOT1MH" }

网关注册权限认证拦截器

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

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

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

白名单

java
复制代码
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 whites = new ArrayList<>(); ​ }

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

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

网关统一鉴权

kotlin
复制代码
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 全局过滤器 */ @Bean public SaReactorFilter getSaReactorFilter(IgnoreWhiteProperties ignoreWhite) { return new SaReactorFilter() // 拦截地址 .addInclude("/**") // 开放地址 .addExclude("/favicon.ico", "/actuator/**") // 鉴权方法:每次访问进入 .setAuth(obj -> { // 登录校验 -- 拦截所有路由 SaRouter.match("/**").notMatch(ignoreWhite.getWhites()).check(r -> { // 检查是否登录 是否有token StpUtil.checkLogin(); }); }).setError(e -> SaResult.error("认证失败,无法访问系统资源").setCode(HttpStatus.UNAUTHORIZED)); } ​ }

启动测试

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

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

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

css
复制代码
{    "code": 200,    "msg": "操作成功",    "data": [       {            "userId": 1,         ...       }   ] }

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

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

注册 Sa-Token 路由拦截器

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

typescript
复制代码
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 的拦截器 */ @Override public void addInterceptors(InterceptorRegistry registry) { // 注册路由拦截器,自定义验证规则 registry.addInterceptor(new SaInterceptor()).addPathPatterns("/**"); } ​ /** * 校验是否从网关转发 */ @Bean public 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

arduino
复制代码
com.csp.mingyue.common.security.config.SecurityConfiguration

微服务引入 mingyue-common-security

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

xml
复制代码
<dependency>  <groupId>com.csp.mingyuegroupId>  <artifactId>mingyue-common-securityartifactId> dependency>

启动测试

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

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

Feign 调用鉴权处理

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

css
复制代码
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 参数

java
复制代码
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 { ​ @Override public Mono 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); } ​ @Override public int getOrder() { return -100; } ​ }

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

获取所有用户信息

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

1. 直接调用

返回:认证失败

image-20230710201308146

2. 登录接口获取 Token

data: hiSTb6JAQrA9LTOhYuA27UD2LhGBI40x

image-20230710201415086

3. 切换 system 进行 Authorize 认证

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

image-20230710201455331

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

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

json
复制代码
{  "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   } ] }

小结

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

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

注:本文转载自juejin.cn的Strive_MY的文章"https://juejin.cn/post/7256958758794084408"。版权归原作者所有,此博客不拥有其著作权,亦不承担相应法律责任。如有侵权,请联系我们删除。
复制链接
复制链接
相关推荐
发表评论
登录后才能发表评论和回复 注册

/ 登录

评论记录:

未查询到任何数据!
回复评论:

分类栏目

后端 (14832) 前端 (14280) 移动开发 (3760) 编程语言 (3851) Java (3904) Python (3298) 人工智能 (10119) AIGC (2810) 大数据 (3499) 数据库 (3945) 数据结构与算法 (3757) 音视频 (2669) 云原生 (3145) 云平台 (2965) 前沿技术 (2993) 开源 (2160) 小程序 (2860) 运维 (2533) 服务器 (2698) 操作系统 (2325) 硬件开发 (2492) 嵌入式 (2955) 微软技术 (2769) 软件工程 (2056) 测试 (2865) 网络空间安全 (2948) 网络与通信 (2797) 用户体验设计 (2592) 学习和成长 (2593) 搜索 (2744) 开发工具 (7108) 游戏 (2829) HarmonyOS (2935) 区块链 (2782) 数学 (3112) 3C硬件 (2759) 资讯 (2909) Android (4709) iOS (1850) 代码人生 (3043) 阅读 (2841)

热门文章

101
推荐
关于我们 隐私政策 免责声明 联系我们
Copyright © 2020-2025 蚁人论坛 (iYenn.com) All Rights Reserved.
Scroll to Top