Jak powiedziałem w komentarzu, uprawnienia na poziomie serwera są odbierane w momencie użycia personifikacji.
Można to obejść na dwa sposoby:
Zły i szybki sposób:
Ustaw swoją bazę danych na ON. To wykona zadanie. Ale jeśli nie rozumiesz w pełni, co to robi, radzę tego NIE robić.
jednak oto kod:
ALTER DATABASE [YourDatabase] SET TRUSTWORTHY ON;
Dobry, ale wolniejszy sposób
Jest to o wiele bardziej precyzyjne i nie ma żadnych nieprzyjemnych skutków ubocznych związanych z bezpieczeństwem.
To, co robisz, to podpisywanie procedury składowanej za pomocą certyfikatu. Tworzysz użytkownika z tego certyfikatu w bazie danych. Nadajesz temu użytkownikowi odpowiednie uprawnienia do tabeli w bazie danych. Tworzysz również login z tego samego certyfikatu i nadajesz temu loginowi uprawnienia zbiorcze.
Ponieważ podpisujesz przechowywany proces tym certyfikatem, za każdym razem, gdy sp zostanie wykonany, jest on wykonywany w kontekście tego użytkownika i loguje się do utworzonego z tego certyfikatu.
kroki to:
-
Utwórz certyfikat w master
-
utwórz login z tego certyfikatu
-
Przyznaj zbiorcze uprawnienia administratora do tego loginu
Teraz potrzebujesz dokładnie tego samego certyfikatu w swojej bazie danych użytkowników, więc mamy kilka dodatkowych kroków do wykonania
-
Eksportuj certyfikat na dysk
-
Zaimportuj certyfikat do swojej bazy danych użytkowników
teraz możemy sfinalizować
- utwórz użytkownika na podstawie certyfikatu
- przyznaj uprawnienia do tabeli temu użytkownikowi
- usuń klauzulę execute as z procedury składowanej
- Podpisz swoją procedurę składowaną swoim certyfikatem
oto kod:
USE master
go
CREATE CERTIFICATE BulkInsertCert
ENCRYPTION BY PASSWORD = 'NicePassword!0'
WITH SUBJECT = 'Gives Bulk Insert Privilegde'
go
CREATE LOGIN BulkInsert_CertLogin FROM CERTIFICATE BulkInsertCert
go
GRANT ADMINISTER BULK OPERATIONS TO BulkInsert_CertLogin
go
BACKUP CERTIFICATE BulkInsertCert TO FILE = '[your directory]\BulkInsertCert.cer'
WITH PRIVATE KEY (FILE = '[your directory]\BulkInsertCert.pvk' ,
ENCRYPTION BY PASSWORD = 'EvenNicerPassword!0',
DECRYPTION BY PASSWORD = 'NicePassword!0')
go
USE [YourDatabase]
CREATE CERTIFICATE BulkInsertCert FROM FILE = '[your directory]\BulkInsertCert.cer'
WITH PRIVATE KEY (FILE = '[your directory]\BulkInsertCert.pvk',
DECRYPTION BY PASSWORD = 'EvenNicerPassword!0',
ENCRYPTION BY PASSWORD = 'TheVeryBestPasswordThereIs!0')
go
--NOW DELETE THE CERTIFICATES FROM DISK
CREATE USER BulkInsert_CertUser FOR CERTIFICATE BulkInsertCert
go
GRANT ALTER, INSERT ON [YourTable] TO BulkInsert_CertUser
go
ALTER PROCEDURE usp_myproc
AS
EXEC('INSERT INTO ' + @tablename + '
SELECT col1, col2, col3
FROM OPENROWSET(
BULK '''+ @filepath +''',
FORMATFILE='''+ @formatfile +''',
FIRSTROW=2
)as t'
)
-- Sign the test procedure each time you have changed it.
ADD SIGNATURE TO usp_myproc BY CERTIFICATE BulkInsertCert
WITH PASSWORD = 'TheVeryBestPasswordThereIs!0'
go
Uwaga końcowa:
Zastąp Twój katalog ścieżką, w której masz pewność, że konto usługi sql ma uprawnienia do zapisu!
Upewnij się, że usuniesz te wyeksportowane certyfikaty po zakończeniu konfiguracji.