Escolar Documentos
Profissional Documentos
Cultura Documentos
Estava conversando com um cliente sobre como um servio WCF pode autenticar de maneira customizada as chamadas que recebe, confrontando as informaes de usurio e senha com os dados de uma tabela em um banco de dados. O primeiro para criar uma classe para autenticar as chamadas do servio. Esta classe deve herdar de System.IdentityModel.Selectors.UserNamePasswordValidator, disponvel no assembly System.IdentityModel, e implementar o mtodo Validate, conforme abaixo:
1: public class CustomUsernamePasswordValidator : UserNamePasswordValidator 2: { 3: public override void Validate(string userName, string password) 4: { 5: if (userName == null || password == null) 6: { 7: throw new ArgumentNullException(); 8: } 9: 10: if (!(userName == "administrator" && password == "P@ssw0rd")) 11: { 12: throw new FaultException("Unknown username or invalid password"); 13: } 14: } 15: }
Notem que por uma questo de facilidade no estou utilizando um banco de dados para validar usurio e senha, mas sim comparando as informaes recebidas contra constantes no meu cdigo. Se a autenticao no ocorrer com sucesso emito uma mensagem de erro do tipo FaulException, que o tipo de exceo possvel de ser propagada pelo WCF (isso vale um post). Em seguida necessrio configurar o servio para utilizar esta customizao para autenticao no arquivo de configuraes:
1: <services> 2: <service behaviorConfiguration="WCFService.CalculatorServiceBehavior" ...> 3: ... 4: </service> 5: </services> 6: <behaviors> 7: <serviceBehaviors> 8: <behavior name="WCFService.CalculatorServiceBehavior"> 9: <serviceMetadata httpGetEnabled="True"/>
10: <serviceDebug includeExceptionDetailInFaults="False" /> 11: <serviceCredentials> 12: <userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="WCFCustomAuthentication.Cus tomUsernamePasswordValidator, WCFCustomAuthentication"/> 13: </serviceCredentials> 14: </behavior> 15: </serviceBehaviors> 16: </behaviors>
Agora necessrio configurar tanto o servio quanto o cliente para autenticar as chamadas atravs de usurio e senha nos seus bindings:
1: <bindings> 2: <wsHttpBinding> 3: <binding name="wsHttpBindingWithMessageSecurity"> 4: <security mode="Message"> 5: <message clientCredentialType="UserName"/> 6: </security> 7: </binding> 8: </wsHttpBinding> 9: </bindings>
Como as informaes de usurio e senha passam de maneira aberta necessrio configurar a comunicao para ocorrer de maneira segura utilizando um certificado, mas isto assunto para o post Autenticao customizada de WCF Parte II. Por ltimo tambm necessrio que o cliente do servio informe as credenciais na chamadas das operaes, assunto do post Autenticao customizada de WCF Parte III.
ambientes de desenvolvimento uma abordagem interessante pode ser gerar certificados de teste (acho que ficou claro) utilizando a ferramenta makecert.
Com o makecert necessrio primeiro criar um certificado Root, utilizado na gerao de outros certificados. Para isto, o comando abaixo deve ser executado no prompt de comando: makecert -n "CN=RootCATest" -r -sv RootCATest.pvk RootCATest.cer
Depois de gerar o certificado Root, precisamos instal-lo no computador. O que deve ser feito no Snap-in de certificados para o computador local do MMC na pasta Trusted Root Certification Authorities, conforme imagem abaixo:
Com o certificado Root instalado, podemos utiliz-lo para gerar o certificado que ir efetivamente proteger a comunicao entre o cliente e o servio. Para isto, o comando abaixo deve ser executado no prompt de comando: makecert -sk localhost -iv RootCATest.pvk -n "CN=localhost" -ic RootCATest.cer -sr localmachine -ss trustedPeople -sky exchange -pe Notem que o comando acima cria e instala o certificado na pasta Trusted People, sem necessidade de instalao manual. Agora que os certificados foram criados e instalados, precisamos configurar o servio e o cliente para utiliz-los. O servio deve ser configurado utilizando a tag serviceCertificate, conforme exemplo abaixo:
1: 2: 3: 4:
7: <userNameAuthentication userNamePasswordValidationMode="Custom"
customUserNamePasswordValidatorType="WCFCustomAuthentication.CustomUse rnamePasswordValidator, WCFCustomAuthentication"/> 8: <serviceCertificate findValue="localhost" x509FindType="FindBySubjectName" storeLocation="LocalMachine" storeName="TrustedPeople"/> 9: 10: 11: 12: </serviceCredentials> </behavior> </serviceBehaviors> </behaviors>
1: 2: 3: 4: 5:
Notem que o cliente foi configurado para validar o servio como PeerOrChainTrust, o que significa que primeiro ele vai verificar se confia no prprio certificado e se no conseguir tenta validar a cadeia hierrquica at chegar no certificado Root. O modelo mais seguro a validao atravs da hierarquia (ChainTrust), entretanto isto no possvel com certificados criados utilizando a ferramenta makecert, somente com certificados comerciais.
1: 2: 3: 4: 5: 6:
7: <message clientCredentialType="UserName"/> 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: </security> </binding> </wsHttpBinding> </bindings> ... <behaviors> <endpointBehaviors> <behavior name="ClientCertificateBehaviour"> <clientCredentials> <serviceCertificate> <authentication
19: certificateValidationMode="PeerOrChainTrust"/> 20: 21: 22: 23: 24: 25: 26: </serviceCertificate> </clientCredentials> </behavior> </endpointBehaviors> </behaviors> </system.serviceModel> </configuration>