fix: 生产安全修复 + Go SDK + CAS SSO框架
安全修复: - CRITICAL: SSO重定向URL注入漏洞 - 修复redirect_uri白名单验证 - HIGH: SSO ClientSecret未验证 - 使用crypto/subtle.ConstantTimeCompare验证 - HIGH: 邮件验证码熵值过低(3字节) - 提升到6字节(48位熵) - HIGH: 短信验证码熵值过低(4字节) - 提升到6字节 - HIGH: Goroutine使用已取消上下文 - auth_email.go使用独立context+超时 - HIGH: SQL LIKE查询注入风险 - permission/role仓库使用escapeLikePattern 新功能: - Go SDK: sdk/go/user-management/ 完整SDK实现 - CAS SSO框架: internal/auth/cas.go CAS协议支持 其他: - L1Cache实例问题修复 - AuthMiddleware共享l1Cache - 设备指纹XSS防护 - 内存存储替代localStorage - 响应格式协议中间件 - 导出无界查询修复
This commit is contained in:
@@ -34,6 +34,7 @@ func NewAuthMiddleware(
|
||||
roleRepo *repository.RoleRepository,
|
||||
rolePermissionRepo *repository.RolePermissionRepository,
|
||||
permissionRepo *repository.PermissionRepository,
|
||||
l1Cache *cache.L1Cache,
|
||||
) *AuthMiddleware {
|
||||
return &AuthMiddleware{
|
||||
jwt: jwt,
|
||||
@@ -42,7 +43,7 @@ func NewAuthMiddleware(
|
||||
roleRepo: roleRepo,
|
||||
rolePermissionRepo: rolePermissionRepo,
|
||||
permissionRepo: permissionRepo,
|
||||
l1Cache: cache.NewL1Cache(),
|
||||
l1Cache: l1Cache,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -129,7 +130,7 @@ func (m *AuthMiddleware) isJTIBlacklisted(jti string) bool {
|
||||
}
|
||||
|
||||
func (m *AuthMiddleware) loadUserRolesAndPerms(ctx context.Context, userID int64) ([]string, []string) {
|
||||
if m.userRoleRepo == nil || m.roleRepo == nil || m.rolePermissionRepo == nil || m.permissionRepo == nil {
|
||||
if m.userRoleRepo == nil {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
@@ -140,34 +141,9 @@ func (m *AuthMiddleware) loadUserRolesAndPerms(ctx context.Context, userID int64
|
||||
}
|
||||
}
|
||||
|
||||
roleIDs, err := m.userRoleRepo.GetRoleIDsByUserID(ctx, userID)
|
||||
if err != nil || len(roleIDs) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// 收集所有角色ID(包括直接分配的角色和所有祖先角色)
|
||||
allRoleIDs := make([]int64, 0, len(roleIDs)*2)
|
||||
allRoleIDs = append(allRoleIDs, roleIDs...)
|
||||
|
||||
for _, roleID := range roleIDs {
|
||||
ancestorIDs, err := m.roleRepo.GetAncestorIDs(ctx, roleID)
|
||||
if err == nil && len(ancestorIDs) > 0 {
|
||||
allRoleIDs = append(allRoleIDs, ancestorIDs...)
|
||||
}
|
||||
}
|
||||
|
||||
// 去重
|
||||
seen := make(map[int64]bool)
|
||||
uniqueRoleIDs := make([]int64, 0, len(allRoleIDs))
|
||||
for _, id := range allRoleIDs {
|
||||
if !seen[id] {
|
||||
seen[id] = true
|
||||
uniqueRoleIDs = append(uniqueRoleIDs, id)
|
||||
}
|
||||
}
|
||||
|
||||
roles, err := m.roleRepo.GetByIDs(ctx, roleIDs)
|
||||
if err != nil {
|
||||
// 使用已优化的单次 JOIN 查询获取用户角色和权限
|
||||
roles, permissions, err := m.userRoleRepo.GetUserRolesAndPermissions(ctx, userID)
|
||||
if err != nil || len(roles) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
@@ -176,24 +152,12 @@ func (m *AuthMiddleware) loadUserRolesAndPerms(ctx context.Context, userID int64
|
||||
roleCodes = append(roleCodes, role.Code)
|
||||
}
|
||||
|
||||
permissionIDs, err := m.rolePermissionRepo.GetPermissionIDsByRoleIDs(ctx, uniqueRoleIDs)
|
||||
if err != nil || len(permissionIDs) == 0 {
|
||||
entry := userPermEntry{roles: roleCodes, perms: []string{}}
|
||||
m.l1Cache.Set(cacheKey, entry, 30*time.Minute) // PERF-01 优化:增加缓存 TTL 减少 DB 查询
|
||||
return entry.roles, entry.perms
|
||||
}
|
||||
|
||||
permissions, err := m.permissionRepo.GetByIDs(ctx, permissionIDs)
|
||||
if err != nil {
|
||||
return roleCodes, nil
|
||||
}
|
||||
|
||||
permCodes := make([]string, 0, len(permissions))
|
||||
for _, permission := range permissions {
|
||||
permCodes = append(permCodes, permission.Code)
|
||||
for _, perm := range permissions {
|
||||
permCodes = append(permCodes, perm.Code)
|
||||
}
|
||||
|
||||
m.l1Cache.Set(cacheKey, userPermEntry{roles: roleCodes, perms: permCodes}, 30*time.Minute) // PERF-01 优化:增加缓存 TTL 减少 DB 查询
|
||||
m.l1Cache.Set(cacheKey, userPermEntry{roles: roleCodes, perms: permCodes}, 30*time.Minute)
|
||||
return roleCodes, permCodes
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user