Autenticação utilizando DataSnap 2010 e TCP/IP Transport
Uma das perguntas mais frequentes em relação ao DataSnap se diz respeito a como implementar autenticação no DataSnap Server utilizando TCP/IP como Transporter (componente TDSTCPServerTransporter), visto que quando utilizamos HTTP temos um componente e método expecifico para tal tarefa.
A pergunta é válida, pois sem isso qualquer um poderá conectar a seu servidor DataSnap e executar os Server Methods disponíveis. O objetivo deste post é mostrar como fazer isso de forma bem simples.
Vou assumir aqui que você já tem algum conhecimento do novo DataSnap, em caso contrário recomendo ler os posts e assistir os vídeos aqui publicados.
Para começar temos que passar ao servidor o usuário e senha, como o seu caminho de conexão é o componente SQLConnection é nele que estaremos armazenado estas duas informações, utilizando a propriedade Params.
Geralmente utilizamos UserName e Password como parâmetro, o que não é errado, mas eu recomendo você utilizar os parâmetros DSAuthenticationUser e DSAuthenticationPassword, porque em caso de se ter outras aplicações conectando ao seu servidor e utilizando HTTP como parâmetro, você terá que usar estes parâmetros, desta forma sendo HTTP ou TCP padronizamos neste dois parâmetros.
Nosso código no lado cliente ficaria assim:
With SQLConnection1 do begin Params.Values['HostName'] := Server; // Endereço do DataSnap Server Params.Values['Port'] := Port; // Porta Params.Values['DSAuthenticationUser'] := 'Usuario'; // Login do Usuário Params.Values['DSAuthenticationPassword'] := 'Senha'; // Senha Usuário end;
Já no lado servidor, faremos a autenticação utilizando o evento OnConnect do componente DSServer.
O evento OnConnect nos fornece o parâmetro DSConnectEventObject o qual nos traz os dados da conexão através da propriedade ConnecProperties, desta forma você terá acesso aos dois parâmeteros enviados pela aplicação cliente e todos os outros valores parte da lista de parâmetros.
No exemplo abaixo as variáveis login e password recebem os valores das propriedades DSAuthenticationUser e DSAuthenticationPassword e em seguinda fazem a validação através da classe TUser, que é uma classe utilizada no exemplo.
Em caso de login ou senha inválido o servidor gera uma Exception, qualquer exception gerada no evento OnConnect inválida a conexão, ou seja, a aplicação cliente não efetuou a conexão ao servidor.
With DSConnectEventObject.ConnectProperties do begin login := Properties.Values['DSAuthenticationUser']; password := Properties.Values['DSAuthenticationPassword']; end; userConn := TUser.Create; try if not userConn.IsValidUser(login, password) then raise Exception.Create('Invalid Login/Password'); finally userConn.Free; end;
Meus exemplos sobre DataSnap foram atualizados com o código acima e já estão disponíveis para download.
Andreanos, e como pegar essas informações da conexão quando um appclient executa um método public do appserver, depois de devidamenteo autenticado? Há como fazer isso?
Obrigado
Neste caso uma forma é você manter o usuário em uma thread e verificar esta antes da execução método.
Sem dúvidas nas próximas versões vamos tornar isso mais fácil.