OlĂ¡ pessoal,
Boa noite!
Neste post vou falar sobre um erro que ocorre ao tentar utilizar o comando OPENROWSET ou OPENQUERY para acessar dados de um servidor remoto onde o linked server utilizado nĂ£o tenha um usuĂ¡rio fixo e o usuĂ¡rio da conexĂ£o nĂ£o pertença Ă role sysadmin, o que representa a maioria dos casos. (mais um erro reportado pelo Henrique Mauri.. kkk)
Msg 7416, Level 16, State 2, Line 22
Access to the remote server is denied because no login-mapping exists.
Esse erro Ă© muito parecido com o cenĂ¡rio de “double hop” que ocorre no Kerberos, onde uma aplicaĂ§Ă£o cliente estĂ¡ no computador 1, o BizTalk RFID estĂ¡ no computador 2, e o recurso que requer as credenciais (como por exemplo, um servidor SQL Server RFIDsink) estĂ¡ no computador 3, mas nesse post vou mostrar uma soluĂ§Ă£o apenas utilizando o SQL Server. Caso vocĂª queira se aprofundar na soluĂ§Ă£o do problema utilizando o Kerberos, dĂª uma lida nesse post.
Simulando o erro no seu ambiente
Uma forma prĂ¡tica de simular esse problema Ă© criando um novo linked server com o parĂ¢metro @useself=N’True’, informando que o mesmo usuĂ¡rio serĂ¡ utilizado nas duas pontas da conexĂ£o, que serĂ¡ o usuĂ¡rio atualmente conectado, e depois tentar utilizar esse linked server.
Como jĂ¡ mencionado acima, essa mensagem de erro sĂ³ aparece quando o usuĂ¡rio que estĂ¡ executando a query NĂƒO faça parte da role sysadmin e o usuĂ¡rio da conexĂ£o esteja utilizando autenticaĂ§Ă£o SQL Server (ao invĂ©s da AutenticaĂ§Ă£o Windows).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
---------------------------------- -- CRIAĂ‡ĂƒO DO LINKED SERVER ---------------------------------- USE [master] GO DECLARE @instancia NVARCHAR(200) = N'127.0.0.1\SQL2014' IF ((SELECT COUNT(*) FROM sys.servers WHERE name = @instancia) > 0) EXEC master.dbo.sp_dropserver @server=@instancia, @droplogins='droplogins' EXEC master.dbo.sp_addlinkedserver @server = @instancia, @srvproduct=N'SQL Server' EXEC master.dbo.sp_addlinkedsrvlogin @rmtsrvname=@instancia,@useself=N'True',@locallogin=NULL,@rmtuser=NULL,@rmtpassword=NULL ---------------------------------- -- CRIAĂ‡ĂƒO DA TABELA DE TESTES ---------------------------------- SELECT * FROM OPENROWSET('SQLNCLI', 'Server=127.0.0.1;Trusted_Connection=yes;', 'SELECT * FROM Testes.dbo.Teste') AS a |
Como resolver o problema
Pelo que eu citei mais acima, estĂ¡ claro que se o usuĂ¡rio que estĂ¡ realizando a conexĂ£o for adicionado Ă role sysadmin, esse problema irĂ¡ parar de ocorrer, mas eu nem considero isso uma soluĂ§Ă£o. Conceder privilĂ©gios (ainda mais de sysadmin) sĂ³ para parar mensagens de erro nunca Ă© soluĂ§Ă£o.
TambĂ©m nĂ£o sou muito a favor de fixar o usuĂ¡rio e senha no Linked Server, de forma que todos os usuĂ¡rios com acesso ao servidor possam utilizar esse Linked Server de forma irrastreĂ¡vel. Sempre marque a opĂ§Ă£o “Be made using the login’s current security context” no LinkedServer.
Uma boa soluĂ§Ă£o seria utilizar AutenticaĂ§Ă£o Windows, mas como a equipe de desenvolvimento da empresa onde ocorreu esse problema nĂ£o iria nem cogitar a hipĂ³tese de alterar a autenticaĂ§Ă£o de todas as aplicações para AutenticaĂ§Ă£o Windows, a melhor soluĂ§Ă£o que eu encontrei para esse problema foi criar um novo usuĂ¡rio apenas para utilizações do OPENROWSET e OPENQUERY, com acessos restritos apenas para as consultas realizadas com esses dois comandos (que sĂ£o bem poucas) e fixar esse usuĂ¡rio e senha no OPENROWSET, ficando dessa forma:
1 2 |
SELECT * FROM OPENROWSET('SQLNCLI', 'server=127.0.0.1\SQL2014;Uid=Usuario_Teste;Pwd=aaa', 'SELECT * FROM Testes.dbo.Teste') AS a |
E Ă© isso aĂ, pessoal!
Se vocĂª souber alguma soluĂ§Ă£o diferente para esse problema, deixe sua sugestĂ£o nos comentĂ¡rios.
Abraço e até mais!