Gerenciando usuários do SQL Server com C# Fernando Datorre Setembro 2012 Um tema antigo na vida dos programadores se refere ao login dos usuários em seus sistemas. O que geralmente encontramos, quase sempre, são desdobramentos da mesma solução: o programador cria as tabelas de usuários no seu banco de dados (com informações nome, login senha e direitos) e solicita que o mesmo digite esses dados de login na primeira tela do programa, validando ou não sua entrada. Quase sempre, por de trás dos panos, o programador se utiliza da conta de super usuário existente (sa, sysadmin, root) para execução dos comandos t-sql. Esta solução, apesar de fácil e comum, esconde alguns problemas posteriores: Falta de segurança: o programador ou dba nunca sabe quem executou os comandos no banco, já que apenas uma instancia do usuário padrão está sendo usada. Logs: os logs (históricos das operações) precisam que ser feitos (executados) via programa e não automaticamente pelo banco, isso deve-se a mesma questão citada acima, haverá sempre o mesmo usuário logado para todas as pessoas. Na tentativa de minimizar esses problemas, uma das soluções seria integrar a aplicação ao sistema de segurança do próprio banco de dados, exigindo que cada usuário realize o login com seus dados de acesso a cada vez que for usar o programa. Cada banco tem suas diretrizes de segurança, vou me ater ao Microsoft SQL Server que já trabalho a algum tempo. A Solução Para realizar a integração de maneira transparente, estabelecemos como meta a criação de uma aplicação que possibilite listar, criar, excluir, dar e tirar permissão de acesso a um usuário diretamente no aplicativo (no caso aqui programado em C#). Esta aplicação desenvolvida será utilizada para exemplificação das ideias (é um projeto apenas conceitual para este artigo): Listar os Logins existentes O primeiro passo é listar os logins existentes no banco. Você poderia utilizar um código semelhante a este: void UsersList() string strconnsa = @"Data Source=FERNANDO-NOTE\SQL08;Initial Catalog=Master;User ID=sa; Password=123"; SqlConnection conn = new SqlConnection(strConnSA); SqlCommand cmd = new SqlCommand(); cmd = new SqlCommand("select name as loginuser, createdate, updatedate from master..syslogins", conn); cmd.commandtype = CommandType.Text; SqlDataAdapter adapter = new SqlDataAdapter(cmd); DataTable table = new DataTable(); adapter.fill(table); loginsdatagridview.datasource = table; qtdelabel.text = "Registros: " + table.rows.count.tostring(); MessageBox.Show(String.Format("0: 1", ex.number, ex.message), ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error); Gerenciando usuários do SQL Server com C#- Fernando Datorre Setembro 2012 Página 1 de 7
O resultado seria mais ou menos assim: O objetivo aqui não é discutir código C# e sim os comandos que usaremos para realizar as operações. No caso, o importante é o select na tabela syslogins para mostrar os logins já criados no banco. Esta mesma consulta é utilizada no própria ferramenta de gerenciamento do SQL Server: Gerenciando usuários do SQL Server com C#- Fernando Datorre Setembro 2012 Página 2 de 7
Login de um usuário: Para realizar o login, basta passar os dados do usuário e abrir a conexão, caso ele não exista ou não seja permitido, uma exceção será lançada. /// Método que realiza o login com os dados repassados /// <param name="username">usuário que se deseja realizar o login</param> /// <param name="password">senha do usuário</param> private void UserLogin(String username, String password) string strconnuser = "Data Source=Fernando-Note\\SQL08;Initial Catalog=Master;User ID=" + username + ";Password=" + password + ""; SqlConnection conn = new SqlConnection(strConnUser); //tenta abrir a conexão.. se não conseguir vai dar erro MessageBox.Show("Login efetuado com sucesso!", ProductName, MessageBoxButtons.OK, MessageBoxIcon.Information); if (ex.number == 18456) MessageBox.Show("Usuário ou senha inválido!", ProductName, MessageBoxButtons.OK, MessageBoxIcon.Warning); else if (ex.number == 18488) MessageBox.Show("Usuário precisa alterar a senha.", ProductName, MessageBoxButtons.OK, MessageBoxIcon.Warning); else MessageBox.Show(String.Format("0: 1", ex.number, ex.message), ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error); Para ilustrar tentamos consultar um usuário que ainda não foi criado. Procurando o usuário teste com a senha 123 é exibido a mensagem de usuário não encontrado: Gerenciando usuários do SQL Server com C#- Fernando Datorre Setembro 2012 Página 3 de 7
Criando um Login de Usuário O código para inserir um login é divido em duas partes. Na primeira o login é criado e na segunda é registrado o direito de acesso do mesmo. Cabe aqui ressaltar que, dependendo da maneira que você quer que seus usuários interajam com o banco de dados, direitos com mais ou menos acesso podem ser definidos. Faça uma pesquisa pela documentação do SQL Server para saber mais a respeitos de logins e regras (roles) de acesso. /// Método que cria um novo usuário no SQL Server /// <param name="username">usuário que se deseja criar o login</param> /// <param name="password">senha do usuário</param> private void UserInsert(String username, String password) SqlConnection conn = new SqlConnection("Data Source=Fernando-Note\\SQL08;Initial Catalog=Master;Integrated Security=True"); // Creating a login specific to SQL Server. SqlCommand cmd = new SqlCommand("CREATE LOGIN " + username + " WITH PASSWORD=N'" + password + "', DEFAULT_DATABASE=SimpleClinic, DE FAULT_LANGUAGE=us_english, CHECK_EXPIRATION=OFF, CHECK_POLICY=OFF", conn); //executa os direitos de acesso cmd = new SqlCommand("EXEC sys.sp_addsrvrolemember @loginame = N'" + username + "', @rolename = N'sysadmin'", conn); MessageBox.Show("Login Criado com sucesso!", ProductName, MessageBoxButtons.OK, MessageBoxIcon.Information); Close(); if (ex.number == 15025) MessageBox.Show("Login já existe.", ProductName, MessageBoxButtons.OK, MessageBoxIcon.Warning); else MessageBox.Show(String.Format("0: 1", ex.number, ex.message), ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error); Depois de preencher os dados e salvar: Resultado mostrado no SQL Management Studio Se tentarmos fazer o login no SQL Server do usuário criado notamos que já está tudo ok: Gerenciando usuários do SQL Server com C#- Fernando Datorre Setembro 2012 Página 4 de 7
Alterando a Senha de Um Usuário: Para alterar a senha de login do usuário, o comando é simples. Neste caso, montamos antes apenas um código de verificação para garantir que não seja trocada a senha de um usuário sem o consentimento do mesmo. /// Método que altera a senha de um usuário /// <param name="username">usuário</param> /// <param name="pwdold">senha atual - antiga</param> /// <param name="pwdnew">nova senha desejada</param> private void UserUpdatePwd(String username, String pwdold, String pwdnew) string strconnuser = @"Data Source=FERNANDO-NOTE\SQL08;Initial Catalog=Master;User ID=" + username + "; Password=" + pwdold; string strconnsa = @"Data Source=FERNANDO-NOTE\SQL08;Initial Catalog=Master;User ID=sa; Password=123"; SqlConnection conn = new SqlConnection(); SqlCommand cmd = new SqlCommand(); //abre a conexão...se der certo a senha e o usuário atual estão ok conn = new SqlConnection(strConnUser); //está ok, agora abre a conexão com o usuário SA para alterar conn = new SqlConnection(strConnSA); cmd = new SqlCommand("ALTER LOGIN " + username + " WITH PASSWORD = '" + pwdnew + "'", conn); //executa a alteração MessageBox.Show("Senha de Login Alterada com sucesso!", ProductName, MessageBoxButtons.OK, MessageBoxIcon.Information); Close(); if (ex.number == 15025) MessageBox.Show("Login já existe.", ProductName, MessageBoxButtons.OK, MessageBoxIcon.Warning); else MessageBox.Show(String.Format("0: 1", ex.number, ex.message), ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error); Gerenciando usuários do SQL Server com C#- Fernando Datorre Setembro 2012 Página 5 de 7
Habilitando e desabilitando um Login Podemos habilitar ou desabilitar o acesso de um usuário de forma muito simples, vejamos: /// Método que Habilita ou desabilita um usuário /// <param name="username">usuário desejado</param> /// <param name="enable">habilitar ou não o usuário</param> private void EnableDisableUser(String username, Boolean enable) string strconnsa = @"Data Source=FERNANDO-NOTE\SQL08;Initial Catalog=Master;User ID=sa; Password=123"; SqlConnection conn = new SqlConnection(); SqlCommand cmd = new SqlCommand(); conn = new SqlConnection(strConnSA); cmd = new SqlCommand("ALTER LOGIN " + username + " " + (enable? "ENABLE" : "DISABLE"), conn); //executa a alteração MessageBox.Show("Login " + (enable? "Habilitado" : "Desabilitado") + " com sucesso!", ProductName, MessageBoxButtons.OK, MessageBoxIcon.Information); Close(); MessageBox.Show(String.Format("0: 1", ex.number, ex.message), ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error); Para conferirmos se o comando realmente funciona na prática, vamos o teste: Gerenciando usuários do SQL Server com C#- Fernando Datorre Setembro 2012 Página 6 de 7
Excluindo um Login Na aplicação teste disponível no site http://www.simplesistemas.com.br/aplicativos você pode ver todos os códigos usados e algumas funcionalidades que deixei de fora deste artigo, como, por exemplo, o DROP que é usado excluir um login. Conclusão Nos códigos e telas acima tentamos exercitar alguns conceitos que podem enriquecer seus códigos ou auxiliar em algum a tarefa que estejam realizando. É claro que nos prendemos a códigos mais simples do que serão usados em aplicações comerciais, devido, principalmente, as regras de negócio envolvidas, porém, estes códigos são as bases de integração entre seus aplicativos e o banco de dados. A ideia apresentada aqui é criar uma nova forma de controle dos seus acessos, com mais segurança e simplificando algumas tarefas penosas do dia a dia. Espero que os códigos seja de alguma ajuda. [] s Fernando Datorre Microsoft.Net C# Architect Simple Sistemas 17 3421-4525 fernando@simplesistemas.com.br Gerenciando usuários do SQL Server com C#- Fernando Datorre Setembro 2012 Página 7 de 7