Thread.CurrentPrincipal est jeté par un intercepteur de services ASP.Net WCF dans un environnement fédéré (WIF)

StackOverflow https://stackoverflow.com/questions/1932424

  •  20-09-2019
  •  | 
  •  

Question

J'ai un par appel service WCF qui est hébergé dans IIS (.svc). Dans le constructeur de service, je mets Thread.CurrentPrincipal = HttpContext.Current.User par cet article . Dans ce cas, HttpContext.Current.User est de type Microsoft.IdentityModel.Claims.ClaimsPrincipal et a les demandes qui ont été renvoyés de mes STS coutume passive.

Cependant, dès que je fais un pas dans mon opération de service et examinerai Thread.CurrentPrincipal , alors que cet objet est encore de type Microsoft.IdentityModel.Claims.ClaimsIdentity , la objet lui-même n'est plus la même chose que HttpContext.Current.User ( IsAuthenticated = false, AuthenticationType = "" et le nom est nulle sur Thread.CurrentPrincipal.Identity ), alors que ceux-ci les valeurs sont toutes encore remplies correctement sur HttpContext.Current.User . Cela me dit que quelque chose intercepte l'appel à l'opération et le changement de manière incorrecte le principal courant à certaines allégations génériques, vide, non authentifié principale.

J'ai vérifié l'ID de thread dans le constructeur, ainsi que dans l'opération et il est le même dans les deux endroits, et l'évaluation de Thread.CurrentPrincipal dans la fenêtre immédiate après l'attribution de HttpContext.Current .user montre que l'identité de fil est correctement défini dans le constructeur, donc quelque chose est en cours d'exécution sans aucun doute entre le constructeur et la méthode, et que quelque chose est en train de changer mon Thread.CurrentPrincipal .

Est-ce que quelqu'un a une idée de ce que fait cela, et comment je peux aller sur la prévention / la fixation de ce comportement?

Était-ce utile?

La solution 2

Lors de la configuration d'un service pour la fédération de WIF, vous appelez

FederatedServiceCredentials.ConfigureServiceHost(this);

Une partie de ce que cet appel fait est de mettre en place une coutume ServiceAuthorizationManager de type IdentityModelServiceAuthorizationManager sur l'hôte de service. Ce gestionnaire d'autorisation semble s'appelé entre l'activation (construction) de l'instance et l'exécution de l'opération, et elle écrasera Thread.CurrentPrincipal avec une instance de IClaimsPrincipal , mais ne semble pas se rendre compte qu'il est en cours d'exécution en mode ASP.NET compatibilité, il ne tire pas le principal de HttpContext.Current.User .

Je suis en mesure de contourner ce comportement en dérivant de IdentityModelServiceAuthorizationManager et redéfinissant la méthode CheckAccess comme suit:

public class CustomAuthorizationManager : IdentityModelServiceAuthorizationManager
{
    public override bool CheckAccess(System.ServiceModel.OperationContext operationContext, ref System.ServiceModel.Channels.Message message)
    {
        var result = base.CheckAccess(operationContext, ref message);

        var properties = operationContext.ServiceSecurityContext.AuthorizationContext.Properties;
        properties["Principal"] = System.Web.HttpContext.Current.User;

        return result;
    }
}

obtient ensuite appliqué à l'hôte de service comme suit:

protected override void InitializeRuntime()
{
    FederatedServiceCredentials.ConfigureServiceHost(this);
    this.Authorization.ServiceAuthorizationManager = new CustomAuthorizationManager();
    base.InitializeRuntime();
}

Et maintenant, quand je rentre dans mon opération de service, je le bon IClaimsPrincipal sur Thread.CurrentPrincipal , alors déclarative PrincipalPermission fonctionne désormais correctement .

Autres conseils

Je viens de rencontrer un problème similaire. Je tournai ma principale personnalisée dans le constructeur de mon service WCF. Quand je suis parti le constructeur, et entra dans la méthode que j'ai appelé, le Thread.CurrentPrincipal a été remplacé par un vide. Je résolu ce problème en ajoutant le comportement suivant:

<serviceAuthorization principalPermissionMode="None"></serviceAuthorization>

Cela a fonctionné très bien pour moi.

Paramètres confguration pour appel FederatedServiceCredentials.ConfigureServiceHost (ce );

est comme ci-dessous dans system.serviceModel ajouter suivante

<extensions>
      <behaviorExtensions>
        <add name="federatedServiceHostConfiguration" type="Microsoft.IdentityModel.Configuration.ConfigureServiceHostBehaviorExtensionElement, Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
      </behaviorExtensions>
    </extensions>

en ligne ajouter à l'intérieur folowing

<behavior name="serviceBehavior">
          <federatedServiceHostConfiguration name="MyService" />

Je suppose que rien n'intercepte l'appel. Soit le CurrentPrincipal est remis à zéro par le temps que vous examinez ou vous êtes dans un autre thread.

Vérifier l'CurrentPrincipal immédiatement après affectation et vous devriez voir la valeur correcte.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top