授权规则:黑白名单 + 来源控制实战

📅 发布时间:2026/7/5 5:38:27 👁️ 浏览次数:
授权规则:黑白名单 + 来源控制实战
本文聚焦Sentinel授权规则的核心实战黑白名单控制与来源控制。作为微服务架构中接口安全防护的关键手段授权规则能帮我们精准拦截非法访问、规范接口调用来源是保障服务稳定性和安全性的重要屏障。本文全程实战导向从“理论铺垫→环境准备→分步实操→进阶优化→避坑指南”覆盖新手入门到生产落地的全流程所有代码可直接复制复用建议收藏后跟着实操确保学完就能上手一、前置认知为什么需要授权规则在微服务场景中我们经常会遇到这样的需求核心接口如用户信息修改、订单删除仅允许公司内网IP访问禁止外部公网调用某个接口被恶意IP频繁请求需要拉黑该IP阻止其继续访问微服务间调用时仅允许指定服务如网关、订单服务调用当前服务接口防止内部非法调用后台管理接口仅允许管理员来源的请求访问普通用户无法触发。这些需求都可以通过Sentinel的授权规则来实现。Sentinel授权规则的核心逻辑是基于请求的“来源”origin通过黑白名单策略控制请求是否能访问目标资源本质是一种“访问权限校验”机制。1.1 核心概念拆解在开始实操前先明确3个核心概念避免后续踩坑资源ResourceSentinel保护的对象也是授权规则作用的目标通常是接口URL、接口方法名如/user/get、orderCreate是限流、授权的最小粒度。来源Origin请求的发起者标识可理解为“谁在调用接口”常见的来源有IP地址、服务名、用户角色如admin、guest、设备类型等。Sentinel默认不会自动识别来源需要我们自定义解析逻辑。黑白名单策略白名单AUTHORITY_WHITE仅允许来源在白名单内的请求访问资源相当于“放行名单”黑名单AUTHORITY_BLACK禁止来源在黑名单内的请求访问资源相当于“拦截名单”。1.2 授权规则核心原理Sentinel通过AuthoritySlot授权插槽实现授权规则的校验它是Sentinel处理链中的重要一环核心流程如下请求进入Sentinel保护的资源时AuthoritySlot被触发通过自定义的来源解析器获取当前请求的来源originAuthorityRuleManager加载该资源对应的授权规则交给AuthorityRuleChecker进行校验根据黑白名单策略和来源匹配结果决定放行或拦截请求拦截时抛出AuthorityException。关键注意点每个资源只能配置一条授权规则无法为同一个接口同时配置“拉黑A”和“只允许B”两条规则需合并为一条规则如将A加入黑名单、B加入白名单或合并为单一策略。二、环境准备必做本次实战基于SpringBoot SpringCloud Alibaba Sentinel提前准备好以下环境避免实操时卡顿2.1 依赖配置Maven核心依赖包括Sentinel核心包、SpringCloud Alibaba Sentinel适配器若需要规则持久化可添加Nacos数据源依赖生产环境推荐!-- SpringBoot 基础依赖略 --!-- SpringCloud Alibaba Sentinel 核心依赖 --dependencygroupIdcom.alibaba.cloud/groupIdartifactIdspring-cloud-starter-alibaba-sentinel/artifactIdversion2021.0.4.0/version!-- 版本与SpringCloud Alibaba对应 --/dependency!-- SpringBoot Actuator可选用于监控 --dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-actuator/artifactId/dependency!-- Sentinel Nacos 规则持久化依赖生产环境推荐可选 --dependencygroupIdcom.alibaba.csp/groupIdartifactIdsentinel-datasource-nacos/artifactId/dependency!-- OpenFeign微服务调用场景可选 --dependencygroupIdorg.springframework.cloud/groupIdartifactIdspring-cloud-starter-openfeign/artifactId/dependency2.2 配置文件application.yml配置Sentinel控制台地址、服务名、来源解析相关配置以及可选的Nacos持久化配置spring:application:name:sentinel-authority-demo# 服务名控制台显示用cloud:alibaba:sentinel:transport:dashboard:127.0.0.1:8858# Sentinel控制台地址自行部署port:8719# 与控制台通信端口默认8719占用则自动1eager:true# 饥饿加载避免首次调用无规则web-context-unify:false# 关闭web上下文统一便于自定义来源解析# 可选Nacos规则持久化配置生产环境必配避免重启服务丢失规则datasource:authority-rule:# 授权规则数据源nacos:server-addr:127.0.0.1:8848# Nacos地址data-id:${spring.application.name}-authority-rulesgroup-id:SENTINEL_GROUPrule-type:authority# 规则类型授权规则# 暴露监控端点可选management:endpoints:web:exposure:include:*# 日志配置可选便于排查授权失败问题logging:level:com.alibaba.csp.sentinel:INFO2.3 控制台部署Sentinel控制台是可视化配置授权规则的核心工具部署方式简单Windows/Linux通用下载Sentinel控制台jar包推荐版本1.8.6与依赖兼容Sentinel官方下载地址执行命令启动控制台java -jar sentinel-dashboard-1.8.6.jar --server.port8858端口可自定义避免冲突访问控制台http://127.0.0.1:8858默认账号密码sentinel/sentinel启动本地SpringBoot服务控制台会自动注册该服务首次调用接口后服务会出现在控制台列表中。三、实战一IP黑白名单控制最常用IP黑白名单是最基础的授权场景适用于“限制特定IP访问”比如拉黑恶意IP、仅允许内网IP访问核心接口。本次实战实现两个场景场景1拉黑恶意IP192.168.1.100、192.168.1.101禁止其访问所有接口场景2仅允许内网IP127.0.0.1、192.168.1.0/24网段访问核心接口/user/admin。3.1 步骤1自定义IP来源解析器Sentinel默认不会自动获取请求的IP作为来源需要实现RequestOriginParser接口自定义来源解析逻辑将请求的IP作为originpackagecom.example.sentinelauthoritydemo.config;importcom.alibaba.csp.sentinel.adapter.spring.webmvc.callback.RequestOriginParser;importorg.springframework.stereotype.Component;importjavax.servlet.http.HttpServletRequest;importjava.util.Objects;/** * 自定义IP来源解析器用于Sentinel IP黑白名单授权 */ComponentpublicclassIpRequestOriginParserimplementsRequestOriginParser{OverridepublicStringparseOrigin(HttpServletRequestrequest){// 1. 获取请求的IP地址处理代理场景如Nginx、网关转发Stringiprequest.getHeader(X-Forwarded-For);if(ipnull||ip.isEmpty()||unknown.equalsIgnoreCase(ip)){iprequest.getHeader(Proxy-Client-IP);}if(ipnull||ip.isEmpty()||unknown.equalsIgnoreCase(ip)){iprequest.getHeader(WL-Proxy-Client-IP);}if(ipnull||ip.isEmpty()||unknown.equalsIgnoreCase(ip)){iprequest.getRemoteAddr();}// 2. 处理多IP转发场景X-Forwarded-For可能包含多个IP取第一个if(ip!nullip.contains(,)){ipip.split(,)[0].trim();}// 3. 兜底若未获取到IP标记为unknownreturnObjects.requireNonNullElse(ip,unknown);}}说明该解析器会将请求的真实IP作为来源origin适配网关转发、代理等生产场景避免因代理导致IP获取错误。3.2 步骤2编写测试接口编写两个测试接口用于验证IP黑白名单效果packagecom.example.sentinelauthoritydemo.controller;importcom.alibaba.csp.sentinel.annotation.SentinelResource;importcom.alibaba.csp.sentinel.slots.block.BlockException;importorg.springframework.web.bind.annotation.GetMapping;importorg.springframework.web.bind.annotation.RequestMapping;importorg.springframework.web.bind.annotation.RestController;/** * 测试接口用于验证Sentinel授权规则IP黑白名单 */RestControllerRequestMapping(/user)publicclassUserController{/** * 普通接口所有人可访问除了黑名单IP */GetMapping(/public)SentinelResource(valueuserPublic,blockHandlerblockHandler)publicStringpublicInterface(){return普通接口当前IP已通过Sentinel授权校验访问成功;}/** * 核心接口仅允许内网IP访问白名单 */GetMapping(/admin)SentinelResource(valueuserAdmin,blockHandlerblockHandler)publicStringadminInterface(){return核心接口当前IP在白名单内访问成功;}/** * 授权失败兜底方法必须与被保护方法参数一致且最后多一个BlockException参数 */publicStringblockHandler(BlockExceptione){// 可根据异常类型区分授权失败、限流、熔断等return授权失败当前IP无访问权限异常信息e.getMessage();}}关键说明SentinelResource注解用于标记被Sentinel保护的资源value是资源名后续配置授权规则时需对应blockHandler是授权失败的兜底方法。3.3 步骤3控制台配置IP黑白名单规则启动SpringBoot服务和Sentinel控制台访问一次测试接口如http://127.0.0.1:8080/user/public确保服务在控制台注册成功然后配置授权规则3.3.1 配置黑名单规则拦截恶意IP控制台左侧选择「授权规则」→ 点击「新增授权规则」配置核心参数重点对应资源名和IP资源名userPublic与接口上SentinelResource的value一致授权类型IP默认可下拉选择策略黑名单配置值192.168.1.100,192.168.1.101多个IP用逗号分隔备注拉黑恶意IP禁止访问普通接口。点击「新增」规则实时生效无需重启服务。3.3.2 配置白名单规则仅允许内网IP访问核心接口再次点击「新增授权规则」配置核心参数资源名userAdmin与核心接口的资源名一致授权类型IP策略白名单配置值127.0.0.1,192.168.1.0/24支持网段配置/24表示该网段下所有IP备注仅允许内网IP访问核心接口。点击「新增」规则生效。3.4 步骤4测试验证使用Postman或浏览器模拟不同IP访问接口验证规则效果可通过修改本地hosts或使用代理工具切换IP访问IP访问接口预期结果实际结果192.168.1.100黑名单/user/public授权失败授权失败当前IP无访问权限127.0.0.1白名单/user/admin访问成功核心接口当前IP在白名单内访问成功10.0.0.1非白名单/user/admin授权失败授权失败当前IP无访问权限192.168.1.102非黑名单/user/public访问成功普通接口当前IP已通过Sentinel授权校验访问成功测试通过后说明IP黑白名单规则配置生效实现了预期的授权控制效果。四、实战二服务来源控制微服务场景在微服务架构中服务间调用频繁我们需要限制“只有指定服务才能调用当前服务的接口”避免非法服务调用。比如订单服务order-service只能被网关服务gateway-service和用户服务user-service调用其他服务禁止调用。本次实战基于OpenFeign实现微服务调用重点演示“服务来源控制”的全流程。4.1 步骤1自定义服务来源解析器服务来源控制的核心是“识别调用方的服务名”我们通过请求头携带服务名再自定义解析器获取服务名作为originpackagecom.example.sentinelauthoritydemo.config;importcom.alibaba.csp.sentinel.adapter.spring.webmvc.callback.RequestOriginParser;importorg.springframework.stereotype.Component;importjavax.servlet.http.HttpServletRequest;importjava.util.Objects;/** * 自定义服务来源解析器用于微服务间授权 * 从请求头中获取调用方服务名作为Sentinel的origin */ComponentpublicclassServiceRequestOriginParserimplementsRequestOriginParser{// 定义请求头中携带服务名的key自定义调用方需对应privatestaticfinalStringSERVICE_NAME_HEADERService-Name;OverridepublicStringparseOrigin(HttpServletRequestrequest){// 从请求头中获取调用方服务名StringserviceNamerequest.getHeader(SERVICE_NAME_HEADER);// 兜底未获取到服务名标记为unknown会被拦截returnObjects.requireNonNullElse(serviceName,unknown);}}说明若同时需要IP和服务来源控制可在解析器中返回“IP:服务名”的格式如127.0.0.1:gateway-service后续配置规则时对应即可。4.2 步骤2配置调用方微服务调用时携带服务名以OpenFeign调用为例在调用方如gateway-service的Feign接口中添加请求头携带自身服务名packagecom.example.gatewayservice.feign;importorg.springframework.cloud.openfeign.FeignClient;importorg.springframework.web.bind.annotation.GetMapping;importorg.springframework.web.bind.annotation.RequestHeader;/** * 调用sentinel-authority-demo服务的Feign接口 */FeignClient(namesentinel-authority-demo)// 被调用服务名publicinterfaceUserFeignClient{// 调用被保护的接口在请求头中携带自身服务名GetMapping(/user/admin)StringgetAdminInfo(RequestHeader(Service-Name)StringserviceName);}调用方Controller层调用Feign接口时传入自身服务名RestControllerRequestMapping(/gateway)publicclassGatewayController{AutowiredprivateUserFeignClientuserFeignClient;// 调用被保护接口携带自身服务名gateway-serviceGetMapping(/call-admin)publicStringcallAdmin(){returnuserFeignClient.getAdminInfo(gateway-service);}}4.3 步骤3控制台配置服务来源授权规则在Sentinel控制台为被调用服务sentinel-authority-demo的核心接口配置服务来源白名单左侧「授权规则」→「新增授权规则」配置核心参数资源名userAdmin与被保护接口的资源名一致授权类型自定义下拉选择对应服务名来源策略白名单配置值gateway-service,user-service允许调用的服务名多个用逗号分隔备注仅允许网关和用户服务调用核心接口。点击「新增」规则生效。4.4 步骤4测试验证合法调用gateway-service调用访问网关接口http://127.0.0.1:8081/gateway/call-admin调用方携带服务名gateway-service预期访问成功合法调用user-service调用同理user-service携带自身服务名调用预期访问成功非法调用test-service调用若test-service携带服务名test-service调用预期授权失败返回兜底提示无服务名调用若调用方未携带Service-Name请求头origin为unknown预期授权失败。测试结果符合预期说明服务来源控制规则配置成功实现了微服务间的授权校验。五、进阶优化生产环境落地技巧前面的实操的是基础场景在生产环境中还需要注意以下几点避免规则失效或出现性能问题5.1 规则持久化必做Sentinel控制台配置的规则默认存储在内存中服务重启后规则会丢失生产环境必须配置规则持久化推荐使用Nacos作为数据源前面配置文件已预留相关配置步骤如下登录Nacos控制台新建配置数据IDsentinel-authority-demo-authority-rules服务名 authority-rules分组SENTINEL_GROUP配置格式JSON配置内容授权规则示例与控制台配置一致[ { resource: userPublic, limitApp: 192.168.1.100,192.168.1.101, strategy: 1, // 1黑名单0白名单 controlBehavior: 0, clusterMode: false }, { resource: userAdmin, limitApp: gateway-service,user-service, strategy: 0, // 0白名单 controlBehavior: 0, clusterMode: false } ]保存配置后服务重启时会自动从Nacos加载授权规则控制台修改规则后也会同步到Nacos实现规则持久化。5.2 性能优化授权规则的校验会伴随每一次请求需注意以下优化点避免影响接口性能开启Sentinel饥饿加载eager: true避免首次调用时规则未加载导致授权失效简化来源解析器逻辑避免在解析器中执行耗时操作如数据库查询批量配置规则避免频繁更新规则规则更新会触发全量加载核心接口优先使用白名单白名单校验逻辑更简洁性能更优。5.3 多场景组合授权实际场景中可能需要“IP服务名”双重授权比如仅允许内网IP的gateway-service调用核心接口此时可修改来源解析器返回“IP:服务名”格式再配置白名单为“192.168.1.10:gateway-service”即可。六、常见坑点避坑指南新手必看结合实战经验整理了4个新手最容易踩的坑提前规避坑点1资源名不匹配规则不生效问题控制台配置的资源名与接口SentinelResource的value不一致导致授权规则无效解决确保资源名完全一致区分大小写建议统一命名规范如接口URL全路径、方法名。坑点2来源解析器未注册origin为unknown问题自定义了解析器但未添加Component注解导致Sentinel无法获取origin所有请求都被拦截解决给解析器添加Component注解确保Spring能扫描到并注入。坑点3多个授权规则配置冲突问题为同一个资源配置了多条授权规则导致规则冲突Sentinel仅生效最后一条解决每个资源只能配置一条授权规则多条件需合并如多个IP、多个服务名用逗号分隔。坑点4代理场景下IP获取错误问题服务部署在Nginx或网关后面解析器获取到的是代理IP而非真实客户端IP解决在解析器中优先获取X-Forwarded-For请求头处理多IP转发场景前面的IP解析器已适配。七、总结与拓展本文我们完成了Sentinel授权规则的核心实战IP黑白名单控制和服务来源控制掌握了“理论→配置→实操→优化”的全流程重点总结授权规则的核心是“来源origin 黑白名单策略”通过AuthoritySlot实现校验IP黑白名单适用于单体服务、对外接口的安全防护服务来源控制适用于微服务间调用生产环境必须配置规则持久化Nacos避免规则丢失同时注意性能优化自定义来源解析器是关键需根据实际场景IP、服务名、用户角色灵活实现。