2017-04-13 1 views
1

Je suis en train d'écrire une application .Net personnalisée qui utilise des revendications pour la sécurité, car nous traversons de nombreuses frontières - Web, API, traitement par lots et ainsi de suite. Pendant le développement, il y a des occasions où je vais créer quelque chose dans le système en étant connecté via Chrome puis je vais tester l'élément nouvellement créé via un autre compte dans Edge et en quelque sorte HttpContext.Current.User.Identity correspond à ma session Chrome. Je définis Thread.CurrentPrincipal dans les coulisses, mais j'ai toujours cru que toutes les requêtes dans IIS engendraient un nouveau thread, donc je n'arrive pas à comprendre pourquoi les requêtes Edge sont traitées comme s'il s'agissait des requêtes Chrome.IISExpress Single-Thread?

Est-il possible qu'il partage ces informations, car Visual Studio est en mode débogage?

+0

_ "... demande à IIS de générer un nouveau thread ..." _ - probablement la requête arrivera sur le prochain thread de pool de threads disponible. Donc, les identifications de threads ne seront pas uniques au fil du temps – MickyD

+0

@rubyhaus En fait, quel est votre problème, je suppose qu'il y a une demande pour le même utilisateur en chrome, vous ne voulez pas le laisser dans d'autres navigateurs, est ce que vous essayez? atteindre ? – Webruster

Répondre

4

Oui, IIS (et donc IISExpress, qui est empaqueté par IIS dans un format "application") est multithread. Cependant, vous avez fait des suppositions incorrectes.

D'abord, non. Une nouvelle requête NE génère PAS de nouveau thread, elle s'exécute sur un thread de pool de threads et ces pools de threads sont réutilisés après la fin de la requête précédente (ou, comme vous le verrez dans une minute, lorsqu'une requête asynchrone est attendue). Deuxièmement, vous ne devez PAS définir Thread.CurrentPrincipal car non seulement IIS est multithread, mais asynchrone. Cela signifie que si votre thread attend, lorsqu'il reprend, il peut s'exécuter sur un thread différent de celui sur lequel il a démarré.

Troisièmement, Thread.CurrentPrincipal est généralement l'identité de l'identité du processus de travail (ou AppPool), cela change le contexte de sécurité dans lequel le thread entier s'exécute. Une meilleure option est d'utiliser la classe WindowsImpersonationContext pour faire l'usurpation d'identité (ce que je suppose que vous essayez de faire).

WindowsIdentity clientId = (WindowsIdentity)User.Identity; 

// When 'using' block ends, the thread reverts back to previous Windows identity, 
// because under the hood WindowsImpersonationContext.Undo() is called by Dispose() 
using (WindowsImpersonationContext wic = clientId.Impersonate()) 
{ 
    // do your work that needs the identity 
} 

Si vous avez besoin de définir un principe personnalisé, vous devez généralement utiliser HttpContext.Current.User plutôt que Thread.CurrentPrincipal.

+0

Je place 'HttpContext.Current.User' du côté web, mais sans référencer 'System.Web' partout, comment puis-je laisser les bibliothèques sous-jacentes (principalement une couche de gestion) savoir qui est l'utilisateur authentifié? J'essaie d'éviter de référencer System.Web, car tout n'utilisera pas les composants Web. J'ai longtemps été sous l'impression que les API d'adhésion de Microsoft définissaient le ThreadPrincipal, donc cette route. – RubyHaus

+1

@RubyHaus - Oui, le code de Microsoft fait souvent beaucoup de choses que nous ne devrions pas faire nous-mêmes, car MS sait ce qu'il fait et gère correctement les cas de nettoyage et de contournement, nous n'en savons pas assez sur les internes. préférable de les éviter. Faites-vous une sorte d'authentification personnalisée? Pouvez-vous simplement transmettre le principal à la bibliothèque à partir de la couche Web? –

+0

J'espérais qu'il y avait une façon plus simple de faire, mais je peux probablement trouver un moyen de le faire. Merci pour l'aide! – RubyHaus