ASP.NET WCF Service's Thread.CurrentPrincipal está sendo jogado fora por algum interceptador em um ambiente federado (WIF)

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

  •  20-09-2019
  •  | 
  •  

Pergunta

Eu tenho um serviço WCF por chamada que está sendo hospedado no IIS (.svc). No construtor do serviço, eu defino Thread.CurrentPrincipal = httpContext.current.user conforme Este artigo. Nesse caso Httpcontext.current.user é do tipo Microsoft.IdentityModel.Claims.ClaimsPrincipal e tem as reivindicações que foram enviadas de volta dos meus STs passivos personalizados.

No entanto, assim que eu entro na minha operação de serviço e examino Thread.CurrentPrincipal, enquanto esse objeto ainda é do tipo Microsoft.IdentityModel.Claims.ClaimsIdentity, o próprio objeto não é mais o mesmo que Httpcontext.current.user (Isauthenticated = false, autenticationType = "" e o nome é nulo em thread.currentPrincipal.Identity), enquanto esses valores ainda estão preenchidos corretamente Httpcontext.current.user. Isso me diz que algo está interceptando a chamada para a operação e alterando incorretamente o diretor atual para um diretor genérico, vazio e não autenticado.

Eu verifiquei o ID do thread no construtor, bem como na operação e é o mesmo nos dois lugares, e avaliando Thread.CurrentPrincipal na janela imediata depois de atribuir de Httpcontext.current.user mostra que a identidade do encadeamento está sendo definida corretamente no construtor, então algo está definitivamente executando entre o construtor e o método, e que algo está mudando meu Thread.CurrentPrincipal.

Alguém tem alguma idéia do que está fazendo isso e como posso prevenir / corrigir esse comportamento?

Foi útil?

Solução 2

Ao configurar um serviço para a Federação WIF, você liga

FederatedServiceCredentials.ConfigureServiceHost(this);

Parte do que esta chamada faz é configurar um costume ServiceAuthorizationManager do tipo IdentityModelServiceAuthorizationManager no host de serviço. Esse gerente de autorização parece ser chamado entre a ativação (construção) da instância e a execução da operação, e substitui Thread.CurrentPrincipal com uma instância de IclaimsPrincipal, mas não parece perceber que está sendo executado no modo de compatibilidade do ASP.NET, por isso não puxa o diretor de Httpcontext.current.user.

Eu era capaz de ignorar esse comportamento derivando de IdentityModelServiceAuthorizationManager e substituindo o CheckAccess Método da seguinte forma:

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;
    }
}

Isso então é aplicado ao host de serviço da seguinte forma:

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

E agora, quando entro na minha operação de serviço, tenho o correto IclaimsPrincipal sobre Thread.CurrentPrincipal, assim declarativo PrincipalPermission agora funciona como esperado.

Outras dicas

Acabei de ter um problema semelhante. Defino meu diretor personalizado no construtor do meu serviço WCF. Quando saí do construtor e entrei no método que chamei, o Thread.CurrentPrincipal foi substituído por um vazio. Eu resolvi isso adicionando o seguinte comportamento:

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

Isso funcionou bem pra mim.

Configuração de configurações para chamada FederatedServiceCredentials.configureviceHost (isto);

é o abaixo em System.Servicemodel Adicionar seguinte

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

Sob Inside Add Flowing Line

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

Meu palpite é que nada está interceptando a ligação. O CurrentPrincipal é redefinido no momento em que você o examina ou está em um thread diferente.

Verifique o CurrentPrincipal imediatamente após atribuir a ele e você verá o valor correto.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top