2009-11-05 7 views
1

J'ai un SecurityService qui a une méthode AutoLogin, qui utilise le ServiceSecurityContext pour trouver quelle identité Windows appelle, puis essaie de trouver le compte d'utilisateur associé dans la base de données. Cela fonctionne correctement lorsqu'il est appelé à partir d'un site Web qui utilise l'emprunt d'identité et nécessite une sécurité intégrée dans IIS. L'appel utilise le stock NetPipeBinding.Comment appeler un service WCF à partir d'un test unitaire en tant qu'identité anonyme?

Je voudrais tester le service comme suit:

[TestMethod] 
public void AutoLoginAsAnonymousFails() 
{ 
    using (var anonymousContext = WindowsIdentity.Impersonate(WindowsIdentity.GetAnonymous().Token)) 
    { 
     ISecurityService securityService = ClientChannelManager.CreateSecurityServiceChannel(); 
     var loginResponse = securityService.AutoLogin(); 
     ((ICommunicationObject)securityService).Close(); 
     Assert.IsFalse(loginResponse.IsSuccessful);    
    } 
} 

Du côté du service de l'utilisateur dans le SecurityContext est toujours moi - comment faire un utilisateur anonyme? J'ai déjà essayé d'usurper l'identité de IntPtr.Zero mais sans succès.

Pour référence, la partie pertinente de la méthode de service:

public ResponseMessage AutoLogin() 
{ 
    if (ServiceSecurityContext.Current.WindowsIdentity != null 
     && !ServiceSecurityContext.Current.WindowsIdentity.IsAnonymous 
     && !ServiceSecurityContext.Current.WindowsIdentity.IsGuest 
     && ServiceSecurityContext.Current.WindowsIdentity.IsAuthenticated) 
    { 
     // find the user based on his windows identity and return success = true message 
    } 

    // return success = false message 
} 

Répondre

2

Ceci est un exemple classique de la façon dont la séparation des préoccupations pourrait vous aider. Au lieu de s'appuyer directement sur ServiceSecurityContext (quelque chose que vous devriez, IMO, ne faites jamais), assurez-vous de configurer votre service afin que les informations de sécurité soient à la place encapsulées dans Thread.CurrentPrincipal. IIRC, lorsque vous utilisez l'authentification et l'emprunt d'identité Windows, il peut même configurer automatiquement pour vous, mais sinon, vous pouvez toujours écrire un ServiceAuthorizationManager personnalisé, qui le fait pour vous.

Cela vous permettra de faire varier vos problèmes de sécurité indépendamment de la logique de votre domaine. Si vous vous en tenez à l'interface IPrincipal et résistez à la tentation de downcasting vers WindowsPrincipal, votre code sera même prêt pour l'avenir de l'identité: Identité basée sur les revendications, telle qu'implémentée par Windows Identity Foundation (WIF). Ceci aide aussi considérablement avec les tests unitaires, parce que vous pouvez simplement assigner GenericPrincipal à Thread.CurrentPrincipal avant d'appeler votre System Under Test (SUT).

+0

bien, Mark (btw: joli nom, mais écrit mal :-p), merci pour votre contribution jusqu'à présent. Tu as probablement raison. Je vais vérifier cela dans un projet de test distinct. Mais je n'ai toujours aucune idée pourquoi le test est incapable de simuler un utilisateur anonyme bien que je sois dans un bloc d'emprunt d'identité. Des idées pour lesquelles cela échoue? –

+0

J'ai besoin d'un peu plus d'informations avant de pouvoir répondre à cette question. Quand j'ai écrit ma réponse à l'origine, j'ai supposé que le test unitaire créait simplement une nouvelle instance de la classe de service elle-même, contournant ainsi l'hôte de service. J'ai basé cette hypothèse sur votre utilisation du terme «test unitaire», mais je vois maintenant que votre code peut également se lire comme si votre test créait un nouveau proxy et invoquait votre service (hébergé ouf de processus) via NetNamedPipes. Est-ce correct une interprétation plus correcte? –

+0

C'est correct. Dans le détail, j'utilise la bibliothèque InProcFactory de Juval Löwys ServiceModelEx. Il permet de remplacer le nouveau mot-clé par un appel en usine - des trucs sympas pour voir si la sérialisation fonctionne. Et oui, ce n'est pas la granularité fine qui est souhaitable pour les tests unitaires, mais croyez-moi - mettre en œuvre un tel type de test est par des amplitudes meilleures que ce que nous avions auparavant ... –

Questions connexes