2013-07-01 6 views
10

Apache Shiroフレームワークを使用してWebアプリケーションを保護しようとしています(UIはVaadin 6に基づいています)。シロのサイトのすべての例を見て、何時間もグーグル探検しましたが、以下の要件に対処するきれいな方法を見つけることはできません。Apache Shiroを使用して階層的な役割/権限を処理するにはどうすればよいですか?

アプリケーションは、企業階層内の特定の部門に属するアクティビティを作成するプロジェクト管理ツールの一種です。各ユーザーは複数の部署で働くことができ、各部署で異なるセキュリティ役割を果たします。例:

 
Department A  - User is 'Manager' here 
Department B 
    Department C  - User is 'Admin' here 
    Department D 

ユーザー部門A ユーザーの「マネージャ」ではまた、(C部門の祖先である)部門Dのための「管理者の役割を継承しなければならない部署C ユーザーに「管理者」です。

ので、(私はいくつかの部門に属するアクティビティを表示したいと仮定した場合)基本的なパーミッションチェックをするようになります:アクティビティのユーザーが表示しようとしている場合

  1. チェック部門のユーザーに所属する役割を持っています。
  2. この部門の彼の役割に基づいて必要な権限を持っていることを確認してください。

私は現在、「システム全体の役割」だけでなく「この特定の部門の役割」という概念を実装する方法を理解していません。

上記の例を「activity:view:123」のような許可文字列に変換するにはどうすればよいですか?そして、ビジネスロジックのパーミッションをどうやってチェックするのですか?

もう1つの疑問は、Shiroの実装です。すぐに使用できるソリューションを使用したいのですが、独自の実装を提供するための最小限の努力が必要です。しかし、Shiroの組み込み実装は単純なケースのためだけに設計されているようです。複雑な認証の実装の例はありますか?(上記のケースをカバーできますか?)

答えて

3

誰かにとって便利なこの問題に対する私の解決策を説明したいだけです。私はこれが最適ではないかもしれないと感じているので、よりクリーンな実装についての提案にはまだオープンしています。

私は次のアクション確保する必要があると仮定:

  • 活動:
  • アクティビティ編集:ビュー

をそして私はまた、アクセス権が広いシステムでないことを確認する必要がありますが、依存私の役割は特に部門です。私がしたことは、私のレルムのユーザーに対して、「部門依存」の許可が明示的に加えられたことです。例(ポスト内の階層を参照してください):

  • DEP_A:アクティビティ:ビュー
  • DEP_C:アクティビティ:ビュー
  • DEP_C:アクティビティ:私はアクションかどうかを確認するたびに

を編集いくつかのアクティビティに対して許可されているかどうか、私は確認する権限のリストを作成しています。例:

活動Aは、私が「表示」にしたい、部門Dに属します。チェックするアクセス権は次のようになります。

  • DEP_D:アクティビティ:ビュー
  • DEP_C:アクティビティ:ビュー
  • DEP_B:アクティビティ:ビュー

私は、部門Cで管理していた場合、私は考え'DEP_C:activity:view'権限を持っているため、 チェックが渡されます。 Thatsは、企業構造階層で権利継承を実装することができます。ここで

は、権限チェックを担当する私のサービスクラスからコードsnippletです:

@Override 
    public void checkIfOperationPermitted(SecurityOperation operation, 
     Object object) 
    { 
     final Subject currentUser = SecurityUtils.getSubject(); 

     if(currentUser.isPermitted(
     SecurityOperation.SYSTEM_ADMIN.getPermissionString()) || 
     currentUser.hasRole("admin")) 
     { 
     // no need to check anything else, 
     // admin is system wide role. 
     return; 
     } 

     if(object instanceof Activity) 
     { 
     // Activity permissions fully depends on organization and 
     // product hierarchies. PermissionResolver is just a class 
     // which generates list of permission strings based on 
     // department activity is belonging to. 
     Activity a = (Activity) object; 
     List<String> permissionsToCheck = 
      permissionResolver.resolveHierarchicalPermissions(operation, a); 
     boolean permitted = false; 
     for(String permission: permissionsToCheck) 
     { 
      if(currentUser.isPermitted(permission)) 
      { 
       permitted = true; 
       break; 
      } 
     } 
     if(!permitted) 
     { 
      throw new UnauthorizedException("Access denied"); 
     } 
     } 
     else 
     { 
     // Check for system wide permissions 
     currentUser.checkPermission(operation.getPermissionString()); 
     } 
    } 

私が考えていたもう一つの方法は、にすることができ、私のレルム内のユーザーのためにこのようなすべての権限を追加しますが、この会社から階層を拒否されます一般的にN層を含んでいます - 特定のユーザー(メモリ使用量)のアクセス許可リストの重複を大幅に増加させます。

関連する問題