2009-09-12 6 views
0

Je suis en train de concevoir une application en 3 couches:sécurité Manutention et découpler

1) couche d'accès aux données
2) Couche entreprise
3) UI

J'essaie de garder les classes découplées si sur la couche d'affaires que j'ai créé des interfaces pour les classes d'accès aux données comme ceci:

public interface ICountryRepository:IRepository 
{ 
    Country GetCountry(int ID); 

    int CreateCountry(Country obj); 
    Boolean UpdateCountry(Country obj); 
    Boolean DeleteCountry(Country obj); 
    ... 
    ... 
} 

et je passe l'interface comme au constructeur param de service:

public CountryService(ICountryRepository repository,ILanguageRepository lang_repository) 
    {  
    .... 
    } 

Mais sur le CountryService par exemple, je dois charger l'utilisateur en cours et ses autorisations afin que je puisse vérifier si l'opération peut être appliquée:

public Country GetCountry(int ID) 
    { 

     if securityService.UserHasPermission(currentUser, GetPermission("CanGetCountry")) 
     { 
      return repository.GetCountry(ID); 
     } 
     else 
     { 
      Throw(New SecurityException("No permissions for that operation ....")) 
     } 

    } 

Cela signifie que je dois instancier le SecurityDataAccess objet et passez-le au constructeur de SecurityService sur mon assembly de couche de gestion que j'essaye d'éviter pour que les objets soient découplés. À l'heure actuelle, je n'ai même pas de référence à un assembly DataAccess sur mon assembly métier. Je pense à utiliser un conteneur IoC ici. En utilisant une configuration externe, je pourrais obtenir la bonne classe/l'assemblage à partir d'un fichier de configuration. Mais je ne suis pas sûr que ce soit la bonne solution car on dit que les conteneurs IoC devraient être utilisés en un seul endroit pour garder les choses simples et que ce devrait être l'assemblage de haut niveau (l'assemblage de l'interface utilisateur) la plupart du temps.

Quelqu'un a une suggestion pour résoudre ce problème? Pourquoi ne pas ajouter le service de sécurité dans le constructeur du service de pays?

Répondre

1

Pourquoi ne pas ajouter le service de sécurité dans le constructeur du service Pays? De cette façon, le conteneur IOC pourrait résoudre la dépendance et injecter la sécurité si nécessaire. Cela signifie que le conteneur IOC s'occuperait de la construction de votre objet CountryService. Et vous utiliseriez le conteneur pour obtenir tous les services.

Une autre option pourrait être de « normaliser » votre dépôt un peu ...

Coupez-le lui a seulement 4-5 fonctions de base identiques pour tous les référentiels, puis utilisez génériques pour les faire tous l'air aussi bien, donc pas

UpdateCountry (...) mais mise à jour (objet T)

Quelque chose comme ceci: http://codebetter.com/blogs/gregyoung/archive/2009/01/16/ddd-the-generic-repository.aspx

Th Vous pouvez utiliser un modèle Chaîne de réponsibilité pour placer votre code de sécurité avant le code DB (http://en.wikipedia.org/wiki/Chain-of-responsibility_pattern)

Ainsi vous pouvez avoir un SecurityChecker qui valide l'accès, déclenche une exception si elle est invalide, ou transmet la demande dans le lien suivant dans la chaîne (Vous pouvez également ajouter dynamiquement une journalisation de cette manière, ou une synchronisation ou autre)

+0

La première suggestion va fonctionner. Mais j'essaie de trouver un moyen d'éviter de passer le service de sécurité à tous les autres services. Je mentionne que les classes DAL sont simples (pas de logique du tout .. lit et écrit) donc pas besoin de sécurité là-bas. –

+1

Le vérificateur de sécurité aura une interface iRepository. Lorsque vous construisez votre référentiel, vous transmettez une référence au service de sécurité. Si l'utilisateur veut enregistrer, alors il "juste" appelle enregistrer sur le service de sécurité externe. Il vérifie si l'utilisateur est autorisé à sauvegarder, et si c'est le cas, il passe l'appel sur le référentiel d'accès aux données interne. Si l'utilisateur n'est pas autorisé à sauvegarder, il lance simplement une exception et empêche l'enregistrement. Jetez un oeil à IOC Container, ils vous aideront à construire de telles chaînes via la configuration –

+0

Je suis d'accord - permettre l'interface iRepository sur le constructeur vous donnera la flexibilité dont vous avez besoin. À moins qu'il n'y ait une autre couche intermédiaire - BusinessObject.SecurityData - que le DAL et le BL utilisent, le mieux que vous pouvez obtenir est d'utiliser iRepository. L'iRepository est également simple car vous n'aurez pas à aller chercher des couches différentes d'assemblages différents pour localiser un problème. –

0

Avez-vous besoin d'implémenter la sécurité dans la couche d'accès aux données? Si vous déplacez votre service de sécurité vers la couche de gestion, comme le suggère Heiko. En d'autres termes, effectuez la sécurité dans la couche de gestion et évitez complètement le problème de l'IoC.

+0

En fait, je ne veux pas de sécurité dans la couche de données. Je veux la sécurité dans la couche de gestion. Le problème pour moi est que j'ai besoin d'instancier le service de sécurité afin que je puisse lire les permissions de l'utilisateur actuel. Mais pour ce faire, je dois passer la sécurité DAL à son constructeur. Cela va coupler la sécurité DAL avec le service de sécurité. C'est mon problème. –

0

Cela peut être hors-faisceau, des excuses si c'est, je suis un programmeur Java EE rôdeur.Il me semble que l'autorisation des méthodes est mieux traitée dans l'infrastructure, de manière déclarative.

Cette article semble suggérer que .Net, comme Java EE offre une possibilité de contrôler l'accès de manière déclarative. Cette approche fonctionne-t-elle pour vous?

Questions connexes