エンタープライズ アプリケーション向けの動的 RBAC システムの実装 - 簡略化

王林
リリース: 2024-08-14 11:02:37
オリジナル
1161 人が閲覧しました

Implementing a Dynamic RBAC System for Enterprise Applications - Simplified

導入

今日のデジタル環境では、リソースとデータを保護するために効果的なアクセス管理が重要です。ロールベースのアクセス制御 (RBAC) システムは、ユーザーの権限とロールを管理するための構造化されたアプローチを提供します。このブログでは、さまざまなアプリケーションのニーズに合わせた RBAC システムの 2 つのバリエーション (共通ビジネス アプリケーションとエンタープライズ ビジネス アプリケーション) について概説します。

概念を説明するために、アクセス制御を管理するサービスのデモ コード スニペットと、RBAC システムで使用される各テーブルの詳細な説明を提供します。

RBAC システムコンポーネント

一般的なビジネス アプリケーション

ほとんどの一般的なビジネス アプリケーションでは、RBAC システムを合理化し、複雑さを増すことなくロールと権限を効果的に管理できます。主要なコンポーネントは次のとおりです:

  1. ユーザーテーブル

    • 目的: ユーザー名、パスワードハッシュ、電子メール、クリアランスレベルなどのユーザー情報を保存します。
    • キー列: user_id、username、password_hash、電子メール、部門、clearance_level
  2. 役割テーブル

    • 目的: アプリケーション内のロールを定義し、各ロールの名前と説明を詳しく説明します。
    • キー列: role_id、role_name、description
  3. モジュールテーブル

    • 目的: アプリケーション モジュールまたはリソースをリストし、その目的と機能を説明します。
    • キー列: module_id、module_name、description
  4. Module_Permission テーブル

    • 目的: 読み取りアクセスや書き込みアクセスなど、各モジュールに関連付けられた権限を指定します。
    • キー列: module_permission_id、module_id、permission_type
  5. Role_Permission テーブル

    • 目的: ロールをモジュール権限にマッピングし、ロールがモジュールに対して実行できるアクションを決定します。
    • キー列: role_permission_id、role_id、module_permission_id
  6. User_Role テーブル

    • 目的: ユーザーとロール間の関係を管理し、ロールベースのアクセス制御を有効にします。
    • キー列: user_role_id、user_id、role_id

エンタープライズ ビジネス アプリケーション

エンタープライズ ビジネス アプリケーションでは、より複雑なアクセス制御のニーズを処理するために追加のコンポーネントが必要になる場合があります。これらには以下が含まれます:

  1. ポリシーテーブル

    • 目的: 追加のアクセス ルールと条件を定義し、より詳細な制御を提供します。
    • キー列: ポリシー ID、ポリシー名、説明
  2. Role_Policy テーブル

    • 目的: ロールをポリシーにリンクし、ロールを特定のルールと条件によって管理できるようにします。
    • キー列: role_policy_id、role_id、policy_id
  3. User_Policy テーブル

    • 目的: ポリシーをユーザーに直接割り当て、個々の権限に対応します。
    • キー列: user_policy_id、user_id、policy_id
  4. Policy_Condition テーブル

    • 目的: コンテキストまたは属性ベースの制約など、ポリシーの条件を指定します。
    • キー列:policy_condition_id、policy_id、condition_type、condition_value
  5. Contextual_Permission テーブル

    • 目的: ユーザーの部門や場所など、特定のコンテキストに基づいてポリシーを適用します。
    • キー列: context_permission_id、policy_id、context_type、context_value
  6. Temporal_Constraint テーブル

    • 目的: 時間ベースのアクセスを管理し、ポリシーの有効性の開始時刻と終了時刻を定義します。
    • キー列:temporal_constraint_id、policy_id、start_time、end_time
  7. 委任テーブル

    • 目的: 一時的な役割の割り当てを容易にし、ユーザーが有効期限を指定して役割を委任できるようにします。
    • キー列: delegation_id、delegate_user_id、delegator_user_id、role_id、delegated_at、expiration_date
  8. Audit_Log テーブル

    • 目的: セキュリティとコンプライアンスの監査のために、ユーザーのアクション、モジュールの操作、ロールの変更を記録します。
    • キー列: Audit_log_id、user_id、action、module_id、role_id、タイムスタンプ、詳細

デモコード: アクセス制御サービス

これは、Java での AccessControlService のサンプル実装であり、動的 RBAC システムでアクセス制御を管理する方法を示しています。この例では、重要なコンポーネントを取り上げ、アクセス許可とポリシーを処理する方法を示します。

import java.time.LocalDateTime;
import java.util.List;

@Service
@Transactional
public class AccessControlService {

    @Autowired
    private UserRepository userRepository;

    @Autowired
    private RoleRepository roleRepository;

    @Autowired
    private ModulePermissionRepository modulePermissionRepository;

    @Autowired
    private RolePermissionRepository rolePermissionRepository;

    @Autowired
    private UserRoleRepository userRoleRepository;

    @Autowired
    private PolicyRepository policyRepository;

    @Autowired
    private UserPolicyRepository userPolicyRepository;

    @Autowired
    private RolePolicyRepository rolePolicyRepository;

    @Autowired
    private PolicyConditionRepository policyConditionRepository;

    @Autowired
    private ContextualPermissionRepository contextualPermissionRepository;

    @Autowired
    private TemporalConstraintRepository temporalConstraintRepository;

    @Autowired
    private DelegationRepository delegationRepository;

    public boolean hasAccess(String username, Long moduleId, String permissionType) {
        // Fetch user
        User user = userRepository.findByUsername(username);
        if (user == null) {
            return false;
        }

        // Check if user has any delegations
        boolean hasDelegatedAccess = checkDelegatedAccess(user.getUserId(), moduleId, permissionType);
        if (hasDelegatedAccess) {
            return true;
        }

        // Check if user has direct access via roles
        List<UserRole> userRoles = userRoleRepository.findByUserId(user.getUserId());
        for (UserRole userRole : userRoles) {
            List<RolePermission> rolePermissions = rolePermissionRepository.findByRoleId(userRole.getRoleId());
            for (RolePermission rolePermission : rolePermissions) {
                ModulePermission modulePermission = modulePermissionRepository.findById(rolePermission.getModulePermissionId()).orElse(null);
                if (modulePermission != null && modulePermission.getModuleId().equals(moduleId) && modulePermission.getPermissionType().equals(permissionType)) {
                    // Check if role has any associated policies
                    if (hasPolicyAccess(user.getUserId(), moduleId, permissionType, modulePermission.getModuleId())) {
                        return true;
                    }
                }
            }
        }

        return false;
    }

    private boolean checkDelegatedAccess(Long userId, Long moduleId, String permissionType) {
        List<Delegation> delegations = delegationRepository.findByDelegateUserId(userId);
        LocalDateTime now = LocalDateTime.now();
        for (Delegation delegation : delegations) {
            // Check if delegation is expired
            if (delegation.getExpirationDate() != null && delegation.getExpirationDate().isBefore(now)) {
                continue;
            }

            List<RolePermission> rolePermissions = rolePermissionRepository.findByRoleId(delegation.getRoleId());
            for (RolePermission rolePermission : rolePermissions) {
                ModulePermission modulePermission = modulePermissionRepository.findById(rolePermission.getModulePermissionId()).orElse(null);
                if (modulePermission != null && modulePermission.getModuleId().equals(moduleId) && modulePermission.getPermissionType().equals(permissionType)) {
                    return true;
                }
            }
        }
        return false;
    }

    private boolean hasPolicyAccess(Long userId, Long moduleId, String permissionType, Long modulePermissionId) {
        // Check policies assigned directly to the user
        List<UserPolicy> userPolicies = userPolicyRepository.findByUserId(userId);
        for (UserPolicy userPolicy : userPolicies) {
            if (isPolicyValid(userPolicy.getPolicyId(), moduleId, permissionType)) {
                return true;
            }
        }

        // Check policies assigned to roles
        List<UserRole> userRoles = userRoleRepository.findByUserId(userId);
        for (UserRole userRole : userRoles) {
            List<RolePolicy> rolePolicies = rolePolicyRepository.findByRoleId(userRole.getRoleId());
            for (RolePolicy rolePolicy : rolePolicies) {
                if (isPolicyValid(rolePolicy.getPolicyId(), moduleId, permissionType)) {
                    return true;
                }
            }
        }

        return false;
    }

    private boolean isPolicyValid(Long policyId, Long moduleId, String permissionType) {
        // Check policy conditions
        List<PolicyCondition> conditions = policyConditionRepository.findByPolicyId(policyId);
        for (PolicyCondition condition : conditions) {
            // Add logic to evaluate conditions based on conditionType and conditionValue
            // e.g., Check if context or attribute matches the condition
        }

        // Check contextual permissions
        List<ContextualPermission> contextualPermissions = contextualPermissionRepository.findByPolicyId(policyId);
        for (ContextualPermission contextualPermission : contextualPermissions) {
            // Add logic to evaluate contextual permissions
            // e.g., Check if current context matches the contextualPermission
        }

        // Check temporal constraints
        List<TemporalConstraint> temporalConstraints = temporalConstraintRepository.findByPolicyId(policyId);
        for (TemporalConstraint temporalConstraint : temporalConstraints) {
            LocalDateTime now = LocalDateTime.now();
            if (now.isBefore(temporalConstraint.getStartTime()) || now.isAfter(temporalConstraint.getEndTime())) {
                return false;
            }
        }

        return true;
    }
}
ログイン後にコピー

結論

一般的なビジネス アプリケーションとエンタープライズ ビジネス アプリケーションを区別することで、RBAC システムをカスタマイズできます

以上がエンタープライズ アプリケーション向けの動的 RBAC システムの実装 - 簡略化の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:dev.to
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート