EXECUTE AS (Transact-SQL)EXECUTE AS (Transact-SQL)

SI APPLICA A: sìSQL Server sìDatabase SQL di Azure sìAzure SQL Data Warehouse noParallel Data Warehouse APPLIES TO: yesSQL Server yesAzure SQL Database yesAzure SQL Data Warehouse noParallel Data Warehouse

Imposta il contesto di esecuzione di una sessione.Sets the execution context of a session.

Per impostazione predefinita, una sessione inizia quando un utente si connette e termina quando l'utente si disconnette.By default, a session starts when a user logs in and ends when the user logs off. Tutte le operazioni eseguite durante una sessione sono soggette alle verifiche delle autorizzazioni dell'utente connesso.All operations during a session are subject to permission checks against that user. Quando viene eseguita un'istruzione EXECUTE AS, il contesto di esecuzione della sessione viene impostato sull'account di accesso o sul nome utente specificato.When an EXECUTE AS statement is run, the execution context of the session is switched to the specified login or user name. In seguito all'impostazione del contesto specifico, le autorizzazioni vengono verificate in base ai token di sicurezza dell'account di accesso e dell'account utente per l'account specifico anziché in base alla persona che ha chiamato l'istruzione EXECUTE AS.After the context switch, permissions are checked against the login and user security tokens for that account instead of the person calling the EXECUTE AS statement. In pratica, l'account utente o l'account di accesso viene rappresentato per l'intera durata dell'esecuzione della sessione o del modulo oppure il passaggio di contesto viene ripristinato in modo esplicito.In essence, the user or login account is impersonated for the duration of the session or module execution, or the context switch is explicitly reverted.

Icona di collegamento a un argomentoConvenzioni della sintassi Transact-SQLTopic link icon Transact-SQL Syntax Conventions

SintassiSyntax

{ EXEC | EXECUTE } AS <context_specification>  
[;]  
  
<context_specification>::=  
{ LOGIN | USER } = 'name'  
    [ WITH { NO REVERT | COOKIE INTO @varbinary_variable } ]   
| CALLER  

ArgomentiArguments

Account di accessoLOGIN
Si applica a: SQL Server 2008SQL Server 2008 tramite SQL Server 2017SQL Server 2017.Applies to: SQL Server 2008SQL Server 2008 through SQL Server 2017SQL Server 2017.

Specifica che il contesto di esecuzione da rappresentare è un account di accesso.Specifies the execution context to be impersonated is a login. L'ambito di rappresentazione è a livello di server.The scope of impersonation is at the server level.

Nota

Questa opzione non è disponibile in un database indipendente o nel database SQL di Azure o in Azure SQL Data Warehouse.This option is not available in a contained database or SQL Database or SQL Data Warehouse.

UtenteUSER
Specifica che il contesto da rappresentare è un utente nel database corrente.Specifies the context to be impersonated is a user in the current database. L'ambito di rappresentazione è limitato al database corrente.The scope of impersonation is restricted to the current database. Un cambio di contesto a un utente del database non eredita le autorizzazioni a livello di server di tale utente.A context switch to a database user does not inherit the server-level permissions of that user.

Importante

Mentre il cambio di contesto all'utente del database è attivo, qualsiasi tentativo di accesso alle risorse esterne al database comporterà l'esito negativo dell'esecuzione dell'istruzione.While the context switch to the database user is active, any attempt to access resources outside of the database will cause the statement to fail. Ciò è valido per le istruzioni USE database, le query distribuite e le query che fanno riferimento a un altro database che usa identificatori in tre o quattro parti.This includes USE database statements, distributed queries, and queries that reference another database that uses three- or four-part identifiers.

'name' Nome utente o nome account di accesso valido.'name' Is a valid user or login name. name deve essere membro del ruolo predefinito del server sysadmin oppure esistere come entità di sicurezza rispettivamente in sys.database_principals o sys.server_principals.name must be a member of the sysadmin fixed server role, or exist as a principal in sys.database_principals or sys.server_principals, respectively.

name può essere specificato come variabile locale.name can be specified as a local variable.

name deve essere un account singleton e non può essere un gruppo, un ruolo, un certificato, una chiave oppure un account predefinito, ad esempio NT AUTHORITY\LocalService, NT AUTHORITY\NetworkService o NT AUTHORITY\LocalSystem.name must be a singleton account, and cannot be a group, role, certificate, key, or built-in account, such as NT AUTHORITY\LocalService, NT AUTHORITY\NetworkService, or NT AUTHORITY\LocalSystem.

Per altre informazioni, vedere Specifica di un nome utente o un nome account di accesso di seguito in questo argomento.For more information, see Specifying a User or Login Name later in this topic.

NO REVERTNO REVERT
Specifica che non è possibile ripristinare il contesto precedente in seguito a un cambio di contesto.Specifies that the context switch cannot be reverted back to the previous context. L'opzione NO REVERT può essere usata solo a livello ad hoc.The NO REVERT option can only be used at the adhoc level.

Per altre informazioni sul ripristino del contesto precedente, vedere REVERT (Transact-SQL).For more information about reverting to the previous context, see REVERT (Transact-SQL).

COOKIE INTO @varbinary_variableCOOKIE INTO @varbinary_variable
Specifica che è possibile ripristinare il contesto di esecuzione precedente solo se l'istruzione REVERT WITH COOKIE chiamante contiene il valore corretto per @varbinary_variable.Specifies the execution context can only be reverted back to the previous context if the calling REVERT WITH COOKIE statement contains the correct @varbinary_variable value. Motore di databaseDatabase Engine passa il cookie a @varbinary_variable.The Motore di databaseDatabase Engine passes the cookie to @varbinary_variable. L'opzione COOKIE INTO può essere usata solo a livello ad hoc.The COOKIE INTO option can only be used at the adhoc level.

@varbinary_variable è varbinary(8000).@varbinary_variable is varbinary(8000).

Nota

Il parametro OUTPUT del cookie è attualmente documentato come varbinary(8000) che rappresenta la lunghezza massima corretta.The cookie OUTPUT parameter for is currently documented as varbinary(8000) which is the correct maximum length. Tuttavia, l'implementazione corrente restituisce varbinary(100).However the current implementation returns varbinary(100). Le applicazioni devono riservare varbinary(8000) in modo che siano in grado di funzionare correttamente se le dimensioni restituite del cookie aumentano in una versione successiva.Applications should reserve varbinary(8000) so that the application continues to operate correctly if the cookie return size increases in a future release.

CALLERCALLER
Se utilizzato all'interno di un modulo, specifica che le istruzioni all'interno del modulo vengono eseguite nel contesto del chiamante del modulo.When used inside a module, specifies the statements inside the module are executed in the context of the caller of the module. Se utilizzato all'esterno di un modulo, l'istruzione non esegue alcuna azione.When used outside a module, the statement has no action.

Nota

Questa opzione non è disponibile in SQL Data Warehouse.This option is not available in SQL Data Warehouse.

RemarksRemarks

Il cambio di contesto di esecuzione rimane valido finché non si verifica una delle situazioni seguenti:The change in execution context remains in effect until one of the following occurs:

  • Viene eseguita un'altra istruzione EXECUTE AS.Another EXECUTE AS statement is run.

  • Viene eseguita un'istruzione REVERT.A REVERT statement is run.

  • La sessione viene rimossa.The session is dropped.

  • La stored procedure o il trigger in cui è stato eseguito il comando è esistente.The stored procedure or trigger where the command was executed exits.

È possibile creare uno stack di contesti di esecuzione eseguendo più volte una chiamata all'istruzione EXECUTE AS in più entità.You can create an execution context stack by calling the EXECUTE AS statement multiple times across multiple principals. Quando viene chiamata, l'istruzione REVERT imposta il contesto sull'account di accesso o sull'utente nel successivo livello superiore nello stack di contesti.When called, the REVERT statement switches the context to the login or user in the next level up in the context stack. Per una dimostrazione di questo comportamento, vedere l'esempio A.For a demonstration of this behavior, see Example A.

Indicazione di un nome utente o di un ID di accessoSpecifying a User or Login Name

Il nome utente o l'ID di accesso specificato in EXECUTE AS <context_specification> deve esistere come entità rispettivamente in sys.database_principals o sys.server_principals. In caso contrario, l'istruzione EXECUTE AS ha esito negativo.The user or login name specified in EXECUTE AS <context_specification> must exist as a principal in sys.database_principals or sys.server_principals, respectively, or the EXECUTE AS statement fails. È inoltre necessario concedere le autorizzazioni IMPERSONATE per l'entità.Additionally, IMPERSONATE permissions must be granted on the principal. A meno che il chiamante non sia il proprietario del database o membro del ruolo predefinito del server sysadmin, l'entità deve esistere anche quando l'utente effettua l'accesso al database o all'istanza di SQL ServerSQL Server tramite l'appartenenza a un gruppo di Windows.Unless the caller is the database owner, or is a member of the sysadmin fixed server role, the principal must exist even when the user is accessing the database or instance of SQL ServerSQL Server through a Windows group membership. Si suppongano ad esempio le condizioni seguenti:For example, assume the following conditions:

  • Il gruppo CompanyDomain\SQLUsers ha accesso al database Sales.CompanyDomain\SQLUsers group has access to the Sales database.

  • CompanyDomain\SqlUser1 è membro del gruppo SQLUsers e pertanto può implicitamente accedere al database Sales.CompanyDomain\SqlUser1 is a member of SQLUsers and, therefore, has implicit access to the Sales database.

Anche se CompanyDomain\SqlUser1 può accedere al database in virtù dell'appartenenza al gruppo SQLUsers, l'istruzione EXECUTE AS USER = 'CompanyDomain\SqlUser1' ha esito negativo in quanto CompanyDomain\SqlUser1 non esiste come entità nel database.Although CompanyDomain\SqlUser1 has access to the database through membership in the SQLUsers group, the statement EXECUTE AS USER = 'CompanyDomain\SqlUser1' fails because CompanyDomain\SqlUser1 does not exist as a principal in the database.

Se l'utente è reso orfano, ovvero se l'accesso associato non esiste più, e non è stato creato con WITHOUT LOGIN, EXECUTE AS avrà esito negativo per tale utente.If the user is orphaned (the associated login no longer exists), and the user was not created with WITHOUT LOGIN, EXECUTE AS will fail for the user.

Procedura consigliataBest Practice

Specificare un account di accesso o un utente che disponga almeno dei privilegi necessari per eseguire operazioni nella sessione.Specify a login or user that has the least privileges required to perform the operations in the session. Ad esempio, non specificare un nome account di accesso con autorizzazioni a livello di server se sono richieste solo autorizzazioni a livello di database oppure non specificare l'account di un proprietario di database a meno che siano richieste le autorizzazioni corrispondenti.For example, do not specify a login name with server-level permissions, if only database-level permissions are required; or do not specify a database owner account unless those permissions are required.

Attenzione

L'istruzione EXECUTE AS può avere esito positivo, a condizione che il Motore di databaseDatabase Engine sia in grado di risolvere il nome.The EXECUTE AS statement can succeed as long as the Motore di databaseDatabase Engine can resolve the name. Se è presente un utente di dominio, è possibile che Windows sia in grado di risolvere l'utente per Motore di databaseDatabase Engine, anche se l'utente di Windows non dispone dell'accesso a SQL ServerSQL Server.If a domain user exists, Windows might be able to resolve the user for the Motore di databaseDatabase Engine, even though the Windows user does not have access to SQL ServerSQL Server. Ciò potrebbe creare una condizione in cui un account di accesso privo di autorizzazione di accesso a SQL ServerSQL Server risulti apparentemente connesso, sebbene l'account di accesso rappresentato disponga solo delle autorizzazioni concesse a public o guest.This can lead to a condition where a login with no access to SQL ServerSQL Server appears to be logged in, though the impersonated login would only have the permissions granted to public or guest.

Utilizzo di WITH NO REVERTUsing WITH NO REVERT

Se l'istruzione EXECUTE AS include la clausola facoltativa WITH NO REVERT, il contesto di esecuzione di una sessione non può essere ripristinato tramite REVERT oppure tramite l'esecuzione di un'altra istruzione EXECUTE AS.When the EXECUTE AS statement includes the optional WITH NO REVERT clause, the execution context of a session cannot be reset using REVERT or by executing another EXECUTE AS statement. Il contesto impostato dall'istruzione rimane valido fino all'eliminazione della sessione.The context set by the statement remains in affect until the session is dropped.

Quando la clausola WITH NO REVERT COOKIE = @varbinary_variable è specificata, il Motore di database di SQL ServerSQL Server Database Engine passa il valore del cookie a @varbinary_variable.When the WITH NO REVERT COOKIE = @varbinary_variable clause is specified, the Motore di database di SQL ServerSQL Server Database Engine passes the cookie value to @varbinary_variable. Il contesto di esecuzione impostato da tale istruzione può essere riportato al contesto precedente se l'istruzione REVERT WITH COOKIE = @varbinary_variable contiene lo stesso valore *@varbinary_variable*.The execution context set by that statement can only be reverted to the previous context if the calling REVERT WITH COOKIE = @varbinary_variable statement contains the same *@varbinary_variable* value.

Questa opzione risulta utile in un ambiente in cui vengono utilizzati i pool di connessioni.This option is useful in an environment in which connection pooling is used. Tramite i pool di connessioni vengono gestiti i gruppi di connessioni al database in modo che tali connessioni possano essere riutilizzate dalle applicazioni in un server applicazioni.Connection pooling is the maintenance of a group of database connections for reuse by applications on an application server. Poiché il valore passato a *@varbinary_variable* è noto solo al chiamante dell'istruzione EXECUTE AS, il chiamante è in grado di garantire che il contesto di esecuzione stabilito non venga modificato da altri.Because the value passed to *@varbinary_variable* is known only to the caller of the EXECUTE AS statement, the caller can guarantee that the execution context they establish cannot be changed by anyone else.

Determinazione dell'account di accesso originaleDetermining the Original Login

Usare la funzione ORIGINAL_LOGIN per restituire il nome dell'account di accesso connesso all'istanza di SQL ServerSQL Server.Use the ORIGINAL_LOGIN function to return the name of the login that connected to the instance of SQL ServerSQL Server. È possibile utilizzare questa funzione per restituire l'identità dell'account di accesso originale in sessioni in cui si verificano numerosi cambi di contesto espliciti o impliciti.You can use this function to return the identity of the original login in sessions in which there are many explicit or implicit context switches.

AutorizzazioniPermissions

Per specificare l'istruzione EXECUTE AS per un account di accesso, il chiamante deve disporre dell'autorizzazione IMPERSONATE per il nome dell'account di accesso specificato e non gli deve essere negata l'autorizzazione IMPERSONATE ANY LOGIN.To specify EXECUTE AS on a login, the caller must have IMPERSONATE permission on the specified login name and must not be denied the IMPERSONATE ANY LOGIN permission. Per specificare l'istruzione EXECUTE AS per un utente del database, il chiamante deve disporre delle autorizzazioni IMPERSONATE per il nome utente specificato.To specify EXECUTE AS on a database user, the caller must have IMPERSONATE permissions on the specified user name. Se si specifica EXECUTE AS CALLER, le autorizzazioni IMPERSONATE non sono obbligatorie.When EXECUTE AS CALLER is specified, IMPERSONATE permissions are not required.

EsempiExamples

A.A. Utilizzo di EXECUTE AS e REVERT per cambiare contestoUsing EXECUTE AS and REVERT to switch context

Nell'esempio seguente viene creato uno stack di contesti di esecuzione utilizzando più entità.The following example creates a context execution stack using multiple principals. Viene quindi utilizzata l'istruzione REVERT per ripristinare il contesto di esecuzione al chiamante precedente.The REVERT statement is then used to reset the execution context to the previous caller. L'istruzione REVERT viene eseguita più volte per innalzare di livello lo stack finché il contesto di esecuzione viene impostato sul chiamante originale.The REVERT statement is executed multiple times moving up the stack until the execution context is set to the original caller.

USE AdventureWorks2012;  
GO  
--Create two temporary principals  
CREATE LOGIN login1 WITH PASSWORD = 'J345#$)thb';  
CREATE LOGIN login2 WITH PASSWORD = 'Uor80$23b';  
GO  
CREATE USER user1 FOR LOGIN login1;  
CREATE USER user2 FOR LOGIN login2;  
GO  
--Give IMPERSONATE permissions on user2 to user1  
--so that user1 can successfully set the execution context to user2.  
GRANT IMPERSONATE ON USER:: user2 TO user1;  
GO  
--Display current execution context.  
SELECT SUSER_NAME(), USER_NAME();  
-- Set the execution context to login1.   
EXECUTE AS LOGIN = 'login1';  
--Verify the execution context is now login1.  
SELECT SUSER_NAME(), USER_NAME();  
--Login1 sets the execution context to login2.  
EXECUTE AS USER = 'user2';  
--Display current execution context.  
SELECT SUSER_NAME(), USER_NAME();  
-- The execution context stack now has three principals: the originating caller, login1 and login2.  
--The following REVERT statements will reset the execution context to the previous context.  
REVERT;  
--Display current execution context.  
SELECT SUSER_NAME(), USER_NAME();  
REVERT;  
--Display current execution context.  
SELECT SUSER_NAME(), USER_NAME();  
  
--Remove temporary principals.  
DROP LOGIN login1;  
DROP LOGIN login2;  
DROP USER user1;  
DROP USER user2;  
GO  

Nell'esempio seguente il contesto di esecuzione di una sessione viene impostato su un utente specifico e quindi viene specificata la clausola WITH NO REVERT COOKIE = @varbinary_variable.The following example sets the execution context of a session to a specified user and specifies the WITH NO REVERT COOKIE = @varbinary_variable clause. Nell'istruzione REVERT è necessario specificare il valore passato alla variabile @cookie nell'istruzione EXECUTE AS per ripristinare correttamente il contesto al chiamante originale.The REVERT statement must specify the value passed to the @cookie variable in the EXECUTE AS statement to successfully revert the context back to the caller. Per eseguire questo esempio, l'account di accesso login1 e l'utente user1 creato nell'esempio A devono esistere.To run this example, the login1 login and user1 user created in example A must exist.

DECLARE @cookie varbinary(8000);  
EXECUTE AS USER = 'user1' WITH COOKIE INTO @cookie;  
-- Store the cookie in a safe location in your application.  
-- Verify the context switch.  
SELECT SUSER_NAME(), USER_NAME();  
--Display the cookie value.  
SELECT @cookie;  
GO  
-- Use the cookie in the REVERT statement.  
DECLARE @cookie varbinary(8000);  
-- Set the cookie value to the one from the SELECT @cookie statement.  
SET @cookie = <value from the SELECT @cookie statement>;  
REVERT WITH COOKIE = @cookie;  
-- Verify the context switch reverted.  
SELECT SUSER_NAME(), USER_NAME();  
GO  

Vedere ancheSee Also

REVERT (Transact-SQL) REVERT (Transact-SQL)
EXECUTE AS Clause (Transact-SQL)EXECUTE AS Clause (Transact-SQL)