我有一台的 16C32G 服务器,部署了 Sillytavern 服务,有点想把它福利资源分享给出去。所以我开始研究如何Sillytavern对接 SSO 的方案
首先查阅了 Sillytavern 官方文档 ,文档中简要说明:
Sign in with SSO
If your SSO-provided username exactly matches the username of a SillyTavern user account, you can sign in to SillyTavern as that user by SSO.
To do this, enable autheliaAuth in config.yaml.
这段说明相当简洁,系统似乎只是匹配已存在的用户名,而不会自动为 SSO 登录的新用户创建账号。
为了确认我的猜测,我决定看下源码
// filepath: src/users.js#L750
async function autheliaUserLogin(request) {
if (!request.session) {
return false;
}
// 获取 Remote-User 的值
const remoteUser = request.get('Remote-User');
if (!remoteUser) {
return false;
}
// 匹配 Remote-User 值的用户, 并切换到该用户
const userHandles = await getAllUserHandles();
for (const userHandle of userHandles) {
if (remoteUser === userHandle) {
const user = await storage.getItem(toKey(userHandle));
if (user && user.enabled) {
request.session.handle = userHandle;
return true;
}
}
}
return false;
}
从源码中可以看出 Sillytavern 的 SSO 实现确实相当基础:
它仅从 HTTP 请求头中获取 Remote-User 值
检查该值是否与系统中已存在的用户名匹配
若匹配成功且用户已启用,则允许登录
若无匹配用户,直接返回 false,没有任何新用户创建逻辑
这种实现方式使得 Sillytavern 的 SSO 功能在实际应用中相当受限:
它只能作为已有用户的鉴权渠道
无法自动为新的 SSO 用户创建账号
管理员需要预先创建所有可能通过 SSO 登录的用户账号
对于我希望将服务作为开放资源分享的目标而言,这种 SSO 实现方式显然不够友好,需要大量的手动前期工作或自定义开发来弥补这一缺陷。