2010-02-26 5 views
2

Dans ma couche logique, j'ai besoin de vérifier les autorisations pour une grande variété d'actions. Certaines actions sont génériques mais certaines sont hautement spécialisées. Chaque action possède une hiérarchie d'autorisations correspondante évaluée avant l'exécution de l'action. J'ai jeté des idées d'architecture dans ma tête mais je n'en ai pas trouvé une solide qui, je pense, sera extensible, simple et élégante.Actions, autorisations et architecture

Le code actuel ressemble à ceci:

public class LogicObject 
{ 
     public void Add() 
     { 
      Check Add Permission 
      Perform 
     } 
     public void Update() 
     { 
      Check Update Permission 
      Perform 
     } 
} 

Le problème avec cette architecture est que, d'abord il est pas vraiment tout ce qui extensible, et le second, il ne me permet pas de vérifier l'autorisation sans effectuer l'action.

Une autre idée que je devais était d'avoir quelque chose comme ceci:

public class AddAction : IAction 
{ 
    public bool IsPermitted; 
    public void Perform(); 
} 

public class LogicObject 
{ 
    public IAction AddAction {get { return new AddAction(); } } 
} 

J'aime cette architecture mieux, mais je ne suis pas tout à fait mis là-dessus. Cela semble un peu hokey. Je ne peux pas imaginer que ce type d'architecture soit unique. Quels sont quelques exemples d'une meilleure façon de faire cela?

Répondre

4

Une autre option que vous avez est d'utiliser la programmation orientée aspect pour avoir un composant externe de vos services pour contrôler l'autorisation d'accès à la méthode. Ce que cela signifie essentiellement, c'est que vos méthodes seront enveloppées dans l'exécution par le code qui effectuera l'autorisation.

Un exemple de solution pour implémenter ceci pour Java est Spring Security qui vous donnera une multitude de façons de personnaliser et de définir votre schéma d'autorisation. L'objet serait alors ressembler à:

public class logicObject { 
    @PreAuthorize("hasRole('ROLE_USER')") 
      public void update() { 
       //Perform 
      } 

    //... 
    } 

vous besoin d'un code Off cours supplémentaire pour définir le contexte de sécurité et de créer un proxy pour la classe logicObject avec ce contexte, ainsi que la définition de votre autorisation elle-même. Comme il semble que l'exemple de code que vous avez donné soit en C#, vous devriez jeter un coup d'œil à la sécurité basée sur les rôles et à tous les biens dans l'espace de noms [System.Security.Permissions] [2]. Il vous permet d'utiliser des attributs pour contrôler l'accès d'une méthode en cours d'exécution. Vous pouvez définir vos propres attributs personnalisés et votre fournisseur d'autorisation. L'utiliser pourrait ressembler à quelque chose comme:

public class LogicObject 
{ 
    [PrincipalPermissionAttribute(SecurityAction.Demand, Role="ROLE_USER")] 
     public void Add() 
     { 
      //Perform 
     } 

} 
0

Je ne pense pas que votre premier exemple était si loin; Je diviserais la logique en deux: avoir les membres de la classe visibles à l'extérieur comme une façade - séparée de l'intérieur (les membres privés) qui font réellement le travail. Le travail des façades extérieures consiste donc à accepter l'appel de fonction, à effectuer un contrôle de sécurité et à répondre comme il convient. Cela signifierait également que vous avez une approche cohérente quant à l'endroit où la vérification de sécurité a été faite.

Une autre option que vous pourriez vouloir examiner est Microsoft Enterprise Libraries, car ils ont des blocs de sécurité qui couvrent ce genre de chose. Vous obtenez un cadre de sécurité gratuit (qui a de fortes chances d'être un bon choix si vous êtes dans le camp MS), et il y aura un exemple de code qui couvrira votre question en détail.

Je ne suis pas sûr d'avoir où la documentation étendue est: Tom Hollanders blog peut être un endroit à regarder, sinon vous pouvez obtenir les entLibs à partir de CodePlex.

1

Il semble que vous utilisiez le style C# ici, donc c'est possible.Net approche du problème consiste à attacher un attribut à la méthode la définit l'autorisation nécessaire pour exécuter la méthode, en utilisant votre exemple:

public class LogicObject 
{ 
     [PrincipalPermission(Security.Demand, Role="AddItem")] 
     public void Add() 
     { 
      Perform 
     } 
     [PrincipalPermission(Security.Demand, Role="AddItem")] 
     public void Update() 
     { 
      Perform 
     } 
} 

PrincipalPermission vérifie l'utilisateur Thread.CurrentPrincipal pour voir si l'utilisateur a des droits à la action en question. J'ai également créé des attributs personnalisés qui ont des fonctions similaires, mais qui traitent davantage de la sécurité au niveau des lignes plutôt que des droits ou des autorisations généraux. L'avantage d'utiliser un attribut est que vous pouvez le coder une fois et que le code s'applique à chaque consommateur de l'attribut, par opposition à l'écriture de la logique encore et encore.

+0

Apparemment, j'aurais dû lire Amitay Dobo complètement avant de poster. Vu le code java dans le premier exemple et sauté sur le reste. Ma faute. – thaBadDawg