2009-11-16 4 views
1

J'utilise actuellement Castle-Windsor avec l'installation WCF pour injecter tous mes services WCF. Je viens de commencer à ajouter des exigences d'autorisation en utilisant un IAuthorizationPolicy personnalisé, qui semble fonctionner lorsqu'il est effectué sur une base par méthode sur le service, mais lorsque la classe de service elle-même est marquée avec les exigences, une exception est levée.Problème avec IAuthorizationPolicy avec WCF et Castle-Windsor

J'ai mis en place des choses basées sur l'exemple à How To – Use Username Authentication with Transport Security in WCF from Windows Forms. Je n'ai pas configuré la classe de module HTTP personnalisée car j'utilise une implémentation Membership existante. Ma mise en œuvre IAuthorizationPolicy (HttpContextPrincipalPolicy) est essentiellement identique.

La partie essentielle de mon Web.config est:

<serviceBehaviors\> 
    <behavior name="MyBehavior"> 
    <serviceMetadata httpGetEnabled="true" /> 
    <serviceDebug includeExceptionDetailInFaults="false" /> 
    <serviceAuthorization principalPermissionMode="UseAspNetRoles" 
          roleProviderName="UserProvider"> 
     <authorizationPolicies> 
     <clear/> 
     <add policyType="Website.FormsAuth.HttpContextPrincipalPolicy,Website"/> 
     </authorizationPolicies> 
    </serviceAuthorization> 
    </behavior> 
</serviceBehaviors> 

Tout semble fonctionner très bien quand je mets les exigences sur la méthode. Cela se fait comme ceci:

[PrincipalPermission(SecurityAction.Demand, Role = RoleNames.USER_ADMINISTRATION)] 

Si cela est sur une méthode OperationContract, les choses fonctionnent comme prévu. Cependant, si elle est déplacée à la classe elle-même (qui met en œuvre le ServiceContract) Je reçois l'exception suivante (avec la plupart des choses supplémentaires élagué out):

Castle.MicroKernel.ComponentActivator.ComponentActivatorException { 
    Message = "ComponentActivator: could not instantiate Services.UserService" 
    InnerException = System.Reflection.TargetInvocationException { 
     Message = "Exception has been thrown by the target of an invocation." 
     InnerException = System.Security.SecurityException { 
      Message = "Request for principal permission failed." 
     } 
    } 
} 

J'ai débogués et a constaté que le constructeur sur HttpContextPrincipalPolicy est appelé, mais Evaluate() n'est pas lorsque la demande est attachée à la classe. Lorsqu'il est associé à la méthode Evaluate(), est appelée. Donc, à ce stade, je suis allé aussi loin que mes débuts .NET/WCF/Castle-Windsor compétences me prendront.

Existe-t-il un moyen de dire à Castle-Windsor d'invoquer le constructeur de service tout en honorant le IAuthorizationPolicy? Ou dire à WCF que Evaluate() doit être appelé pour la création de la classe? Ou y a-t-il un autre moyen de faire la même chose avec la WCF? Je ne veux pas avoir à marquer chaque méthode avec exactement le même bit de déclaration d'attribut.

Répondre

1

Lorsque vous marquez la classe elle-même avec un PrincipalPermissionAttribute, cela indique en fait à l'exécution qu'à l'instant où la classe est utilisée, la demande d'autorisation doit être satisfaite. Alors maintenant, quand Castle-Windsor essaie d'instancier la classe, la demande d'autorisation est faite et bien sûr elle ne peut pas être satisfaite parce que le contexte de sécurité n'est pas établi correctement à ce moment-là.

AFAIK, PrincipalPermissionAttribute n'est pas pris en charge au niveau de la classe pour WCF en raison de la nature de son exécution même si elle est autorisée à partir d'une perspective .NET pure. Castle-Windsor ne peut donc pas créer votre instance de service pour la même raison.

+0

Cela semble correspondre à ce que je vois. Je me demande cependant, y a-t-il une autre façon de faire quelque chose de semblable sans avoir à marquer chaque méthode? –

+0

Eh bien, vous pouvez faire ce que vous voulez si vous écrivez votre propre IAuthorizationPolicy. Donc, si vous vouliez créer un modèle de sécurité où l'accès était contrôlé au niveau du service, vous pouvez vérifier les revendications sur l'identité actuelle pour voir si elles sont autorisées à accéder à ce service. La seule différence est que vous êtes responsable du stockage des données de la liste de contrôle d'accès dans votre propre formulaire, par opposition à l'utilisation de PrincipalPermissionAttribute. Cela peut être un attribut personnalisé que vous écrivez vous-même ou vous pouvez le stocker en dehors du code statique dans un fichier de base de données/configuration. –

Questions connexes