Zoals ik in de opmerking al zei, worden de machtigingen op serverniveau verwijderd zodra u imitatie gebruikt.
Er zijn 2 manieren om dit te omzeilen:
De slechte en snelle manier:
Stel uw database stuwkracht in op AAN. Het zal de klus klaren. Maar als je niet helemaal begrijpt wat dit doet, zou mijn advies zijn om dit NIET te doen.
hier is echter de code:
ALTER DATABASE [YourDatabase] SET TRUSTWORTHY ON;
De goede maar langzamere manier
Dit is veel nauwkeuriger en heeft geen vervelende beveiligingsbijwerkingen.
Wat u doet, is dat u uw opgeslagen procedure ondertekent met een certificaat. U maakt een gebruiker van dat certificaat in de database. U geeft die gebruiker de juiste machtigingen op uw tafel in de database. U maakt ook een login aan vanaf hetzelfde certificaat en verleent die login de bulkrechten.
Omdat je het opgeslagen proces met dat certificaat ondertekent, wordt elke keer dat de sp wordt uitgevoerd, het uitgevoerd in de context van die gebruiker en log je in op dat waar het is gemaakt met dat certificaat.
de stappen zijn:
-
Certificaat aanmaken in master
-
maak een login aan vanaf dat certificaat
-
Verleen bulkbeheerdersrechten voor die login
Nu heb je precies hetzelfde certificaat nodig in je gebruikersdatabase, dus we moeten nog wat extra stappen doen
-
Exporteer het certificaat naar schijf
-
Importeer het certificaat in uw gebruikersdatabase
nu kunnen we afronden
- gebruiker maken van het certificaat
- toestemming op tafel verlenen aan die gebruiker
- verwijder execute as-clausule uit uw opgeslagen procedure
- Onderteken uw opgeslagen procedure met uw certificaat
hier is de code:
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
Laatste opmerking:
Vervang uw map door een pad waarvan u zeker weet dat het sql-serviceaccount toestemming heeft om te schrijven!
Zorg ervoor dat u die geëxporteerde certificaten verwijdert nadat u klaar bent met instellen.