Pergunta

Estou desenvolvendo serviços WCF com BasichttpBinding, esses serviços devem estar acessíveis usando .NET 1.1 e .NET 2.0, para esse fim, estou usando BasichttpBinding.
Nos Serviços da Web antigos do ASMX, eu assumi um cabeçalho SOAP (AuthHeader) para autenticar o usuário a cada solicitação.

Como posso autenticar no WCF usando BasichttpBinding? Qualquer amostra ou tutorial será útil.


nrk

Foi útil?

Solução

Você pode usar o AuthHeader como fez antes de mudar para o WCF. Talvez seja mais conviniente para você, porque os princípios permanecerão os mesmos. A coisa ruim que vejo nesta solução é uma transferência de senha de texto simples. De qualquer forma, é apenas mais uma opção e você pode criptografar/descriptografar a senha de alguma forma.

Nesse caso, você deve implementar o seu próprio seu idispatchMessageInspector e iclientMessageInspector, como

[AttributeUsage(AttributeTargets.Class)]
public class CredentialsExtractorBehaviorAttribute : Attribute, IContractBehavior, IDispatchMessageInspector
{
    #region IContractBehavior implementation.

    public void ApplyDispatchBehavior(ContractDescription contractDescription, ServiceEndpoint endpoint,
                                      DispatchRuntime dispatchRuntime)
    {
        dispatchRuntime.MessageInspectors.Add(this);
    }

    ... empty interface methods impl skipped ...

    #endregion

    #region IDispatchMessageInspector implementation.

    public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext)
    {
        int i = request.Headers.FindHeader("username", "sec");
        if (-1 != i)
        {
            string username = request.Headers.GetHeader<string>("username", "sec");
            ... do smth ...
        }
        return null;
    }

    public void BeforeSendReply(ref Message reply, object correlationState)
    {
        return;
    }

    #endregion
}

Em uma amostra, coloquei apenas o nome de usuário do cabeçalho, mas você pode implementar sua classe A contendo nome de usuário e senha e usá -lo em vez de string. No cliente:

internal class CredentialsInserter : IContractBehavior, IClientMessageInspector
{
    private string m_username;

    public CredentialsInserter(string username)
    {
        m_username = username;
    }

    #region IContractBehavior implementation.

    ... empty interface methods impl skipped ...

    public void ApplyClientBehavior(ContractDescription contractDescription, ServiceEndpoint endpoint,
                                    ClientRuntime clientRuntime)
    {
        clientRuntime.MessageInspectors.Add(this);
    }

    #endregion

    #region IClientMessageInspector implementation.

    public object BeforeSendRequest(ref Message request, IClientChannel channel)
    {
        MessageHeader<string> mh = new MessageHeader<string>(m_username);
        request.Headers.Add(mh.GetUntypedHeader("username", "sec"));
        return null;
    }

    public void AfterReceiveReply(ref Message reply, object correlationState)
    {
        return;
    }

    #endregion
}

Em seguida, você deve colocar o atributo CREDENCIALSEXTROBORBEHAVIORTIVIBUTIVE na sua classe de implementação de serviço.

[CredentialsExtractorBehavior]
public class DummyService : IDummyService
{
   ... impl ...
}

E no lado do cliente, você deve fazer o seguinte:

        using (DummyServiceClient c = new DummyServiceClient("TcpEndpoint"))
        {
            c.ChannelFactory.Endpoint.Contract.Behaviors.Add(
                new CredentialsInserter("_username_"));
            c.DummyMethod();
        }

Outras dicas

Primeiro de tudo - sim, você pode! Depende se você usa a ligação de transporte ou mensagem-se você estiver voltado para a Internet, é mais provável que você use segurança baseada em mensagens.

Infelizmente, para segurança baseada em mensagens, o BasichttpBinding suporta apenas certificados, o que é um pouco de dor.

Por outro lado, o WSHTTPBINDING suportaria nome de usuário/senha ou outros métodos.

Você configuraria o WSHTTPBINDING com credenciais do cliente de nome de usuário/senha sobre segurança baseada em mensagens como esta:

  <system.serviceModel>
    <bindings>
      <wsHttpBinding>
        <binding name="wsUserName">
          <security mode="Message">
            <message clientCredentialType="UserName"/>
          </security>
        </binding>
      </wsHttpBinding>
    </bindings>
    <services>
      <service name="yourservice">
        <endpoint name="YourEndpoint"
                  address=""
                  binding="wsHttpBinding"
                  bindingConfiguration="wsUserName"
                  contract="IYourService" />
      </service>
    </services>
  </system.serviceModel>

A seção abaixo <bindings> define a Configuração de ligação Para WSHTTPBinding, que usa a segurança da mensagem com as credenciais do cliente de nome de usuário/senha.

A seção abaixo <service> Define um serviço de amostra que usa WSHTTPBinding e que referencia a configuração de ligação que acabamos de definir.

No lado do servidor, agora você pode usar o nome de usuário/senha que está sendo enviado pelo fio para validar seus chamadores no seu Active Directory (todo mundo que está chamando precisa de uma conta de anúncio com você) ou no banco de dados do sistema de associação ASP.NET; Ou, se você realmente deve, também pode escrever seu próprio mecanismo de autenticação.

Encontre muitas informações úteis no WCF segurança no codeplex - Excelente recurso.

Verifique os cenários aqui para tentar combinar um à sua situação. Cada cenário é fornecido com um chceklist de itens necessários para implementar a solução.

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