6.2 太牛了!动态权限控制竟然可以这样实现?

2 阅读5分钟

// compareValues 比较值 func compareValues(left, right interface{}) int { // 简化实现,实际应用中需要更完善的类型处理 switch left := left.(type) { case int: if right, ok := right.(int); ok { if left > right { return 1 } else if left < right { return -1 } return 0 } case float64: if right, ok := right.(float64); ok { if left > right { return 1 } else if left < right { return -1 } return 0 } case string: if right, ok := right.(string); ok { return strings.Compare(left, right) } } return 0 }

// inValues 检查值是否在数组中 func inValues(value, array interface{}) bool { if arr, ok := array.([]interface{}); ok { for _, item := range arr { if item == value { return true } } } return false }

// containsValue 检查数组是否包含值 func containsValue(array, value interface{}) bool { if arr, ok := array.([]interface{}); ok { for _, item := range arr { if item == value { return true } } } return false }

// GenerateCacheKey 生成缓存键 func (hac *HybridAccessControl) GenerateCacheKey(request *AccessRequest) string { // 简化实现,实际应用中需要更复杂的键生成策略 return fmt.Sprintf("%s:%s:%s", request.Subject.ID, request.Resource.ID, request.Action.Name) }

// CheckAccess 检查访问权限 func (hac *HybridAccessControl) CheckAccess(request *AccessRequest) (*AccessDecision, error) { // 生成缓存键 cacheKey := hac.GenerateCacheKey(request)

// 检查缓存
if decision, exists := hac.cache.Get(cacheKey); exists {
    return decision, nil
}

// 通过策略引擎评估
decision, err := hac.policyEngine.Evaluate(request)
if err != nil {
    return nil, fmt.Errorf("policy engine evaluation failed: %w", err)
}

// 如果策略引擎没有给出决策,则使用RBAC+ABAC混合评估
if decision.DecisionType == DecisionTypeDefault {
    decision, err = hac.evaluateHybrid(request)
    if err != nil {
        return nil, fmt.Errorf("hybrid evaluation failed: %w", err)
    }
}

// 缓存决策
hac.cache.Set(cacheKey, decision)

return decision, nil

}

// evaluateHybrid 混合评估 func (hac *HybridAccessControl) evaluateHybrid(request *AccessRequest) (*AccessDecision, error) { // 根据配置决定优先级 if hac.config.RBACPriority { // RBAC优先 return hac.evaluateRBACFirst(request) } else { // ABAC优先 return hac.evaluateABACFirst(request) } }

// evaluateRBACFirst RBAC优先评估 func (hac *HybridAccessControl) evaluateRBACFirst(request *AccessRequest) (*AccessDecision, error) { // 首先尝试RBAC评估 rbacAllowed, err := hac.checkRBAC(request) if err == nil && rbacAllowed { return &AccessDecision{ Allowed: true, DecisionType: DecisionTypeRBAC, Reason: "RBAC permission granted", Attributes: make(map[string]interface{}), Timestamp: time.Now(), }, nil }

// 如果RBAC不允许,再尝试ABAC评估
abacAllowed, err := hac.checkABAC(request)
if err != nil {
    return nil, fmt.Errorf("ABAC evaluation failed: %w", err)
}

if abacAllowed {
    return &AccessDecision{
        Allowed:      true,
        DecisionType: DecisionTypeABAC,
        Reason:       "ABAC permission granted",
        Attributes:   make(map[string]interface{}),
        Timestamp:    time.Now(),
    }, nil
}

// 都不允许
return &AccessDecision{
    Allowed:      false,
    DecisionType: DecisionTypeDefault,
    Reason:       "Both RBAC and ABAC denied access",
    Attributes:   make(map[string]interface{}),
    Timestamp:    time.Now(),
}, nil

}

// evaluateABACFirst ABAC优先评估 func (hac *HybridAccessControl) evaluateABACFirst(request *AccessRequest) (*AccessDecision, error) { // 首先尝试ABAC评估 abacAllowed, err := hac.checkABAC(request) if err == nil && abacAllowed { return &AccessDecision{ Allowed: true, DecisionType: DecisionTypeABAC, Reason: "ABAC permission granted", Attributes: make(map[string]interface{}), Timestamp: time.Now(), }, nil }

// 如果ABAC不允许,再尝试RBAC评估
rbacAllowed, err := hac.checkRBAC(request)
if err != nil {
    return nil, fmt.Errorf("RBAC evaluation failed: %w", err)
}

if rbacAllowed {
    return &AccessDecision{
        Allowed:      true,
        DecisionType: DecisionTypeRBAC,
        Reason:       "RBAC permission granted",
        Attributes:   make(map[string]interface{}),
        Timestamp:    time.Now(),
    }, nil
}

// 都不允许
return &AccessDecision{
    Allowed:      false,
    DecisionType: DecisionTypeDefault,
    Reason:       "Both ABAC and RBAC denied access",
    Attributes:   make(map[string]interface{}),
    Timestamp:    time.Now(),
}, nil

}

// checkRBAC 检查RBAC权限 func (hac *HybridAccessControl) checkRBAC(request *AccessRequest) (bool, error) { // 从主体属性中获取用户ID userID, ok := request.Subject.Attributes["user_id"].(string) if !ok { return false, fmt.Errorf("user_id not found in subject attributes") }

// 从资源属性中获取资源标识
resourceID, ok := request.Resource.Attributes["id"].(string)
if !ok {
    return false, fmt.Errorf("resource id not found in resource attributes")
}

// 检查用户是否有对应权限
permission := fmt.Sprintf("%s:%s", request.Action.Name, resourceID)
return hac.rbacService.CheckUserPermission(userID, permission)

}

// checkABAC 检查ABAC权限 func (hac *HybridAccessControl) checkABAC(request *AccessRequest) (bool, error) { return hac.abacService.CheckPermission( request.Subject, request.Resource, request.Action, request.Environment) }

// DynamicPolicyManager 动态策略管理器 type DynamicPolicyManager struct { policyEngine *PolicyEngine rbacService *AdvancedRBACService abacService *ABACService }

// NewDynamicPolicyManager 创建动态策略管理器 func NewDynamicPolicyManager(policyEngine *PolicyEngine, rbacService *AdvancedRBACService, abacService *ABACService) *DynamicPolicyManager { return &DynamicPolicyManager{ policyEngine: policyEngine, rbacService: rbacService, abacService: abacService, } }

// AddDynamicRolePolicy 添加动态角色策略 func (dpm *DynamicPolicyManager) AddDynamicRolePolicy(roleID, resourceType, action string, conditions []PolicyCondition) { rule := &HybridPolicyRule{ ID: fmt.Sprintf("dynamic_role_%s_%s_%s", roleID, resourceType, action), Name: fmt.Sprintf("Dynamic Role Policy for %s", roleID), Description: fmt.Sprintf("Dynamic policy for role %s on %s resources with %s action", roleID, resourceType, action), Type: PolicyRuleTypeRBAC, Priority: 50, Conditions: conditions, Effect: EffectPermit, Metadata: map[string]interface{}{ "role_id": roleID, "resource_type": resourceType, "action": action, }, }

dpm.policyEngine.AddPolicyRule(rule)

}

// AddDynamicAttributePolicy 添加动态属性策略 func (dpm *DynamicPolicyManager) AddDynamicAttributePolicy(subjectAttr, resourceAttr, action string, conditions []PolicyCondition) { rule := &HybridPolicyRule{ ID: fmt.Sprintf("dynamic_attr_%s_%s_%s", subjectAttr, resourceAttr, action), Name: fmt.Sprintf("Dynamic Attribute Policy"), Description: fmt.Sprintf("Dynamic policy based on subject %s and resource %s with %s action", subjectAttr, resourceAttr, action), Type: PolicyRuleTypeABAC, Priority: 40, Conditions: conditions, Effect: EffectPermit, Metadata: map[string]interface{}{ "subject_attr": subjectAttr, "resource_attr": resourceAttr, "action": action, }, }

dpm.policyEngine.AddPolicyRule(rule)

}

// RemoveDynamicPolicy 移除动态策略 func (dpm *DynamicPolicyManager) RemoveDynamicPolicy(ruleID string) { dpm.policyEngine.RemovePolicyRule(ruleID) }

// TimeBasedPolicyManager 基于时间的策略管理器 type TimeBasedPolicyManager struct { policyEngine *PolicyEngine timer *time.Timer }

// NewTimeBasedPolicyManager 创建基于时间的策略管理器 func NewTimeBasedPolicyManager(policyEngine *PolicyEngine) *TimeBasedPolicyManager { return &TimeBasedPolicyManager{ policyEngine: policyEngine, } }

// AddTimeBasedPolicy 添加基于时间的策略 func (tbpm *TimeBasedPolicyManager) AddTimeBasedPolicy(rule *HybridPolicyRule, activationTime time.Time) { duration := time.Until(activationTime) if duration <= 0 { // 立即激活 tbpm.policyEngine.AddPolicyRule(rule) return }

// 定时激活
tbpm.timer = time.AfterFunc(duration, func() {
    tbpm.policyEngine.AddPolicyRule(rule)
})

}

// ContextAwarePolicyManager 上下文感知策略管理器 type ContextAwarePolicyManager struct { policyEngine *PolicyEngine }

// NewContextAwarePolicyManager 创建上下文感知策略管理器 func NewContextAwarePolicyManager(policyEngine *PolicyEngine) *ContextAwarePolicyManager { return &ContextAwarePolicyManager{ policyEngine: policyEngine, } }

// AddContextAwarePolicy 添加上下文感知策略 func (capm *ContextAwarePolicyManager) AddContextAwarePolicy(rule *HybridPolicyRule, contextChecker func(interface{}) bool) { // 这里可以实现基于上下文的策略管理 // 例如根据用户行为、系统负载等动态调整策略 capm.policyEngine.AddPolicyRule(rule) }

// 使用示例 func main() { // 创建混合访问控制系统 config := &HybridConfig{ RBACPriority: true, CacheTTL: 5 * time.Minute, EnableSimulation: true, }

hac := NewHybridAccessControl(config)

// 创建动态策略管理器
dynamicPM := NewDynamicPolicyManager(hac.policyEngine, hac.rbacService, hac.abacService)

// 添加动态角色策略:管理员在工作时间可以访问所有资源
workTimeConditions := []PolicyCondition{
    {
        Type:     ConditionTypeTime,
        Field:    "hour",
        Operator: "ge",
        Value:    9,
    },
    {
        Type:     ConditionTypeTime,
        Field:    "hour",
        Operator: "le",
        Value:    18,
    },
}

dynamicPM.AddDynamicRolePolicy("admin", "any", "any", workTimeConditions)

// 添加动态属性策略:同一部门的用户可以查看公开文档
deptConditions := []PolicyCondition{
    {
        Type:     ConditionTypeAttribute,
        Field:    "subject.department",
        Operator: "eq",
        Value:    "${resource.department}",
    },
    {
        Type:     ConditionTypeAttribute,
        Field:    "resource.visibility",
        Operator: "eq",
        Value:    "public",
    },
}

dynamicPM.AddDynamicAttributePolicy("department", "department", "read", deptConditions)

// 创建访问请求
request := &AccessRequest{
    Subject: &Subject{
        ID: "user001",
        Attributes: map[string]interface{}{
            "user_id":    "user001",
            "role":       "manager",
            "department": "sales",
            "level":      5,
        },
    },
    Resource: &Resource{
        ID:   "doc001",
        Type: "document",
        Attributes: map[string]interface{}{
            "id":         "doc001",
            "title":      "Sales Report",
            "owner":      "user002",
            "department": "sales",
            "visibility": "public",
            "sensitivity": "normal",
        },
    },
    Action: &Action{
        Name: "read",
    },
    Environment: &Environment{
        Attributes: map[string]interface{}{
            "ip":        "192.168.1.100",
            "location":  "office",
            "device":    "desktop",
            "time_zone": "UTC+8",
        },
    },
}

// 检查访问权限
fmt.Println("=== 动态权限控制测试 ===")

decision, err := hac.CheckAccess(request)
if err != nil {
    fmt.Printf("权限检查出错: %v\n", err)
    return
}

fmt.Printf("访问决策: %+v\n", decision)
fmt.Printf("允许访问: %t\n", decision.Allowed)
fmt.Printf("决策类型: %s\n", decision.DecisionType)
fmt.Printf("决策原因: %s\n", decision.Reason)

// 测试缓存效果
fmt.Println("\n--- 测试缓存效果 ---")
startTime := time.Now()
for i := 0; i < 100; i++ {
    hac.CheckAccess(request)
}
endTime := time.Now()

fmt.Printf("100次访问检查耗时: %v\n", endTime.Sub(startTime))

// 显示当前策略
fmt.Println("\n=== 当前策略规则 ===")
hac.policyEngine.mutex.RLock()
for _, rule := range hac.policyEngine.rules {
    fmt.Printf("规则ID: %s\n", rule.ID)
    fmt.Printf("  名称: %s\n", rule.Name)
    fmt.Printf("  类型: %s\n", rule.Type)
    fmt.Printf("  优先级: %d\n", rule.Priority)
    fmt.Printf("  效果: %s\n", rule.Effect)
    fmt.Printf("  条件数量: %d\n", len(rule.Conditions))
    fmt.Println()
}
hac.policyEngine.mutex.RUnlock()

}