Usuário com melhor resposta
WCF com autenticação

Pergunta
-
Boa tarde a todos.
Estou implementando um serviço utilizando segurança de mensagem com autenticação username.
Já estou mais ou menos uma semana batendo na mesma tecla.
A mensagem de erro é a seguinte:
Já criei os certificados. Não entendo muito bem de ceretificados, mas em fim segui a receita no site da microsoft.
Para os que não conhecem vejam:
http://msdn.microsoft.com/en-us/library/ff648498
Porem está apresentando a mensagem de erro a baixo. Não sej mais o que fazer. A quem pudem me ajudar eu agradeço.
Não é possível abrir o canal seguro porque ocorreu uma falha na negociação de segurança com o ponto de extremidade remoto. Isso pode ter sido causado pela ausência ou especificação incorreta de EndpointIdentity na classe EndpointAddress usada para criar o canal. Verifique se a classe EndpointIdentity especificada ou implícita por EndpointAddress identifica corretamente o ponto de extremidade remoto.
Config do servico
<system.serviceModel>
<services>
<service name="WcfSecurity.Service1" behaviorConfiguration="WcfSecurity.Service1Behavior">
<!-- Service Endpoints -->
<endpoint address="" binding="wsHttpBinding" contract="WcfSecurity.IService1"></endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
</services>
<bindings>
<wsHttpBinding>
<binding name="srvBidingConfig">
<security mode="Message">
<message clientCredentialType="UserName"/>
</security>
</binding>
</wsHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="WcfSecurity.Service1Behavior">
<!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
<serviceMetadata httpGetEnabled="true"/>
<!-- To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information -->
<serviceDebug includeExceptionDetailInFaults="true"/>
<serviceCredentials>
<serviceCertificate findValue="CN=skydes5" />
<userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="WcfSecurity.CustomUsernamePasswordValidator, WcfSecurity"/>
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>Config do cliente
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="WSHttpBinding_IService1" 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">
<message clientCredentialType="UserName" algorithmSuite="Default" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<behaviors>
<endpointBehaviors>
<behavior name="certConfig">
<clientCredentials>
<serviceCertificate>
<authentication certificateValidationMode="PeerTrust"/>
</serviceCertificate>
</clientCredentials>
</behavior>
</endpointBehaviors>
</behaviors>
<client>
<endpoint address="http://skydes5.sky/wcfAutenticado/Service1.svc"
binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IService1"
contract="ServiceReference1.IService1" name="WSHttpBinding_IService1" behaviorConfiguration="certConfig">
<identity>
<userPrincipalName value="MinhaMaquina\ASPNET" />
<!--<certificate encodedValue="30818902818100AE0E785D5EFE84F11F4DA8FDE504A9305ECAE05F7B385D650F92E22D401B66CD125839956E31EAF6C0AE2EC14DCBDDD985ECDC64DAFF0D8739B90924F0384B889A8D4B6082A885F238447A29DEAE1C25F528487758C71CD556849B75E643310DA8B070F0CB4B866EE421DFA7EC7E3231C0CAFD5740FC56387DDBBD9AEEB310A70203010001"/>-->
</identity>
</endpoint>
</client>
</system.serviceModel>Veja que na indentity eu
já fiz várias configurações.
Agradeço a quem puder me ajudar.
Respostas
-
Finalmente consegui.
Eu não estava definindo o bidding para o bindingConfiguration no endpoint.
Agora sim funcionando tudo ok.
Config Server
<system.serviceModel> <services> <service name="WcfSecurity.Service1" behaviorConfiguration="WcfSecurity.Service1Behavior"> <!-- Service Endpoints --> <endpoint address="" binding="wsHttpBinding" contract="WcfSecurity.IService1" bindingConfiguration="srvBidingConfig"> <identity> <certificateReference findValue="CN=skydes5"/> </identity> </endpoint> <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/> <host> <baseAddresses> <add baseAddress="http://localhost/wcfAutenticado"/> </baseAddresses> </host> </service> </services> <bindings> <wsHttpBinding> <binding name="srvBidingConfig"> <security mode="Message"> <message clientCredentialType="UserName" negotiateServiceCredential="true" establishSecurityContext="true"/> </security> </binding> </wsHttpBinding> </bindings> <behaviors> <serviceBehaviors> <behavior name="WcfSecurity.Service1Behavior"> <!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment --> <serviceMetadata httpGetEnabled="true"/> <!-- To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information --> <serviceDebug includeExceptionDetailInFaults="true"/> <serviceCredentials> <serviceCertificate findValue="CN=skydes5"/> <userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="WcfSecurity.CustomUsernamePasswordValidator, WcfSecurity"/> </serviceCredentials> </behavior> </serviceBehaviors> </behaviors> </system.serviceModel>
Config Cliente
<system.serviceModel> <bindings> <wsHttpBinding> <binding name="WSHttpBinding_IService1" 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" /> </security> </binding> </wsHttpBinding> </bindings> <behaviors> <endpointBehaviors> <behavior name="configAut"> <clientCredentials> <serviceCertificate> <authentication certificateValidationMode="PeerOrChainTrust" revocationMode="NoCheck"/> </serviceCertificate> </clientCredentials> </behavior> </endpointBehaviors> </behaviors> <client> <endpoint address="http://skydes5.sky/wcfAutenticado/Service1.svc" binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IService1" contract="ServiceReference1.IService1" name="WSHttpBinding_IService1" behaviorConfiguration="configAut"> <identity> <certificate encodedValue="AwAAAAEAAAAUAAAAqCf8nLySr3Dt+We0BKCELuyuPn8gAAAAAQAAAPIBAAAwggHuMIIBW6ADAgECAhDcqanZD6ocvkDIHSreK07YMAkGBSsOAwIdBQAwFTETMBEGA1UEAxMKUm9vdENBVGVzdDAeFw0xMjA1MjMxNzM4NTdaFw0zOTEyMzEyMzU5NTlaMBIxEDAOBgNVBAMTB3NreWRlczUwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANpHc047/VRf+8Rk5Fc5RTxpvPdsiRmLAn2QFXLQ2LXX7u56jCltEyOMmTIKU8hdVf6xYlwxsnn9295L4cSPK1jH6YLv2/4Haohp9sCp4+YeMOTDEVJXJkQy/o1b+UKm8FBdK5ipWd0OYqIb/7Vzd37cShGbU/0Rd0iAwomjTyjHAgMBAAGjSjBIMEYGA1UdAQQ/MD2AELLXo5eO/mR34nSvnCmNU9ChFzAVMRMwEQYDVQQDEwpSb290Q0FUZXN0ghD0ByJaVRWjh0VyBwXqz4jPMAkGBSsOAwIdBQADgYEAaoXHx/LnfzvypzLu8K2qoO2DW6T8+aYwyjtCMaLNajJ6ep0IuBM5UzdRSwOH1qcdpSgzaqTVNVDNmepfNAnEeMk+ApeYc3zQIhgBiKl253ygE2zD16Dsm0+hf33Hp8arOIL9OGv0w/CnRi7Xd3PaKE+uedFkDiHyb1zpyxCx/+U=" /> </identity> </endpoint> </client> </system.serviceModel>
Veja que no cliente na seção <Identity> ele já buscou a chave publica no serviço. Isso porque no serviço na seção <Identity> ao invés de colocar <dns value ="localhost" eu coloquei <certificateReference findValue="CN=skydes5"/>.
Automaticamente ele passa a chave publica para o cliente. Só que é preciso da permissão para o usuario do IIS ter acesso a chave privada. Veja em um post aqui.
http://social.msdn.microsoft.com/Forums/pt/wcfpt/thread/5474d58c-0e2d-4b5f-9416-b11b5fc3fc24
Depois de uma semana patinando finalmente conseguiiiiiiii.
O que não gostei do wcf é a questão de vc ser obrigado a informar um certificado neste cenário.
Foi bom para estudo, mas para simples aplicações, vou implementar de outro jeito.
- Editado augustoICE terça-feira, 29 de maio de 2012 18:21
- Marcado como Resposta augustoICE quinta-feira, 31 de maio de 2012 17:18
Todas as Respostas
-
O certificado é obrigatório para o seu cenário?
Se não for: Fiz um post em meu blog que eu explico como criar uma custom credential de username, caso queira implementar e testar: http://jquaglio.blogspot.com.br/2012/05/custom-credential-validator-no-wcf.html
-
José, se eu não me engano já tentei este teu post. Já fiz quase todos do Israel Aece. Acho que estou comento bola é com o maldito certificado.
É que na verdade eu estou utilizando o vinculo wsHttpBinding, que exige certificado. Neste seu exemplo você não mostra qual vinculo você está utilizando, mas acredito que seja o wsHttpBasic não é?
Criei um certificado Root, depois instalei loja de certificados autorizados. Com o certificado root gerei outro certificado tudo certinho, configurei o IIS com o certificado que eu criei. Segui exatamente a receita da microsoft no post abaixo.
http://msdn.microsoft.com/en-us/library/ff648840.aspx.
Este post tem exemplos de segurança baseado em mensagem e transporte. Tem exemplos de como cirar, instalar e configurar o certificado no IIS.
-
Augusto,
O tipo do binding não importa muito. Já utilizei essa solução (do meu post) em HTTPS e NET.TCP e as duas funcionam.
A única coisa que você tem que ficar atento é o SECURITY. Que deve ser utilizado o userName.
Aqui está um exemplo de um customBinding HTTPS que utiliza o custom credential de username.
<customBinding> <binding name="customHttps" openTimeout="00:05:00" receiveTimeout="00:05:00" sendTimeout="00:05:00"> <textMessageEncoding messageVersion="Soap12"> <readerQuotas maxDepth="32" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="4096" maxNameTableCharCount="16384" /> </textMessageEncoding> <security authenticationMode="UserNameOverTransport"> <secureConversationBootstrap /> </security> <httpsTransport maxReceivedMessageSize="5242880" maxBufferSize="5242880" transferMode="Buffered" /> </binding> </customBinding>
Não esqueça também de alterar o serviceMetadata dentro do behavior (em serviceBehavior)
<serviceMetadata httpsGetEnabled="true" />
PS: Vou alterar meu post, inserindo as informações de binding.
-
-
-
-
Finalmente consegui.
Eu não estava definindo o bidding para o bindingConfiguration no endpoint.
Agora sim funcionando tudo ok.
Config Server
<system.serviceModel> <services> <service name="WcfSecurity.Service1" behaviorConfiguration="WcfSecurity.Service1Behavior"> <!-- Service Endpoints --> <endpoint address="" binding="wsHttpBinding" contract="WcfSecurity.IService1" bindingConfiguration="srvBidingConfig"> <identity> <certificateReference findValue="CN=skydes5"/> </identity> </endpoint> <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/> <host> <baseAddresses> <add baseAddress="http://localhost/wcfAutenticado"/> </baseAddresses> </host> </service> </services> <bindings> <wsHttpBinding> <binding name="srvBidingConfig"> <security mode="Message"> <message clientCredentialType="UserName" negotiateServiceCredential="true" establishSecurityContext="true"/> </security> </binding> </wsHttpBinding> </bindings> <behaviors> <serviceBehaviors> <behavior name="WcfSecurity.Service1Behavior"> <!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment --> <serviceMetadata httpGetEnabled="true"/> <!-- To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information --> <serviceDebug includeExceptionDetailInFaults="true"/> <serviceCredentials> <serviceCertificate findValue="CN=skydes5"/> <userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="WcfSecurity.CustomUsernamePasswordValidator, WcfSecurity"/> </serviceCredentials> </behavior> </serviceBehaviors> </behaviors> </system.serviceModel>
Config Cliente
<system.serviceModel> <bindings> <wsHttpBinding> <binding name="WSHttpBinding_IService1" 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" /> </security> </binding> </wsHttpBinding> </bindings> <behaviors> <endpointBehaviors> <behavior name="configAut"> <clientCredentials> <serviceCertificate> <authentication certificateValidationMode="PeerOrChainTrust" revocationMode="NoCheck"/> </serviceCertificate> </clientCredentials> </behavior> </endpointBehaviors> </behaviors> <client> <endpoint address="http://skydes5.sky/wcfAutenticado/Service1.svc" binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IService1" contract="ServiceReference1.IService1" name="WSHttpBinding_IService1" behaviorConfiguration="configAut"> <identity> <certificate encodedValue="AwAAAAEAAAAUAAAAqCf8nLySr3Dt+We0BKCELuyuPn8gAAAAAQAAAPIBAAAwggHuMIIBW6ADAgECAhDcqanZD6ocvkDIHSreK07YMAkGBSsOAwIdBQAwFTETMBEGA1UEAxMKUm9vdENBVGVzdDAeFw0xMjA1MjMxNzM4NTdaFw0zOTEyMzEyMzU5NTlaMBIxEDAOBgNVBAMTB3NreWRlczUwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANpHc047/VRf+8Rk5Fc5RTxpvPdsiRmLAn2QFXLQ2LXX7u56jCltEyOMmTIKU8hdVf6xYlwxsnn9295L4cSPK1jH6YLv2/4Haohp9sCp4+YeMOTDEVJXJkQy/o1b+UKm8FBdK5ipWd0OYqIb/7Vzd37cShGbU/0Rd0iAwomjTyjHAgMBAAGjSjBIMEYGA1UdAQQ/MD2AELLXo5eO/mR34nSvnCmNU9ChFzAVMRMwEQYDVQQDEwpSb290Q0FUZXN0ghD0ByJaVRWjh0VyBwXqz4jPMAkGBSsOAwIdBQADgYEAaoXHx/LnfzvypzLu8K2qoO2DW6T8+aYwyjtCMaLNajJ6ep0IuBM5UzdRSwOH1qcdpSgzaqTVNVDNmepfNAnEeMk+ApeYc3zQIhgBiKl253ygE2zD16Dsm0+hf33Hp8arOIL9OGv0w/CnRi7Xd3PaKE+uedFkDiHyb1zpyxCx/+U=" /> </identity> </endpoint> </client> </system.serviceModel>
Veja que no cliente na seção <Identity> ele já buscou a chave publica no serviço. Isso porque no serviço na seção <Identity> ao invés de colocar <dns value ="localhost" eu coloquei <certificateReference findValue="CN=skydes5"/>.
Automaticamente ele passa a chave publica para o cliente. Só que é preciso da permissão para o usuario do IIS ter acesso a chave privada. Veja em um post aqui.
http://social.msdn.microsoft.com/Forums/pt/wcfpt/thread/5474d58c-0e2d-4b5f-9416-b11b5fc3fc24
Depois de uma semana patinando finalmente conseguiiiiiiii.
O que não gostei do wcf é a questão de vc ser obrigado a informar um certificado neste cenário.
Foi bom para estudo, mas para simples aplicações, vou implementar de outro jeito.
- Editado augustoICE terça-feira, 29 de maio de 2012 18:21
- Marcado como Resposta augustoICE quinta-feira, 31 de maio de 2012 17:18