Membership: Geração/Reset de Password


Se voce está utilizando as funcionalidades de autenticação do ASP.NET 2.0, então é provável que voce já se deparou com a necessidade de recuperar/redefinir (PasswordRecovery) a senha de uma determinado usuário. Há um detalhe importante a ser observado quando voce habilita esta funcionalidade.

O comportamento deste controle merece uma atenção especial para os dois cenários suportados:

  • enablePasswordRetrieval = true: quando esta opção está definida como true, obriga voce também a definir a propriedade passwordFormat para um valor diferente de Hashed. Se esta combinação de valores for atendida, a senha será recuperada da base de dados e enviada para o e-mail do respectivo usuário.
  • enablePasswordRetrieval = false: esta configuração é geralmente utilizada quando a propriedade passwordFormat é definida como Hashed, ou seja, não será possível recuperar a senha da base de dados, pois ela foi hasheada. Neste caso, quando o usuário utilizar o controle PasswordRecovery, então ele gerará uma nova senha e, é neste momento que começa toda a confusão.

O processo para a geração da nova senha invoca, indiretamente, o método GeneratePassword do provider selecionado que, na maioria dos casos, é o SqlMembershipProvider. Dentro deste método há uma chamada para o método estático GeneratePassword da classe Membership. A confusão ocorre aqui por causa de dois atributos que são configurados no arquivo Web.Config: minRequiredPasswordLength e minRequiredNonalphanumericCharacters. Esses valores servem apenas para validação de senhas informadas pelo usuário mas, para o processo de geração automática (reset), são desprezados.

O SqlMembershipProvider tem um comportamento padrão que é: se o valor informado no atributo minRequiredPasswordLength for menor que 14, ele assume 14; o valor do atributo minRequiredNonalphanumericCharacters é sempre informado mas, pela lógica implementada, não mudará em nada.

O que voce precisa fazer é sobrescrever o método GeneratePassword da classe SqlMembershipProvider e, colocar a regra necessária para mudar o comportamento padrão. Eis aqui uma possível implementação:

using System.Security.Cryptography;

public class CustomMembershipProvider : SqlMembershipProvider
{
    private static char[] chars = “a0bc1d2efgh3i4jkl5m6n7o8p9qrstuvuyzw”.ToCharArray();

    public override string GeneratePassword()
    {
        if (this.MinRequiredNonAlphanumericCharacters == 0)
        {
            byte[] randomBytes = new byte[this.MinRequiredPasswordLength];
            char[] result = new char[this.MinRequiredPasswordLength];
            new RNGCryptoServiceProvider().GetBytes(randomBytes);

            for (int i = 0; i < this.MinRequiredPasswordLength; i++)
            {
                int index = ((int)randomBytes[i]) % chars.Length;
                result[i] = chars[index];
            }

            return new string(result);
        }
        else
        {
            return base.GeneratePassword();
        }
    }
}

//Configuração (Web.Config):
<membership defaultProvider=”SqlMembershipProvider”>
    <providers>
        <clear/>
        <add
            name=”SqlMembershipProvider”
            type=”CustomMembershipProvider”
            minRequiredNonalphanumericCharacters=”0″
            minRequiredPasswordLength=”5″/>
    </providers>
</membership>

Anúncios

Deixe uma resposta

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s