Diferenciar maiúsculas no login e na senha

.NET

25/10/2013

Para diferenciar maiúsculas no login e na senha montei estes dois códigos, mas nenhum funciona, o que está errado ?

OleDbCommand comando = new OleDbCommand("SELECT * FROM Funcionario Where Login = '@Login' And Senha = '@Senha' COLLATE Latin1_General_CS_AS", conexao);


OleDbCommand comando = new OleDbCommand("SELECT * FROM Funcionario Where Login COLLATE Latin1_General_CS_AS = '" + @Login.Trim() +"' And Senha COLLATE Latin1_General_CS_AS = '" + @Senha.Trim() + "', conexao);


Jair Souza

Jair Souza

Curtidas 0

Respostas

Marcio Araujo

Marcio Araujo

25/10/2013

Jair, pesquisei sobre isso no php mas não encontrei nenhuma solução, uma pergunta, isso deve ser feito no php ou no proprio banco.
GOSTEI 0
Jair Souza

Jair Souza

25/10/2013

Verificando
GOSTEI 0
Jair Souza

Jair Souza

25/10/2013

Com o primeiro código dá o erro abaixo :

[url]http://www.uploaddeimagens.com.br/imagens/erro_colate_1-png[/url]

...e osegundo nem consegui acertar dentro do código.

Agradeço se puder ajudar.



GOSTEI 0
Joel Rodrigues

Joel Rodrigues

25/10/2013

O segundo está bem errado, esqueça ele.
Vamos trabalhar no primeiro. Comece removendo as aspas simples que tem em volta dos parâmetros e teste novamente.

Ah, qual banco você está usando?
GOSTEI 0
Jair Souza

Jair Souza

25/10/2013

O banco é ACCESS.
Mesmo tirando as aspas dá o mesmo erro, o código está assim :

OleDbCommand comando = new OleDbCommand("SELECT F.Perfil, P.Descricao FROM Funcionario AS F " + " INNER JOIN Perfil AS P ON F.Perfil = P.IDPerfil Where F.Login = @Login And F.Senha = @Senha COLLATE Latin1_General_CS_AS", conexao);
GOSTEI 0
Joel Rodrigues

Joel Rodrigues

25/10/2013

Tente modificar o WHERE para o seguinte:
Where F.Login COLLATE Latin1_General_CS_AS= @Login COLLATE Latin1_General_CS_AS And F.Senha COLLATE Latin1_General_CS_AS = @Senha COLLATE Latin1_General_CS_AS


Se não der, tente tirar o collate que fica depois dos parâmetros, deixando apenas depois dos campos.
GOSTEI 0
Jair Souza

Jair Souza

25/10/2013

Alterei para as duas formas, e nenhuma das duas funcionou, continua dando o mesmo erro.

OleDbCommand comando = new OleDbCommand("SELECT * FROM Funcionario AS F" + "INNER JOIN Perfil AS P ON F.Perfil = P.IDPerfil Where F.Login COLLATE Latin1_General_CS_AS = @Login F.Senha COLLATE Latin1_General_CS_AS = @Senha ", conexao);
GOSTEI 0
Joel Rodrigues

Joel Rodrigues

25/10/2013

Cara, só agora reparei que falta um espaço depois do "F" (apelido da tabela). Ponha aí para ver se não é isso que está bagunçando.
GOSTEI 0
Jair Souza

Jair Souza

25/10/2013

Não resolveu...com esta linha exatamente como está tirando somente a parte do "COLLATE Latin1_General_CS_AS", faz o login normal, mas sem diferenciar maiusculas, é alguma detalhe ligado diretamente ao COLLATE...

Coloquei o COLLATE no campo e no parâmetro, somente no campo e depois somente no parâmetro, entre parênteses e sem parenteses...e nada

OleDbCommand comando = new OleDbCommand("SELECT * FROM Funcionario AS F " + "INNER JOIN Perfil AS P ON F.Perfil = P.IDPerfil Where F.Login COLLATE Latin1_General_CS_AS = @Login F.Senha COLLATE Latin1_General_CS_AS = @Senha ", conexao);
GOSTEI 0
Jair Souza

Jair Souza

25/10/2013

E aí pessoal !
Alguma dica ?
Eu já tentei quase tudo de orientações pesquisadas na net, menos uma que desse certo.
O que eu acho estranho não ter algo objetivo para este caso, pois me parece que todo login tem por obrigação diferenciar maiúsculas e acentos.
GOSTEI 0
Jair Souza

Jair Souza

25/10/2013

Bom dia, pessoal !
Realmente não encontro nada na net que solucione este problema...
Devo desistir ?
Ninguem tem uma idéia ?
GOSTEI 0
Joel Rodrigues

Joel Rodrigues

25/10/2013

Amigo, confesso que não respondi mais porque eu realmente nem sabia o que dizer. Nunca passei por tal situação. Mas pesquisando agora, encontrei o seguinte tópico em que o pessoal desencoraja bastante o cara que fez a pergunta, dizendo que não dá pra fazer. Veja só: [url]http://www.accessforums.net/queries/use-collate-statement-select-clause-1981.html[/url].
GOSTEI 0
[desativado] Gonçalves

[desativado] Gonçalves

25/10/2013

Pessoal,

tanto o mecanismo do JET (Access) quanto o mecanismo do SQL Server não diferenciam maiusculas de minusculas e nem caracteres acentuados de não acentuados (dependo do collation claro).

Mas a pergunta que fica é porque você tem que diferenciar maiusculas e minusculas no login e senha?

Por acaso você estaria permitindo, por exemplo, um usuário Teste e um usuário tesTe? Seriam diferentes para sua aplicação?
GOSTEI 0
Jair Souza

Jair Souza

25/10/2013

É que eu gostaria que quando o usuário fizer o login, tenha que digitar exatamente como foi cadastrado, mas no momento se digitar João ou joão é permitido o acesso.
GOSTEI 0
[desativado] Gonçalves

[desativado] Gonçalves

25/10/2013

Então, vai de cada um e das premissas de seu projeto mas, um sistema de autenticação por usuário e senha, por si só, não é a maneira mais segura de se fazer autenticação de um usuário mas, muitas vezes, é o que podemos fazer.

Já que não há outro jeito e precisa ser assim (não importando o motivo), a força da sua autenticação (ainda que esteja vulnerável a uma infinidade de tipos de ataques) está na maneira de guardar e verificar a senha.

Veja, imagino que o username na sua aplicação seja a chave da tabela. Se for, não faz sentido diferenciar Joao de joAo. Para o banco de dados, conforme exposto, será a mesma coisa e se você cadastrar outro JOao, vai haver problema de chave duplicada.

O que eu sempre faço, nesses casos, é colocar uma chave composta como, por exemplo, o e-mail e o username. Deste modo, fica mais difícil eu ter um username Joao com e-mail joao@dominio.com.br

Neste caso, o e-mail dele me ajuda a deixar o usuário quase que ÚNICO. Outra coisa boa a fazer é usar o CPF como username ou parte da chave composta. Afinal, CPF é um dos poucos documentos federais garantido de ser único.

Para proteção da senha, eu sempre guardo um HASH da mesma. Me avisa se não souber o que é e como computar o hash que eu te explico. Isto pode ser feito tanto no código da aplicação quanto no banco de dados. Como uma função HASH retorna a senha "protegida" e não pode ser revertida, ou seja, com o resultado do HASH eu não chego na senha, eu guardo o resultado do HASH no banco, no campo da senha, e toda vez que o usuário informa a senha dele, eu tiro o HASH novamente e verifico com o que está gravado no banco.

Deste modo, nem eu nem ninguém consegue saber o que o usuário digitou.

Claro que, você estará com isto vulnerável a ataques por MiTM (Man in The Middle) onde eu consigo facilmente capturar a senha do usuario (o HASH mesmo) e usá-lo mais tarde para autenticar e ganhar acesso aos dados dele. Existem técnicas para proteger contra estes tipos de ataques, configurações de servidor e, infelizmente, mudar drasticamente o seu código de autenticação.
GOSTEI 0
Jair Souza

Jair Souza

25/10/2013

Bom então parece mais coerente para um aplicativo simples, criar um código para verificar se já tem “Joao” cadastrado e também verificar se este “Joao” Já está logado.
Se já tem “Joao” cadastrado não cadastra outro.
Se já está logado não logar outra vez.
E deixar digitar o “Joao” como quiser.
GOSTEI 0
Joel Rodrigues

Joel Rodrigues

25/10/2013

Amigo, geralmente o campo login não é case sensitive, ou seja, não diferencia maiúsculas de minúsculas. Isso geralmente é aplicado apenas no campo senha.
GOSTEI 0
[desativado] Gonçalves

[desativado] Gonçalves

25/10/2013

Isso mesmo Jair. Fica mais fácil assim não é mesmo?
GOSTEI 0
Jair Souza

Jair Souza

25/10/2013

Com certeza, mas para a senha parece importante diferenciar ?
GOSTEI 0
Joel Rodrigues

Joel Rodrigues

25/10/2013

Com certeza, mas para a senha parece importante diferenciar ?
Para a senha é fundamental que seja diferenciado, inclusive alguns sistemas requerem que a senha seja composta por letras maiúsculas e minúsculas (além de caracteres especiais e numéricos, em alguns casos).
GOSTEI 0
Jair Souza

Jair Souza

25/10/2013

...sim, mas como fazer ? Já que COLLATE Latin1_General_CS_AS não dá.
Partindo do que já tenho nesta linha :

OleDbCommand comando = new OleDbCommand("SELECT * FROM Funcionario F " + "INNER JOIN Perfil AS P ON F.Perfil  = P.IDPerfil Where [F.Login] = @Login and [F.Senha] = @Senha and F.Situacao = true", conexao);
GOSTEI 0
[desativado] Gonçalves

[desativado] Gonçalves

25/10/2013

Jair,

não entendi.

Você deve ter uma tabela de "Funcionario" associada a uma de "Perfil". Este "Perfil" tem um usuário eu uma senha.

Username deve ser chave ou parte dela.
A senha é a senha. Unica e intransferível associada aquele usuário.

Para logar, usuario digitado deve ser igual ao usuário no banco, senha digitada deve ser igual a senha no banco e mais quaisquer outras regras que você decidir.

O que mais falta?
GOSTEI 0
Jair Souza

Jair Souza

25/10/2013

A senha pode ser "a123b" ou "A123B" ou "A123b" ou ...porque não diferencia maiúscula de minúscula.
Me parece que essa senha não é tão senha assim, não é ?
...mas é mais por capricho, que gostaria de que ficasse no rigor da comparação do que foi digitado com o que está banco.
Tipo é no Windows.
GOSTEI 0
[desativado] Gonçalves

[desativado] Gonçalves

25/10/2013

Então mas é por isso que eu te falei que o melhor seria você guardar o HASH da senha ao invés de a senha em claro. Desta maneira, a senha vai ficar relativamente protegida e não haverá possibilidade de gerar usuários e senhas iguais ...

Veja, se o usuário for parte da chave da tabela, não vão existir dois JOAO. Isto permite que mesmo que exista a senha TESTE para o JOAO e o RONALDO, não vai importar. Um não vai saber da existência do outro.

Não sei se acabei confundindo mais do que explicando ...
GOSTEI 0
Jair Souza

Jair Souza

25/10/2013

Este é o meu primeiro projeto...
Como eu faria o HASH ?
Tenho uma tabela Funcionario com os campos :

IDFuncionario - numeração automatica - chave primaria
Nome
Login
Senha
Perfil
Situacao

E uma tabela Perfil :

IDPerfil - Numeração automatica = chave primária
Nome
Descricao



GOSTEI 0
[desativado] Gonçalves

[desativado] Gonçalves

25/10/2013

Sugestão:

IDFuncionario - numeração automatica - chave primaria
Nome
Login - chave primaria
Senha
Perfil
Situacao

O resto fica como está.

Para gerar o HASH em JAVA você pode usar o seguinte:

import java.security.MessageDigest;

public class teste {

    public static String ComputeHash(String senha) {
        try {
            MessageDigest mecanismoDeHash = MessageDigest.getInstance("SHA-256");
            byte[] hashEmBytes = mecanismoDeHash.digest(senha.getBytes("UTF-8"));
            StringBuffer hashEmHexadecimal = new StringBuffer();

            for (int i = 0; i < hashEmBytes.length; i++) {
                String hex = Integer.toHexString(0xff & hashEmBytes[i]);
                if (hex.length() == 1) {
                    hashEmHexadecimal.append('0');
                }
                hashEmHexadecimal.append(hex);
            }

            return hashEmHexadecimal.toString();
        } catch (Exception ex) {
            throw new RuntimeException(ex);
        }
    }
}


Esse método deve ser usado quando você recebe a senha do usuário e vai gravar ela no banco quando faz o cadastro do usuário e quando recebe a senha no login para comparar com o que foi salvo no banco.
GOSTEI 0
[desativado] Gonçalves

[desativado] Gonçalves

25/10/2013

Desculpe, esqueci em C#

using System;
using System.Security.Cryptography;
using System.Text;

public class teste {

    static string ComputeHash(string senha) {
        SHA256Managed mecanismoDeHash = new SHA256Managed();
        string hashEmHexadecimal = String.Empty;
        byte[] bytesHash = mecanismoDeHash.ComputeHash(Encoding.UTF8.GetBytes(senha), 0, Encoding.UTF8.GetByteCount(senha));
        foreach(byte b in bytesHash)
        {
            hashEmHexadecimal += b.ToString("x2");
        }
        return hashEmHexadecimal;
    }
}
GOSTEI 0
POSTAR