64 votes

Comment puis-je déléguer les contrôles d'autorisation JAAS à Shiro ?

Je développe une application côté serveur qui nécessite une authentification et une autorisation basées sur des objets. J'aime la simplicité de Shiro, mais pour être compatible avec JAAS, j'ai écrit un LoginModule qui utilise Apache Shiro comme mécanisme sous-jacent.

Mais mon problème est que je n'ai pas trouvé le moyen de déléguer les contrôles d'autorisation JAAS à Shiro. Comment puis-je y parvenir ?

2 votes

Deniz, avez-vous trouvé un moyen d'utiliser Shiro avec JAAS ? Si non, quelle approche avez-vous adoptée ? Merci, Kevin

5 votes

Ma principale préoccupation était d'utiliser Shiro pour la sécurité de JMX, qui utilise JAAS comme principale méthode de sécurité. J'ai résolu ce problème en implémentant un JMXAuthenticator qui crée un sujet JAAS mutable sur le contexte de contrôle d'accès actuel et stocke le sujet Shiro dans l'ensemble des informations d'identification privées du sujet JAAS. Plus tard, j'ai implémenté un LoginModule qui était en fait une enveloppe autour de l'interface Authenticator de Shiro (étendue par SecurityManagers).

0 votes

Vous pourriez peut-être fournir plus d'informations sur la nature exacte du problème, notamment le code de votre LoginModule, l'erreur que vous obtenez et la configuration du runtime.

4voto

Uux Points 1003

Note : La réponse traite du cas général où un système d'autorisation externe doit être intégré à la JVM, au moyen du cadre de sécurité standard. Elle n'est pas spécifique à Shiro ou JMX, car je ne connais ni l'un ni l'autre.


Conceptuellement, il semble que vous soyez après le point de décision politique (PDP) -- l'installation où les requêtes d'autorisation ( "L'entité X est-elle autorisée à faire Y ?" ) sont évalués, c'est-à-dire Le JDK en propose plusieurs :

  1. L'efficacité SecurityManager et plus particulièrement son checkXXX groupe de méthodes.
  2. El ProtectionDomain notamment sa classe implies(Permission) méthode.
  3. La clé implies(ProtectionDomain, Permission) méthode de l'efficacité Policy .
  4. Deuxièmement, le implies méthodes de CodeSource , PermissionCollection , Permission y Principal .

Chacune des méthodes susmentionnées peut être surchargée afin de personnaliser, à une granularité ascendante, la fonctionnalité du PDP conceptuel. Il convient de noter que JAAS (contrairement à ce que son nom suggère) n'a pas réellement apporté son propre PDP ; il a plutôt fourni le signifie pour le domaine et la politique afin de prendre en charge les requêtes basées sur les principaux, en plus du facteur de confiance d'origine du code. Par conséquent, à mon avis, votre exigence de rester "compatible JAAS" se traduit essentiellement par la volonté d'utiliser le modèle d'autorisation Java SE (original plus JAAS), c'est-à-dire le modèle d'autorisation Java SE. le site bac à sable, ce dont je doute qu'il s'agisse de ce que vous désirez. Les frameworks tels que Shiro ont tendance à être utilisés lorsque le modèle standard est jugé de trop bas niveau et/ou trop gourmand en performances ; en d'autres termes, lorsque la logique d'autorisation est trop faible. pas besoin évaluer chaque trame de pile pour un ensemble donné de facteurs de confiance, car ces facteurs sont plus souvent insensibles au contexte que non. Selon la validité de mon hypothèse, trois cas principaux sont à examiner :

  1. L'autorisation est AccessControlContext -indépendante. Les attributs d'autorisation natifs de Shiro (SNAA), quels qu'ils soient, s'appliquent à l'ensemble du fil. L'origine du code n'est pas pertinente.
  2. L'origine du code compte, rendant obligatoire l'utilisation du bac à sable. Les SNAA sont toujours AccessControlContext -Indépendante.
  3. L'origine du code et les SNAA sont à la fois pertinents et AccessControlContext - dépendant .

1. Autorisation basée uniquement sur les SNAA

  1. Gérez l'authentification comme bon vous semble. Si vous souhaitez continuer à utiliser le système d'authentification de JAAS javax.security.auth SPI pour l'authentification, oubliez l'établissement d'une norme Subject comme résultat de l'authentification, au lieu de lier directement le résultat spécifique à Shiro au stockage local du thread. De cette façon, vous obtenez un accès plus pratique aux SNAAs, et vous évitez d'avoir à utiliser les fonctions AccessControlContext (et souffrir du potentiel pénalité de performance ), pour les retrouver.

  2. Sous-classe SecurityManager en remplaçant au moins les deux checkPermission des méthodes telles qu'elles

    1. traduire, si nécessaire, le Permission l'argument en quelque chose que le PDP de Shiro (SPDP) comprend, avant de
    2. en déléguant à la SPDP les SNAA et les permissions propres au thread (et en lançant un SecurityException si le SPDP signale un refus d'accès).

    La surcharge de réception du contexte de sécurité peut simplement ignorer l'argument correspondant. Au moment de l'initialisation de l'application, l'instanciation et l'installation ( System::setSecurityManager ) votre mise en œuvre.


2. Autorisation hybride, combinant l'origine du code avec des SNAA insensibles au contexte

  1. Gérer l'authentification comme bon vous semble ; une fois de plus, associez l'authentification spécifique à Shiro à l'authentification de l'utilisateur. Subject avec le fil lui-même.
  2. Sous-classe SecurityManager en remplaçant au moins les deux checkPermission mais cette fois-ci de façon à ce qu'elles soient déléguées à la fois à la SPDP et/ou à l'implémentation surchargée (qui à son tour appelle checkPermission sur, en conséquence, le contexte de contrôle d'accès actuel ou fourni). Le(s)quel(s) et l'ordre dans lequel ils doivent être consultés pour une permission donnée dépendent bien sûr de l'implémentation. Lorsque les deux doivent être invoqués, le SPDP doit être interrogé en premier, car il répondra probablement plus rapidement que le contexte de contrôle d'accès.
  3. Si le SPDP doit en plus gérer l'évaluation des permissions accordées au code provenant d'un certain emplacement et/ou d'un ensemble de signataires de code, vous devrez également sous-classer Policy en mettant en œuvre implies(ProtectionDomain, Permission) de sorte que, comme SecurityManager::checkPermission ci-dessus, il passe une certaine représentation intelligible du domaine (généralement seulement son CodeSource ) et les arguments de permission -- mais logiquement no les SNAAs -- au SPDP. L'implémentation doit être efficace dans la mesure du possible, puisqu'elle sera invoquée une fois par domaine, par contexte de contrôle d'accès à checkPermission temps. Instanciation et installation ( Policy::setPolicy ) votre mise en œuvre.

3. Autorisation hybride, combinant l'origine du code et les SNAA, tous deux sensibles au contexte.

  1. Gérez l'authentification comme bon vous semble. Malheureusement, la gestion des sujets n'est pas aussi simple que la création d'un fichier ThreadLocal dans ce cas.

  2. Sous-classez, instanciez et installez une Policy qui remplit les fonctions combinées de SecurityManager::checkPermission y Policy::implies comme décrit individuellement dans le deuxième cas.

  3. Instance et installation d'une norme SecurityManager .

  4. Créer un ProtectionDomain de la sous-classe, capable de stocker et d'exposer les SNAA.

  5. Auteur 1 a DomainCombiner que

    1. est construit avec les SNAAs ;

    2. met en œuvre combine(ProtectionDomain[], ProtectionDomain[]) de sorte que

      1. il remplace les domaines du premier argument du tableau (le contexte "actuel") par des instances équivalentes de l'implémentation personnalisée ;
      2. ajoute ensuite ceux du second argument (le contexte "assigné" ou "hérité"), le cas échéant, au premier tel quel ; et enfin
      3. renvoie la concaténation.

    Comme Policy::implies l'implémentation doit être efficace (par exemple en éliminant les doublons), car elle sera invoquée à chaque fois que la fonction getContext y checkPermission AccessController méthodes sont.

  6. Une fois l'authentification réussie, créez un nouveau AccessControlContext qui englobe l'actuel, ainsi qu'une instance de l'option personnalisée DomainCombiner qui, à leur tour, enveloppent les SNAA. Le code d'enveloppement à exécuter au-delà de ce point "à l'intérieur" d'un AccessController::doPrivilegedWithCombiner en transmettant également le contexte de contrôle d'accès de remplacement.


1 Au lieu d'utiliser des domaines personnalisés et votre propre implémentation de combinateur, il y a aussi l'alternative apparemment plus simple de traduire les SNAAs en <code>Principal</code> et, en utilisant la norme <code>SubjectDomainCombiner</code> en les liant à l'actuel <code>AccessControlContext</code> (comme ci-dessus, ou simplement par l'intermédiaire des domaines de l'UE). <code>Subject::doAs</code> ). Le fait que cette approche réduise l'efficacité de la politique dépend principalement de la profondeur de la pile d'appels (combien de domaines distincts le contexte de contrôle d'accès comprend-il). Finalement, les optimisations de la mise en cache que vous pensiez pouvoir éviter d'implémenter dans le cadre du combinateur de domaines vous reviendront en pleine figure lors de la création de la politique, il s'agit donc essentiellement d'une décision de conception que vous devrez prendre à ce moment-là.

1 votes

Bien que j'aie trouvé une solution et répondu à ma propre question il y a 6 ans, la quantité d'informations utiles que vous avez fournies ici pour tous ceux qui tombent sur cette question mérite définitivement d'être une réponse acceptée.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X