惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
云风的 BLOG
云风的 BLOG
aimingoo的专栏
aimingoo的专栏
Vercel News
Vercel News
T
The Blog of Author Tim Ferriss
F
Full Disclosure
A
About on SuperTechFans
C
Check Point Blog
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
量子位
Know Your Adversary
Know Your Adversary
K
Kaspersky official blog
L
LINUX DO - 热门话题
Recorded Future
Recorded Future
C
Cisco Blogs
M
MIT News - Artificial intelligence
T
Tenable Blog
G
GRAHAM CLULEY
月光博客
月光博客
Recent Announcements
Recent Announcements
V
Visual Studio Blog
IT之家
IT之家
T
The Exploit Database - CXSecurity.com
The GitHub Blog
The GitHub Blog
T
Threat Research - Cisco Blogs
D
DataBreaches.Net
P
Privacy International News Feed
P
Proofpoint News Feed
I
Intezer
博客园 - 叶小钗
C
CXSECURITY Database RSS Feed - CXSecurity.com
The Hacker News
The Hacker News
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
博客园 - Franky
SecWiki News
SecWiki News
宝玉的分享
宝玉的分享
P
Palo Alto Networks Blog
Last Week in AI
Last Week in AI
小众软件
小众软件
Hacker News - Newest:
Hacker News - Newest: "LLM"
O
OpenAI News
N
News and Events Feed by Topic
Microsoft Security Blog
Microsoft Security Blog
Security Archives - TechRepublic
Security Archives - TechRepublic
N
News and Events Feed by Topic
The Cloudflare Blog
Spread Privacy
Spread Privacy
酷 壳 – CoolShell
酷 壳 – CoolShell
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
B
Blog RSS Feed

Halo - 强大易用的开源建站工具 | 应用市场

ShaneYu EverUs Ethereal 主题漫游 软件分发管理 Moonlit Playground 山月记 Shortcode 初春图床 AI智能套件 文档 Cosolar 业余无线电 GardMap 通联网格地图 元数据字段管家 评论组件 Next 统一身份认证 Morpho Moesora 全能右键 保险箱插件 Earthquake Aurora InkNest Quiet 项目集 AI回评 AI Foundation Kaze 域名主题路由 代码增强(高亮+折叠+长图折叠) 氢·简 文章组件 Floating Particles Huohuo Weather Glass Vahlok AstraHub 星链 全局私密 业余无线电 QSL卡片管理系统 Bark 推送 微信读书(WeRead)信息展示 自定义社交分享卡片 Halorum 文章加密 KMath 轻言 Navidrome 播放器 家庭私厨 页面转换器 Sky Blog 3(macOS) 在线显示 邀请码注册 安全跳转助手 日程日历 Cartly 商城主题
演示站防护
2026-07-01 · via Halo - 强大易用的开源建站工具 | 应用市场

演示站防护

演示站防护是一个 Halo 插件,用来限制“演示角色”在 Halo 控制台、用户中心和核心 API 中执行高风险写操作。它适合公开演示站、试用环境、售前演示环境这类场景:访客可以登录体验后台,但不能发布文章、改用户、删资源、上传附件、改主题插件配置,别让人一顿乱点把站点霍霍没了。

功能体验

地址 账号/密码
管理端 demo/demo123.

交流群

点击链接加入群聊【halo博客-lywq插件】

功能介绍

  • 按 Halo 角色识别演示用户:配置项保存的是角色 metadata.name,插件会读取当前登录用户的真实角色绑定。
  • 按 HTTP 方法拦截危险操作:可分别控制 POSTPUTPATCH 写请求和 DELETE 删除请求。
  • 按路径模式保护接口:支持精确路径、* 单段通配、** 多段通配。
  • 支持放行路径:放行路径优先级高于保护路径,用于避免误拦插件自身接口或必须开放的接口。
  • 对前端返回结构化错误:被拦截时返回 403application/problem+json,提示 当前演示用户禁止操作
  • 默认关闭:安装后不会立刻影响管理员操作,需要手动启用。

这个插件是演示环境的兜底防护,不是 Halo RBAC 的替代品。演示账号本身也别乱给超级管理员权限,除非你已经把所有危险接口都配进保护路径里,不然就是往门口挂个锁、后墙留个洞,闹呢。

环境要求

  • Halo >= 2.25.0
  • Java 21+
  • Node.js 18+
  • pnpm

安装教程

  1. 构建插件:
./gradlew build
  1. 构建完成后,在 build/libs 目录找到插件 jar,例如:
build/libs/plugin-demo-guard-1.0.0-SNAPSHOT.jar
  1. 进入 Halo 控制台,打开 插件 页面。

  2. 上传并安装插件 jar。

  3. 启用插件后,进入插件设置页配置防护规则。

升级线上环境时,一定要上传新构建出来的 jar。只改本地代码不升级线上插件,线上当然没反应,这个锅代码不背。

使用教程

最小可用示例:禁止演示用户发布文章

如果你现在只想拦截这个发布接口:

/apis/api.console.halo.run/v1alpha1/posts/019f1b47-2f0e-75fa-a868-d5231f673d24/publish

保护路径应该配置成通配形式:

/apis/api.console.halo.run/v1alpha1/posts/*/publish

同时确认:

启用演示站防护:开启
拦截写请求:开启
演示角色标识:选择演示用户绑定的角色 metadata.name

发布文章接口是 PUT 请求,所以只开“拦截删除请求”没用,这地方别拧巴。

1. 创建演示角色

在 Halo 控制台创建一个专门给演示用户使用的角色,例如 演示角色

插件配置里最终保存的是角色的 metadata.name,通常类似:

role-jlijn3me

不用手填也行,插件设置页的“演示角色标识”会从 Halo 角色列表中选择并保存实际角色名。

2. 给演示用户绑定角色

创建或选择一个演示用户,例如 demo,并给它绑定上一步创建的演示角色。

如果演示用户没有绑定这个角色,插件不会把它当作演示用户处理。

3. 开启防护

在插件设置中配置:

启用演示站防护:开启
演示角色标识:选择演示角色
拦截写请求:开启
拦截删除请求:按需开启

4. 配置保护路径

保护路径只写 URL path,不要写协议、域名、端口和查询参数。

正确:

/apis/api.console.halo.run/v1alpha1/posts/*/publish

错误:

http://localhost:8090/apis/api.console.halo.run/v1alpha1/posts/*/publish

多个路径可以用换行、空格、逗号或分号分隔:

/apis/api.console.halo.run/v1alpha1/posts/*/publish
/apis/api.console.halo.run/v1alpha1/posts/*/unpublish
/apis/api.console.halo.run/v1alpha1/posts/*/recycle

也可以写成一行:

/apis/api.console.halo.run/v1alpha1/posts/*/publish /apis/api.console.halo.run/v1alpha1/posts/*/unpublish /apis/api.console.halo.run/v1alpha1/posts/*/recycle

5. 配置放行路径

放行路径优先级高于保护路径。默认放行插件自身接口:

/apis/console.demoguard.muyin.site/**

不要把放行路径写得太宽,例如:

/apis/**

这会把所有 Halo API 都放掉,防护直接变空气,配置了等于没配置。

配置项说明

配置项 说明 建议
启用演示站防护 总开关,关闭后不拦截任何请求。 配完角色和路径后再开启。
演示角色标识 演示角色的 metadata.name 数组。 使用设置页下拉选择,不要填显示名。
拦截写请求 拦截命中保护路径的 POSTPUTPATCH 演示站通常开启。
拦截删除请求 拦截命中保护路径的 DELETE 演示站通常开启。
保护路径 需要禁止演示用户访问的 API path。 只写 path,支持 ***
放行路径 优先放行的 API path。 保留插件自身接口,别写太宽。

路径匹配规则

  • * 匹配单个路径段。
  • ** 匹配多个路径段。
  • 只匹配 path,不匹配 query string。
  • 放行路径先匹配,命中后不再拦截。
  • GET 请求不会被“拦截写请求”拦截。
  • DELETE 请求只受“拦截删除请求”控制。

示例:禁止演示角色发布任意文章:

/apis/api.console.halo.run/v1alpha1/posts/*/publish

可匹配:

/apis/api.console.halo.run/v1alpha1/posts/019f1b47-2f0e-75fa-a868-d5231f673d24/publish

如果接口带查询参数,例如:

/apis/api.console.halo.run/v1alpha1/posts/xxx/publish?async=true

保护路径仍然只写:

/apis/api.console.halo.run/v1alpha1/posts/*/publish

常用保护路径示例

下面这些路径和插件默认配置保持一致,可以按你的演示站开放范围删减。原则很简单:不想让演示用户改的,就别心软。

文章发布、取消发布、回收:

/apis/api.console.halo.run/v1alpha1/posts/*/publish
/apis/api.console.halo.run/v1alpha1/posts/*/unpublish
/apis/api.console.halo.run/v1alpha1/posts/*/recycle

文章底层资源:

/apis/content.halo.run/v1alpha1/posts/**

用户、角色和权限:

/apis/console.api.security.halo.run/v1alpha1/users/**
/apis/api.console.halo.run/v1alpha1/users
/apis/api.console.halo.run/v1alpha1/users/test/permissions
/apis/api.console.halo.run/v1alpha1/users/-/password
/apis/api.console.halo.run/v1alpha1/users/-
/api/v1alpha1/users/**
/api/v1alpha1/roles/**

附件:

/apis/api.console.halo.run/v1alpha1/attachments/upload
/apis/storage.halo.run/v1alpha1/attachments/**

独立页面:

/apis/content.halo.run/v1alpha1/singlepages/**

主题和插件:

/apis/api.console.halo.run/v1alpha1/themes/*/reset-config
/apis/theme.halo.run/v1alpha1/themes/**
/apis/api.console.halo.run/v1alpha1/plugins/*/plugin-state
/apis/api.console.halo.run/v1alpha1/plugins/*/reset-config
/apis/plugin.halo.run/v1alpha1/plugins/**

系统配置和迁移:

/apis/console.api.halo.run/v1alpha1/systemconfigs/basic
/apis/migration.halo.run/v1alpha1/backups
/apis/console.api.migration.halo.run/v1alpha1/restorations

用户中心安全项:

/apis/uc.api.security.halo.run/v1alpha1/personalaccesstokens
/apis/uc.api.security.halo.run/v1alpha1/authentications/two-factor/settings/enabled
/apis/uc.api.security.halo.run/v1alpha1/authentications/two-factor/totp

不同 Halo 版本或插件可能会调整接口路径。拿不准就打开当前站点的 Swagger:

/swagger-ui/index.html

照真实接口路径配置,别靠猜。尤其是 reset-configresetconfig 这种命名,猜错一个字符就全白搭。

验证是否生效

  1. 使用演示用户登录 Halo 控制台。
  2. 在浏览器开发者工具的 Network 面板确认操作请求的 method 和 path。
  3. 执行受保护操作,例如发布文章。
  4. 预期返回 403,响应体包含 当前演示用户禁止操作
  5. 使用非演示角色账号重复同样操作,应该正常通过。

如果演示用户和管理员都被拦,通常是角色配错或账号角色混了;如果谁都不拦,先看总开关、请求方法、真实 path 和线上 jar 版本。别上来就怀疑玄学,十有八九是配置没对上。

被拦截时的响应

命中防护后,插件返回:

HTTP/1.1 403 Forbidden
Content-Type: application/problem+json

响应体:

{
  "status": 403,
  "title": "当前演示用户禁止操作",
  "detail": "当前演示用户禁止操作",
  "message": "当前演示用户禁止操作"
}

如果前端仍然只显示 403: Forbidden,说明前端统一错误处理没有读取 detailmessage 字段。后端已经把话递过去了,前端不接,那就是前端自己的脾气。

常见问题

本地有效,线上无效

优先检查这几件事:

  • 线上是否已经安装新构建的 jar。
  • 插件设置里的 enabled 是否为 true
  • 演示用户是否真的绑定了配置中的角色 metadata.name
  • 请求方法是否在拦截范围内,例如发布文章是 PUT,需要开启“拦截写请求”。
  • 保护路径是否只写 path,没有写域名、协议、端口。
  • 放行路径是否过宽,例如误写了 /apis/**
  • 当前线上 Halo 的真实接口路径是否和你配置的一致。

保护路径一整行配置为什么之前不生效

旧版本只按换行和逗号拆分路径。一整行空格分隔会被当成一个超长路径模式,自然匹配不到真实接口。

当前版本已经支持空格、换行、逗号和分号分隔。线上要获得这个能力,必须升级到包含该修复的新 jar。

为什么没进入演示角色判断

通常是当前请求没有可用登录态,或者插件版本还在使用较旧的过滤器链。当前版本在 Halo 安全认证之后读取用户信息,正常登录请求会进入演示角色判断。

为什么配置了角色还是没拦住

确认配置的是角色 metadata.name,不是显示名。显示名可以叫“演示角色”,但真正保存和匹配的一般是:

role-xxxxxxxx

开发约定

新建 Halo 插件必须优先使用官方脚手架:

pnpm create halo-plugin

不要复制已有插件目录改名初始化,容易带入脏配置、缓存和错误依赖。

本地开发

启动 Halo 开发服务:

./gradlew haloServer

前端开发:

cd ui
pnpm install
pnpm dev

热加载插件:

./gradlew reload

运行测试和构建:

./gradlew test
./gradlew build

许可证

GPL-3.0 © Lywq