2013-06-29 8 views
0

Après avoir suivi les cours Pluralsight de Dominick Baier et les blogs autour de WIF 4.5, je suis toujours confronté à un problème que je n'arrive pas à résoudre. J'utilise WCF Data Services avec l'autorisation basée sur les revendications en utilisant WIF 4.5.Service de données WCF avec WIF 4.5; Principal non défini pour les requêtes POST

J'ai mon ClaimsAuthenticationManager et ClaimsAuthorizationManager mis en place dans le web.config:

<section name="system.identityModel" type="System.IdentityModel.Configuration.SystemIdentityModelSection, System.IdentityModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089" /> 
... 
<system.identityModel> 
<identityConfiguration> 
    <claimsAuthenticationManager type="Magnum.WCFDataService.ClaimsTransformer, Magnum.WCFDataService" /> 
    <claimsAuthorizationManager type="Magnum.WCFDataService.AuthorizationManager, Magnum.WCFDataService" /> 
</identityConfiguration> 
</system.identityModel> 

Voici le contenu de mon AuthorizationManager:

public class AuthorizationManager : ClaimsAuthorizationManager 
{ 
    public override bool CheckAccess(AuthorizationContext context) 
    { 
     var action = context.Action.First(); 

     if (action.Type.Equals(ClaimPermission.ActionType)) 
     { 
      var resource = context.Resource.First(); 
      return context.Principal.HasClaim(resource.Value, action.Value); 
     } 

     return base.CheckAccess(context); 
    } 
} 

Le premier problème que j'ai rencontré que WCF était automatiquement appeler mon AuthorizationManager pour chaque requête et passer le verbe http pour l'action et l'URL de la ressource, cela était inutile car je voulais déterminer manuellement quand les revendications ont été appelées en utilisant la requête et changer interce ptors fournis par les services de données. C'est là que j'ai trouvé explanation du problème de Dominick suggérant d'écrire une classe personnalisée et un attribut pour remplacer ClaimsPrincipalPermission. Cela s'est bien passé, l'attribut est sur l'intercepteur de changement et de requête et appelle mon AuthorizationManager une deuxième fois avec mon URI personnalisé.

Maintenant, le problème est, pour les requêtes GET, cela fonctionne sans accroc. Le AuthorizationManager est appelé une fois par WCF que j'ignore et une deuxième fois en utilisant mon attribut que je gère. Cependant, pour les requêtes POST (chaque fois que j'ai un intercepteur de changement), lorsque le AuthorizationManager est appelé une deuxième fois avec mon URI, le principal sur le contexte est un GenericPrincipal plutôt qu'un ClaimsPrincipal et ne contient pas mes revendications à vérifier.

Comment puis-je m'assurer que mon ClaimsPrincipal est toujours généré à partir de ClaimsTransformer (ClaimsAuthenticationManager) à chaque fois que le AuthorizationManager est appelé?

Informations supplémentaires Après quelques recherches intensives, j'ai réduit le problème. Je vois seulement le GenericPrincipal si j'utilise le SaveChangesOptions.Batch en appelant la méthode SaveChanges de mon client. Si je n'envoie pas de mise à jour par lots, j'obtiens un ClaimsPrincipal comme d'habitude. Donc, nouvelle question; Comment puis-je conserver ClaimsPrincipal pour les mises à jour par lots?

J'ai trouvé quelques informations sur un thread MSDN (http://social.msdn.microsoft.com/Forums/en-US/35eb817d-363c-4a94-b9eb-351cd0d8567f/batch-update-and-impersonation-current-user) indiquant que je dois utiliser les éléments suivants dans mon web.config:

<serviceAuthorization principalPermissionMode="Always" impersonateCallerForAllOperations="true" impersonateOnSerializingReply="true" /> 

mais maintenant je reçois l'erreur suivante:

The service operation 'ProcessRequestForMessage' that belongs to the contract with the 'IRequestHandler' name and the 'http://tempuri.org/' namespace does not allow impersonation. 
+0

@leastprivilege Auriez-vous quelques instants pour donner votre avis à ce sujet? – ChrisO

Répondre

0

Problème résolu, ceci est la configuration correcte pour garantir que les requêtes par lots fonctionnent correctement avec WIF 4.5 en utilisant un service de données WCF

<behavior> 
    <serviceCredentials useIdentityConfiguration="true" /> 
    <serviceAuthorization principalPermissionMode="Always" impersonateOnSerializingReply="true" /> 
</behavior> 
Questions connexes