Usuário com melhor resposta
WCF - Usando autenticação em WsHttpbinding

Pergunta
-
Fiz uma WCF Library, que consigo consumir normalmente por outra aplicação. Implementei a UserNamePasswordValidator. mas quando tento consumir o serviço, passando o user e pass, ao tentar acessar qualquer método do serviço, ele lança uma exception com a seguinte descrição:
SOAP security negotiation with 'http://localhost:6000/FleuryServico/UserName' for target 'http://localhost:6000/Servico/UserName' failed. See inner exception for more details.
Alguem sabe me dizer o que pode ser? Já tentei de tudo, e não funciona com essa forma de autenticação.
Obrigado
Respostas
-
Boas Savoia,
Não lembro a configuração padrão do WCF, mas tente especificar o tipo de validação do certificado na aplicação cliente, como mostrado abaixo:
<behaviors>
<endpointBehaviors>
<behavior name="ClientBehavior">
<clientCredentials>
<serviceCertificate>
<authentication certificateValidationMode="PeerTrust" />
</serviceCertificate>
</clientCredentials>
</behavior>
</endpointBehaviors>
</behaviors>
Depois, vincule este behavior ao endpoint (ainda do lado do cliente):
<client>
<endpoint address="http://localhost:6000/ClienteServico/UserName"
binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IServicoIntegracao"
contract="ServiceReference1.IServicoIntegracao" name="WSHttpBinding_IServicoIntegracao"
behaviorConfiguration="ClientBehavior">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
</client>
http://www.israelaece.com- Marcado como Resposta Andre SBC quarta-feira, 16 de setembro de 2009 20:46
Todas as Respostas
-
Boas Savoia,
Já tentou ver a exceção interna para ver o que ele mostra? Atente-se também para o uso do certificado.
Este artigo pode te ajudar em algo, pois tem um passo a passo: http://www.israelaece.com/post/WCF-Seguranca-Autenticacao-e-Autorizacao-Customizadas.aspx
http://www.israelaece.com -
Então Israel, inclusive consultei esse seu arquivo.. estou fazendo o básico por enquanto... só para autenticar, sem testar as roles do usuário... veja os configs..
server:
<configuration>
<system.web>
<compilation debug="true" />
</system.web>
<appSettings>
<add key="SimularServico" value="false"/>
</appSettings>
<!-- When deploying the service library project, the content of the config file must be added to the host's
app.config file. System.Configuration does not support config files for libraries. -->
<system.serviceModel>
<diagnostics>
<messageLogging logEntireMessage="true" logMalformedMessages="true"
logMessagesAtServiceLevel="true" logMessagesAtTransportLevel="true" />
</diagnostics>
<bindings>
<wsHttpBinding>
<binding name="NewBinding0">
<security mode="Message">
<message clientCredentialType="UserName" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<services>
<service behaviorConfiguration="Empresa.Cliente.WebService.Service1Behavior"
name="Empresa.Cliente.WebService.ServicoIntegracao">
<endpoint address="UserName" binding="wsHttpBinding" bindingConfiguration="NewBinding0"
contract="Empresa.Cliente.WebService.IServicoIntegracao">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<host>
<baseAddresses>
<add baseAddress="http://localhost:6000/ClienteServico" />
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="Empresa.Cliente.WebService.Service1Behavior">
<serviceMetadata httpGetEnabled="True"/>
<serviceDebug includeExceptionDetailInFaults="False" />
<serviceCredentials>
<!--
The serviceCredentials behavior allows one to specify a custom validator for username/password combinations.
-->
<userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="Empresa.Cliente.WebService.Autenticacao, Empresa.Cliente.WebService" />
<!--
The serviceCredentials behavior allows one to define a service certificate.
A service certificate is used by a client to authenticate the service and provide message protection.
This configuration references the "localhost" certificate installed during the setup instructions.
-->
<serviceCertificate findValue="localhost" storeLocation="LocalMachine" storeName="My" x509FindType="FindBySubjectName" />
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
Cliente:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="WSHttpBinding_IServicoIntegracao" closeTimeout="00:01:00"
openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard"
maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true"
allowCookies="false">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<reliableSession ordered="true" inactivityTimeout="00:10:00"
enabled="false" />
<security mode="Message">
<transport clientCredentialType="Windows" proxyCredentialType="None"
realm="" />
<message clientCredentialType="UserName" negotiateServiceCredential="true"
algorithmSuite="Default" establishSecurityContext="true" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<client>
<endpoint address="http://localhost:6000/ClienteServico/UserName"
binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IServicoIntegracao"
contract="ServiceReference1.IServicoIntegracao" name="WSHttpBinding_IServicoIntegracao">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
</client>
</system.serviceModel>
</configuration>
Rodei o certmgr para criar o certificado.... (isso vem no Samples da Microsoft)antes disso ele sempre me retornar um outro erro..
echo off
set SERVER_NAME=localhost
echo ---------------------------------------------------------------------
echo cleaning up the certificates from previous run
certmgr.exe -del -r CurrentUser -s TrustedPeople -c -n %SERVER_NAME%
certmgr.exe -del -r LocalMachine -s My -c -n %SERVER_NAME%echo ---------------------------------------------------------------------
echo Server cert setup starting
echo for server: %SERVER_NAME%
echo making server cert
makecert.exe -sr LocalMachine -ss MY -a sha1 -n CN=%SERVER_NAME% -sky exchange -pe
echo copying server cert to client's CurrentUser store
certmgr.exe -add -r LocalMachine -s My -c -n %SERVER_NAME% -r CurrentUser -s TrustedPeople
echo ---------------------------------------------------------------------
Código Client:
ServiceReference1.ServicoIntegracaoClient servico = new ServiceReference1.ServicoIntegracaoClient();
servico.ClientCredentials.UserName.UserName = "teste";
servico.ClientCredentials.UserName.Password = "teste";servico.TestarServico();
Isso está direto na library, usando o Test Client.. criei uma camada de Host, e mesmo assim tb não rolou.... tem idéia do que possa ser?
o que vc quis dizer com exceção interna? Debugando, ele nem chega a bater na Autenticacao.cs.
Obrigado
Savoia
-
Boas Savoia,
Não lembro a configuração padrão do WCF, mas tente especificar o tipo de validação do certificado na aplicação cliente, como mostrado abaixo:
<behaviors>
<endpointBehaviors>
<behavior name="ClientBehavior">
<clientCredentials>
<serviceCertificate>
<authentication certificateValidationMode="PeerTrust" />
</serviceCertificate>
</clientCredentials>
</behavior>
</endpointBehaviors>
</behaviors>
Depois, vincule este behavior ao endpoint (ainda do lado do cliente):
<client>
<endpoint address="http://localhost:6000/ClienteServico/UserName"
binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IServicoIntegracao"
contract="ServiceReference1.IServicoIntegracao" name="WSHttpBinding_IServicoIntegracao"
behaviorConfiguration="ClientBehavior">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
</client>
http://www.israelaece.com- Marcado como Resposta Andre SBC quarta-feira, 16 de setembro de 2009 20:46
-
Agora sim.. Obrigado...
Nem imaginava que tinha que criar isso do lado do cliente... agora, ao fazer o proxy, isso poderia ser default né?... mas enfim..
uma pergunta.. esse certificado que eu gerei, já é o suficiente para fazer a autenticação né? estou fazendo o teste na minha máquina mesmo.. outra estação acessando esse serviço.. basta fazer essa configuração, e passar o user e pass né?
Obrigado -
Boas Savoia,
Grande parte das configurações padrão são sempre mais restritiva, e neste caso o valor padrão é ChainTrust, ou seja, instrui o WCF a confiar no certificado somente se ele foi emitido através de um orgão como Verisign, Serasa, etc.
Para testes isso é o suficiente, mas em ambiente de produção, o correto é recorrer a algum orgão (como Verisign, Serasa, etc.) para comprar esse certificado.
http://www.israelaece.com -
Amigo, siga os seguintes passos:
makecert -n "CN=RootCATest" -r -sv RootCATest.pvk RootCATest.cer
makecert -crl -n "CN=RootCATest" -r -sv RootCATest.pvk RootCATest.crl
makecert -sk MyKeyName -iv RootCATest.pvk -n "CN=tempCert" -ic RootCATest.cer -sr localmachine -ss my -sky exchange -peEncontre a PrivateKey, se for Windows Vista estará no diretorio abaixo:
C:\ProgramData\Microsoft\Crypto\RSA\MachineKeys
Caso contrario baixe o aplicativo FindPrivateKey.exe e execute a rotina abaixo, ela lhe retornará a private key do certificado citado, no caso tempCert.
FindPrivateKey.exe My LocalMachine -n "CN=tempCert"
Algo que voce deve fazer é aplicar a permissão a essas chaves ao Servico de Rede, caso o seu windows seja ingles, substitua para "NETWORKING SERVICE" ao inves de "SERVIÇO DE REDE"
cacls.exe "C:\Documents and Settings\All Users\Application Data\Microsoft\Crypto\RSA\Machinekeys\c97679a3da9a0576cff48d08cdd48389_584ea20d-bfa5-4665-b443-b3ee50747ee0" /E /G "SERVIÇO DE REDE":R
cacls.exe "C:\Documents and Settings\All Users\Application Data\Microsoft\Crypto\RSA\Machinekeys\c97679a3da9a0576cff48d08cdd48389_584ea20d-bfa5-4665-b443-b3ee50747ee0makecert -n "CN=RootCATest" -r -sv RootCATest.pvk RootCATest.cer
O .config do seu serviço deverá ter algumas definições:
<
<netTcpBinding>
<binding name="TcpServiceBindingConfig">
<security mode="Message">
<message clientCredentialType="UserName" />
<transport clientCredentialType="None" protectionLevel="None" />
</security>
</binding>
</netTcpBinding>
</bindings>
<services>
<service behaviorConfiguration="ServiceBehavior" name="Business.ServiceFacade">
<endpoint address="net.tcp://localhost:808/Service.svc" binding="netTcpBinding"
bindingConfiguration="TcpServiceBindingConfig"
contract="Services.Contracts.IServiceContract" />
<endpoint address="net.tcp://localhost:808/Service.svc/mex" binding="mexTcpBinding"
contract="IMetadataExchange" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="ServiceBehavior">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
<serviceCredentials>
<serviceCertificate
findValue="tempCert"
x509FindType="FindBySubjectName"
storeName="My"
storeLocation="LocalMachine" />
<userNameAuthentication userNamePasswordValidationMode="Custom"
customUserNamePasswordValidatorType="MySecurity.FnacAuthentication, MySecurity" />
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
O .config do seu client deverá ter algumas definições:<
<netTcpBinding>
<binding name="TcpClientBindingConfig">
<security mode="Message">
<message clientCredentialType="UserName"/>
<transport clientCredentialType="None" protectionLevel="None"/>
</security>
</binding>
</netTcpBinding>
</bindings><
<endpoint name="TcpProdutoService"
address="net.tcp://localhost:808/Service.svc"
contract="Services.Contracts.IProdutoServiceContract"
binding="netTcpBinding"
bindingConfiguration="TcpClientBindingConfig"
behaviorConfiguration="ClientBehavior">
<identity>
<certificate
encodedValue="+YfyLHlDHuTySegXe7BgM9x/s9+Bkm9Xd2bkhuyF2h/K+WpHj0x8dJ7G1vmPcvF3ogK0sduXcJg8kP9A6TJd+......." />
</identity>
</endpoint>
</client>
Esse encodedValue voce poderá obter automaticamente se criar o serviço através do WebReference no proprio VisualStudio.
<behaviors>
<endpointBehaviors>
<behavior name="ClientBehavior">
<clientCredentials>
<serviceCertificate>
<authentication certificateValidationMode="None"/>
</serviceCertificate>
</clientCredentials>
</behavior>
</endpointBehaviors>
</behaviors>
Acho que isso lhe ajudará...
Abs.,
Marcel Piva
Marcel Piva