Anda di halaman 1dari 6

Autenticao customizada de WCF Parte I

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.

Autenticao customizada de WCF Parte II


No post anterior da nossa srie, Autenticao customizada de WCF Parte I, mostrei como criar uma classe para autenticar as informaes de usurio e senha, ficando pendente como trafegar estas informaes de maneira segura, atravs do uso de certificados. Exatamente o assunto do post de hoje. O primeiro passo conseguir o certificado para ser utilizado na configurao do servio. Uma opo para ambientes de produo comprar um certificado de uma entidade certificadora, uma outra opo gerar um certificado atravs do Certificate Server, uma das funcionalidade do Windows Server. J para

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:

<behaviors> <serviceBehaviors> <behavior name="WCFService.CalculatorServiceBehavior"> <serviceMetadata httpGetEnabled="True"/>

5: <serviceDebug includeExceptionDetailInFaults="False" /> 6: <serviceCredentials>

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>

J a configurao do cliente deve ficar similar ao cdigo xml abaixo:

1: 2: 3: 4: 5:

<behaviors> <endpointBehaviors> <behavior name="ClientCertificateBehaviour"> <clientCredentials> <serviceCertificate>

6: <authentication certificateValidationMode="PeerOrChainTrust"/> 7: 8: 9: 10: 11: </serviceCertificate> </clientCredentials> </behavior> </endpointBehaviors> </behaviors>

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.

Autenticao customizada de WCF Parte III


Esta a ltima parte da srie de autenticao customizada com WCF e hoje iremos ver como o cliente fornece as informaes das credenciais para o servio. O primeiro passo comear com uma aplicao que contm um proxy gerado para o servio, em seguida configur-la para utilizar autenticao do tipo UserName e tambm para validar o servio atravs de um certificado, conforme abaixo:

1: 2: 3: 4: 5: 6:

<configuration> <system.serviceModel> <bindings> <wsHttpBinding> <binding ...> <security mode="Message">

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>

Em seguida, necessrio que a aplicao informe ao servio a credencial utilizada na autenticao:

1: CalculatorServiceReference.CalculatorClient proxy = new CalculatorServiceReference.CalculatorClient();

2: 3: 4: 5: 6: double n = proxy.Add(1, 2); proxy.ClientCredentials.UserName.UserName = "administrator"; proxy.ClientCredentials.UserName.Password = "P@ssw0rd";