Tenho um requisito para proteger um ponto de extremidade do serviço net.tcp do WCF transmitido usando WIF . Ele deve autenticar as chamadas recebidas no nosso servidor de token. O serviço é transmitido porque foi projetado para transferir grandes quantidades de dados e coisas.
Isso parece ser impossível. E se eu não conseguir contornar o problema, meu Natal será arruinado e eu me matarei até a sarjeta enquanto compradores alegres passam por cima do meu corpo lentamente esfriando. É sério, pessoal.
Por que isso é impossível? Aqui está o Catch-22.
No cliente, preciso criar um canal com o GenericXmlSecurityToken que recebo do nosso servidor de token. Não há problema.
// people around here hate the Framework Design Guidelines.
var token = Authentication.Current._Token;
var service = base.ChannelFactory.CreateChannelWithIssuedToken(token);
return service.Derp();
Eu disse "no problemo"? Problemo. De fato, NullReferenceException
estilo problemo.
"Bro", perguntei ao Framework, "você checa mesmo?" O Framework ficou em silêncio, então eu desmontei e descobri que
((IChannel)(object)tChannel).
GetProperty<ChannelParameterCollection>().
Add(federatedClientCredentialsParameter);
foi a fonte da exceção e que a GetProperty
chamada estava retornando null
. Então, WTF? Acontece que, se eu ativar a Segurança da mensagem e definir o tipo de credencial do cliente IssuedToken
, essa propriedade agora existe no ClientFactory
(protip: Não há "SetProperty" equivalente no IChannel, o bastardo).
<binding name="OMGWTFLOL22" transferMode="Streamed" >
<security mode="Message">
<message clientCredentialType="IssuedToken"/>
</security>
</binding>
Doce. Não há mais NREs. No entanto, agora meu cliente é culpado de nascença (ainda o amo). Indo além dos diagnósticos do WCF (protip: faça seus piores inimigos fazer isso depois de esmagá-los e levá-los diante de você, mas antes de apreciar as lamentações de mulheres e crianças), vejo que é por causa de uma incompatibilidade de segurança entre o servidor e o cliente.
A atualização solicitada não é suportada por 'net.tcp: // localhost: 49627 / MyService'. Isso pode ocorrer devido a ligações incompatíveis (por exemplo, segurança ativada no cliente e não no servidor).
Verificando as diags do host (novamente: esmague, dirija, leia logs, desfrute de lamentações), vejo que isso é verdade
O tipo de protocolo application / ssl-tls foi enviado para um serviço que não suporta esse tipo de atualização.
"Bem, eu", eu digo, "ativarei a segurança de mensagens no host!" E eu faço. Se você quiser saber como é, é uma cópia exata da configuração do cliente. Olho para cima.
Resultado: Kaboom.
A ligação ('NetTcpBinding', ' http://tempuri.org/ ') suporta streaming que não pode ser configurado junto com a segurança no nível da mensagem. Considere escolher um modo de transferência diferente ou escolher a segurança no nível de transporte.
Portanto, meu host não pode ser transmitido nem protegido por tokens . Catch-22.
tl; dr: Como posso proteger um ponto de extremidade net.tcp WCF transmitido usando WIF ???
<security mode="Transport" /> <transport clientCredentialType="IssuedToken" /> </security>
TransportWithMessageCredential
O modo pode ser outra opção.Respostas:
O WCF tem dificuldades em algumas áreas com streaming (estou olhando para você, MTOM 1 ) devido a um problema fundamental em como ele falha na execução da pré-autenticação da maneira que a maioria das pessoas pensaria que deveria funcionar (isso afeta apenas solicitações subsequentes para esse canal) , não a primeira solicitação) Ok, esse problema não é exatamente o seu, mas siga em frente, pois chegarei ao seu no final. Normalmente, o desafio HTTP funciona assim:
Agora, se você tentar ativar o streaming MTOM em um terminal WCF no servidor, ele não irá reclamar. Mas, quando você o configura no proxy do cliente (como deve, eles devem corresponder às ligações), ele explodirá em uma morte ardente. A razão para isso é que a sequência de eventos acima que o WCF está tentando impedir é a seguinte:
Observe que você acabou de enviar 200 MB ao servidor quando precisou enviar apenas 100 MB. Bem, este é o problema. A resposta é enviar a autenticação na primeira tentativa, mas isso não é possível no WCF sem escrever um comportamento personalizado. Enfim, eu discordo.
Seu problema
Primeiro, deixe-me dizer que o que você está tentando é impossível 2 . Agora, para que você pare de girar suas rodas, deixe-me dizer por que:
Parece-me que agora você está vagando em uma classe de problemas semelhante. Se você ativar a segurança no nível da mensagem, o cliente deverá carregar todo o fluxo de dados na memória antes de poder realmente fechar a mensagem com a função hash usual e a assinatura xml exigidas pelo ws-security. Se precisar ler o fluxo inteiro para assinar a mensagem única (que não é realmente uma mensagem, mas é um único fluxo contínuo), você poderá ver o problema aqui. O WCF precisará transmiti-lo uma vez "localmente" para calcular a segurança da mensagem e transmiti-lo novamente para enviá-lo ao servidor. Isso é claramente uma coisa boba, então o WCF não permite segurança no nível de mensagem para o fluxo de dados.
Portanto, a resposta simples aqui é que você deve enviar o token como um parâmetro para o serviço da Web inicial ou como um cabeçalho SOAP e usar um comportamento personalizado para validá-lo. Você não pode usar o WS-Security para fazer isso. Francamente, isso não é apenas um problema do WCF - não consigo ver como ele poderia funcionar praticamente para outras pilhas.
Resolvendo o problema do MTOM
Este é apenas um exemplo de como eu resolvi meu problema de streaming MTOM para autenticação básica. Talvez você possa entender isso e implementar algo semelhante ao seu problema. O ponto crucial é que, para habilitar seu inspetor de mensagens personalizado, é necessário desativar toda noção de segurança no proxy do cliente (ele permanece ativado no servidor), além do nível de transporte (SSL):
Observe que eu desativei a segurança de transporte aqui porque fornecerei isso usando um inspetor de mensagens e um comportamento personalizado:
Portanto, este exemplo é para quem está sofrendo com o problema do MTOM, mas também como um esqueleto para implementar algo semelhante para autenticar seu token gerado pelo serviço de token protegido por WIF principal.
Espero que isto ajude.
(1) Dados grandes e streaming
(2) Segurança da mensagem no WCF (consulte "desvantagens").
fonte
MTOM and Basic Authorization
e MTOM e OAuth2 ?