Há algum tempo em comentei aqui sobre as opções de segurança no WCF, e mais tarde, como customizá-la para receber e validar usernames e passwords em um repositório qualquer. Antes da versão 3.5 do WCF, essa customização somente trabalha com segurança em nível de mensagem. Com o 3.5, a Microsoft adicionou esse suporte para também trabalhar com segurança em nível de transporte.
Isso é útil em cenários onde queremos utilizar a autenticação Basic do HTTP como meio de fornecimento das credenciais, mas ao invés da conta informada existir e de ser validada dentro do sistema operacional, vamos customizar essa regra, utilizando um repositório customizado, como uma base de dados, evitando que os clientes tenham, obrigatoriamente, contas cadastradas dentro do Windows.
Para que isso funcione, a configuração de segurança do binding deverá ser definida como Transport, e a forma de fornecimento de credenciais como Basic. Além disso, você também precisará implementar um validador customizado, herdando da classe abstrata UserNamePasswordValidator, como eu já mostrei neste artigo. Abaixo temos a configuração do lado do serviço:
<bindings>
<basicHttpBinding>
<binding name=”bindingConfig”>
<security mode=”Transport”>
<transport clientCredentialType=”Basic”/>
</security>
</binding>
</basicHttpBinding>
</bindings>
Apenas lembre-se de que o Basic faz com que as credenciais sejam trafegadas codificadas e não criptografadas, e justamente por isso, estamos recorrendo à segurança em nível transporte (que neste caso é o HTTPS), para garantir a integridade e confidencialidade da mensagem e das credenciais. Para informar as credenciais do lado do cliente, você faz da mesma forma que antes:
using (Servico p = new Servico)
{
p.ClientCredentials.UserName.UserName = “IA”;
p.ClientCredentials.UserName.Password = “123”;
Console.WriteLine(p.Ping(“teste”));
}
O único problema desta técnica, é que você não poderá hospedar o serviço no IIS. Isso se deve ao fato de que quando o atributo clientCredentialType estiver definido como Basic, o IIS fará a verificação durante o carregamento do serviço, analisando se o modo de autenticação Basic está habilitado para aquele diretório virtual, e caso contrário, uma exceção do tipo NotSupportedException será disparada, informando que o modo Basic não está habilitado.
Só que se você habilitá-lo, o problema volta a acontecer, pois a ideia por trás desta técnica, é utilizar o Basic como forma de envio das credenciais, mas não de validá-las, e com isso, se você colocar um usuário e senha que não existe dentro do Windows, ele não deixará você acessar o serviço, e mesmo que você digite um usuário/senha válidos, a implementação da classe UserNamePasswordValidator nunca será executada. Para que isso seja possível, você precisa modificar o pipeline do ASP.NET, acoplando módulos customizados que farão esse trabalho.