Pergunta

Eu criei com sucesso um cliente WS que funciona corretamente quando não está usando a autenticação.

No entanto, o servidor (WebSphere) agora exige a adição de um token de nome de usuário de segurança WS, e estou tendo dificuldade em fazer isso. A mensagem de sabão resultante deve se parecer com a seguinte:

<soapenv:Envelope 
  xmlns:ns="http://foo.bar/1.0"
  xmlns:ns1="http://www.witsml.org/schemas/140"   
  xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">

  <soapenv:Header>

    <wsse:Security soapenv:mustUnderstand="1" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
      <wsse:UsernameToken wsu:Id="UsernameToken-2" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
        <wsse:Username>foo</wsse:Username>
        <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">bar</wsse:Password>    
        <wsse:Nonce EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">foooooobar==</wsse:Nonce>
        <wsu:Created>2010-01-25T13:09:24.860Z</wsu:Created>
      </wsse:UsernameToken>
    </wsse:Security>

  </soapenv:Header>

  <soapenv:Body>
    <ns:fooBar>...</ns:fooBar>
  </soapenv:Body>

Eu baixei e instalei o WSE 3.0 SDK da Microsoft e adicionei uma referência à DLL no meu projeto Visual Studio 2005.

Agora tenho acesso ao Microsoft.Web.Services3.* Namespaces, mas atualmente estou perplexo sobre como proceder.

O código do cliente foi gerado automaticamente por uma referência da Web, então eu só faço uma pequena quantidade de trabalho para enviar a mensagem ao servidor não autenticado:

WS.FooResultHttpService ws = new WS.FooResultHttpService();
ws.Url = "http://foo.bar.baz";
ws.SendSomething(message);

Acabei de começar a investigar usando Microsoft.Web.Services3.Security.Tokens.UsernameTokenManager, mas até agora não consegui colocar nada em funcionamento.

Qualquer dica seria muito apreciada, pois não consigo encontrar boas receitas na rede.

Obrigado!

Foi útil?

Solução 2

Infelizmente consegui funcionar antes de ler Ótima resposta de Wsanville.

Para ajudar os outros, estou postando todas as etapas que precisava fazer para fazer isso trabalhar com o Visual Studio 2005:

  • Instalar WSE 3.0, escolher personalizadas e selecione tudo
  • Ler Implementando a autenticação direta com o token de nome de usuário no WSE 3.0 para dicas
  • Relanomizar o Visual Studio 2005, agora clique com o botão direito do mouse no seu projeto no Solution Explorer, e você deve ter um Configurações do WSE 3.0 Item de menu e use isso, se desejar.
  • Atualize suas referências da Web, isso deve criar uma nova classe de proxy de serviço da web http, com um nome diferente, por exemplo YourWsNameHttpServiceWse. Isso é essencialmente o mesmo que correr WSEWSDL3.EXE
  • Use esta nova classe e você deve ter acesso a métodos e propriedades da WSE, como SetClientCredential.

Acabei fazendo quase tudo no código, em vez de confiar nos arquivos de configuração que são construídos com minha dll C#. O código acabou sendo assim:

FooBarHttpServiceWse wse = new FooBarHttpServiceWse();

wse.SetClientCredential(new UsernameToken(
    "username",
    "password",
    PasswordOption.SendPlainText));

wse.SetPolicy(new FooBarPolicy());
wse.CallSomeServerFunction(yourRequest)

Eu criei minha própria política, que parecia assim:

using Microsoft.Web.Services3.Design;

// ...

public class FooBarPolicy : Policy
{
    public FooBarPolicy()
    {
        this.Assertions.Add(new UsernameOverTransportAssertion());
    }
}

Finalmente, o servidor WebSphere respondeu que Um cabeçalho necessário que representa uma mensagem que endereça a propriedade não está presente, e inspecionar a mensagem de saída (usando a bela ferramenta Violinista) Vi a falha de sabão do servidor indicava que o cabeçalho de ação estava faltando.

Eu tentei em vão definir o wsa:Action elemento eu mesmo:

using Microsoft.Web.Services3.Addressing;

// ...

wse.RequestSoapContext.Addressing.Action = new Action("CallSomeServerFunction");

O problema era que, mesmo que eu estivesse uma ação, quando foi enviada sobre o fio, estava vazio. Acontece que eu tive que abrir a aula de proxy da WSE e editar um atributo lá:

[System.Web.Services.Protocols.SoapDocumentMethodAttribute(
    "---Edit this to set wsa:Action---", 
    Use=System.Web.Services.Description.SoapBindingUse.Literal, 
    ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Bare)]
// ...
public SomeServerFunction(...)

Depois disso, tudo deu certo.

Outras dicas

Certifique -se de que sua classe de proxy herda Microsoft.Web.Services3.WebServicesClientProtocol.

Você pode fazer isso alterando a classe proxy em si ou gerando -a através da linha de comando usando WSEWSDL3.EXE com o /type:webClient trocar.

Você pode passar as credenciais como esta:

using Microsoft.Web.Services3;
using Microsoft.Web.Services3.Security.Tokens;
using Microsoft.Web.Services3.Security;
.
.
.
WS.FooResultHttpService ws = new WS.FooResultHttpService();
ws.RequestSoapContext.Security.Tokens.Add(new UsernameToken("blah", "blah", PasswordOption.SendPlainText));

Foi o que eu fiz no passado para obter o WSE3.0 no Studio 2008. Espero que ajude.

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