feat: support permanent credentials and overlapping token rotation

This commit is contained in:
2026-09-27 11:45:15 +08:00
parent 87aa710013
commit 385a618154
29 changed files with 718 additions and 161 deletions

View File

@@ -46,18 +46,23 @@ func (s *TaskStore) transaction(ctx context.Context, token auth.Token, action st
}
func authenticate(ctx context.Context, tx *sql.Tx, token auth.Token) (auth.Permissions, error) {
var digest core.Digest
var raw []byte
err := tx.QueryRowContext(ctx, `SELECT c.secret_digest,c.permissions FROM orbit_credentials c
var raw, previous []byte
var currentValid, previousValid bool
err := tx.QueryRowContext(ctx, `SELECT c.secret_digest,c.permissions,c.previous_secret_digest,
(c.expires_at IS NULL OR c.expires_at>UTC_TIMESTAMP(6)),
COALESCE(c.previous_valid_until>UTC_TIMESTAMP(6),FALSE) FROM orbit_credentials c
JOIN orbit_namespaces n ON n.id=c.namespace_id JOIN orbit_applications a ON a.id=n.application_id
WHERE c.namespace_id=? AND c.id=? AND c.revoked_at IS NULL
AND (c.expires_at IS NULL OR c.expires_at>UTC_TIMESTAMP(6)) AND n.enabled=TRUE AND a.enabled=TRUE FOR SHARE`, token.NamespaceID, token.CredentialID).Scan(&digest, &raw)
AND n.enabled=TRUE AND a.enabled=TRUE FOR SHARE`, token.NamespaceID, token.CredentialID).Scan(&digest, &raw, &previous, &currentValid, &previousValid)
if errors.Is(err, sql.ErrNoRows) {
return auth.Permissions{}, fault.Unauthorized
}
if err != nil {
return auth.Permissions{}, err
}
if subtle.ConstantTimeCompare(digest[:], token.Digest[:]) != 1 {
currentMatch := subtle.ConstantTimeCompare(digest[:], token.Digest[:])
previousMatch := subtle.ConstantTimeCompare(previous, token.Digest[:])
if !(currentValid && currentMatch == 1) && !(previousValid && previousMatch == 1) {
// 控制台会话使用独立的短期令牌摘要,不轮换也不覆盖业务 SDK
// 凭据。只有经过会话表、账号、命名空间和应用启停状态联合校验,
// 才允许沿用该业务凭据的权限快照。