fix(security): Q2 Chunk 2 — 多租户安全加固 + 限流 fail-closed

- auth_service::refresh() 添加 tenant_id 校验
- user_service get_by_id/update/delete/assign_roles 改为数据库级 tenant_id 过滤
- 限流中间件改为 fail-closed:Redis 不可达时返回 429 而非放行
This commit is contained in:
iven
2026-04-17 17:45:59 +08:00
parent 39a12500e3
commit 080d2cb3d6
3 changed files with 46 additions and 14 deletions

View File

@@ -180,6 +180,17 @@ impl AuthService {
.map_err(|e| AuthError::Validation(e.to_string()))?
.ok_or(AuthError::TokenRevoked)?;
// 验证用户属于 JWT 中声明的租户
if user_model.tenant_id != claims.tid {
tracing::warn!(
user_id = %claims.sub,
jwt_tenant = %claims.tid,
actual_tenant = %user_model.tenant_id,
"Token tenant_id 与用户实际租户不匹配"
);
return Err(AuthError::TokenRevoked);
}
let role_resps = Self::get_user_role_resps(claims.sub, claims.tid, db).await?;
let user_resp = UserResp {
id: user_model.id,

View File

@@ -126,11 +126,13 @@ impl UserService {
tenant_id: Uuid,
db: &sea_orm::DatabaseConnection,
) -> AuthResult<UserResp> {
let user_model = user::Entity::find_by_id(id)
let user_model = user::Entity::find()
.filter(user::Column::Id.eq(id))
.filter(user::Column::TenantId.eq(tenant_id))
.filter(user::Column::DeletedAt.is_null())
.one(db)
.await
.map_err(|e| AuthError::Validation(e.to_string()))?
.filter(|u| u.tenant_id == tenant_id && u.deleted_at.is_none())
.ok_or_else(|| AuthError::Validation("用户不存在".to_string()))?;
let roles = Self::fetch_user_role_resps(id, tenant_id, db).await?;
@@ -193,11 +195,13 @@ impl UserService {
req: &UpdateUserReq,
db: &sea_orm::DatabaseConnection,
) -> AuthResult<UserResp> {
let user_model = user::Entity::find_by_id(id)
let user_model = user::Entity::find()
.filter(user::Column::Id.eq(id))
.filter(user::Column::TenantId.eq(tenant_id))
.filter(user::Column::DeletedAt.is_null())
.one(db)
.await
.map_err(|e| AuthError::Validation(e.to_string()))?
.filter(|u| u.tenant_id == tenant_id && u.deleted_at.is_none())
.ok_or_else(|| AuthError::Validation("用户不存在".to_string()))?;
let next_ver = check_version(req.version, user_model.version)
@@ -247,11 +251,13 @@ impl UserService {
db: &sea_orm::DatabaseConnection,
event_bus: &EventBus,
) -> AuthResult<()> {
let user_model = user::Entity::find_by_id(id)
let user_model = user::Entity::find()
.filter(user::Column::Id.eq(id))
.filter(user::Column::TenantId.eq(tenant_id))
.filter(user::Column::DeletedAt.is_null())
.one(db)
.await
.map_err(|e| AuthError::Validation(e.to_string()))?
.filter(|u| u.tenant_id == tenant_id && u.deleted_at.is_none())
.ok_or_else(|| AuthError::Validation("用户不存在".to_string()))?;
let current_version = user_model.version;
@@ -294,11 +300,13 @@ impl UserService {
db: &sea_orm::DatabaseConnection,
) -> AuthResult<Vec<RoleResp>> {
// 验证用户存在
let _user = user::Entity::find_by_id(user_id)
let _user = user::Entity::find()
.filter(user::Column::Id.eq(user_id))
.filter(user::Column::TenantId.eq(tenant_id))
.filter(user::Column::DeletedAt.is_null())
.one(db)
.await
.map_err(|e| AuthError::Validation(e.to_string()))?
.filter(|u| u.tenant_id == tenant_id && u.deleted_at.is_none())
.ok_or_else(|| AuthError::Validation("用户不存在".to_string()))?;
// 验证所有角色存在且属于当前租户