Come ho detto nel commento, le autorizzazioni a livello di server vengono eliminate nel momento in cui usi la rappresentazione.
Ci sono 2 modi per aggirare questo problema:
Il modo cattivo e veloce:
Imposta il tuo database su ON. Farà il lavoro. Ma se non capisci appieno cosa fa questo, allora il mio consiglio sarebbe di NON farlo.
tuttavia, ecco il codice:
ALTER DATABASE [YourDatabase] SET TRUSTWORTHY ON;
Il modo buono ma più lento
Questo è molto più preciso e non ha effetti collaterali negativi sulla sicurezza.
Quello che fai è firmare la tua stored procedure con un certificato. Si crea un utente da quel certificato nel database. Concedi a quell'utente le autorizzazioni appropriate sulla tua tabella nel database. Crei anche un accesso dallo stesso certificato e concedi a quell'accesso le autorizzazioni in blocco.
Poiché firmi il processo archiviato con quel certificato, ogni volta che la sp viene eseguita, viene eseguita nel contesto di quell'utente e accedi a quello dove è stato creato da quel certificato.
i passaggi sono:
-
Crea certificato nel master
-
crea un accesso da quel certificato
-
Concedi autorizzazioni di amministratore in blocco a quell'accesso
Ora hai bisogno esattamente dello stesso certificato nel tuo database utente, quindi abbiamo alcuni passaggi extra da fare
-
Esporta il certificato su disco
-
Importa il certificato nel tuo database utente
ora possiamo finalizzare
- crea utente dal certificato
- Concedi l'autorizzazione sulla tabella a quell'utente
- rimuovere la clausola execute as dalla procedura memorizzata
- Firma la tua stored procedure con il tuo certificato
ecco il codice:
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
Nota finale:
Sostituisci la tua directory con un percorso in cui sei sicuro che l'account del servizio sql abbia il permesso di scrivere!
Assicurati di eliminare i certificati esportati dopo aver terminato la configurazione..