1. 程式人生 > >SQLServer之建立LOGON觸發器

SQLServer之建立LOGON觸發器

LOGON觸發器工作原理

登入觸發器將為響應 LOGON 事件而激發儲存過程。 與 SQL Server例項建立使用者會話時將引發此事件。 登入觸發器將在登入的身份驗證階段完成之後且使用者會話實際建立之前激發。 因此,來自觸發器內部且通常將到達使用者的所有訊息(例如錯誤訊息和來自 PRINT 語句的訊息)會傳送到 SQL Server 錯誤日誌。 如果身份驗證失敗,將不激發登入觸發器。

LOGON觸發器建立

語法:

--登入觸發器在伺服器物件-》觸發器中檢視

--宣告資料庫引用
use 資料庫名;
go

--判斷是否存在登入觸發器,如果存在則刪除


if exists(select * from sys.server_triggers where name=觸發器名)
drop trigger 觸發器名 on all server;
go

--建立觸發器
create

--觸發器識別符號
trigger

--觸發器名稱
觸發器名

on

--適用範圍: SQL Server 2008 到 SQL Server 2017。
--將 DDL 或登入觸發器的作用域應用於當前伺服器。 如果指定了此引數,則只要當前伺服器中的任何位置出現 event_type 或 event_group,就會激發該觸發器。
all server

with

--適用範圍: SQL Server 2008 到 SQL Server 2017。


--對 CREATE TRIGGER 語句的文字進行模糊處理。 使用 WITH ENCRYPTION 可以防止將觸發器作為 SQL Server 複製的一部分進行釋出。 不能為 CLR 觸發器指定 WITH ENCRYPTION。
encryption,

--EXECUTE AS Clause
--{ EXEC | EXECUTE } AS { SELF | OWNER | 'user_name' }
--CALLER
--指定模組內的語句在模組呼叫方的上下文中執行。 執行模組的使用者不僅必須對模組本身擁有適當的許可權,還要對模組引用的任何資料庫物件擁有適當許可權。
--CALLER 是除佇列外的所有模組的預設值,與 SQL Server 2005 行為相同。


--CALLER 不能在 CREATE QUEUE 或 ALTER QUEUE 語句中指定。
--SELF
--EXECUTE AS SELF 與 EXECUTE AS user_name 等價,其中指定使用者是建立或更改模組的使用者。 建立或更改模組的使用者的實際使用者 ID 儲存在 sys.sql_modules 或 sys.service_queues 目錄檢視的 execute_as_principal_id 列中。
--SELF 是佇列的預設值。
--OWNER
--指定模組內的語句在模組的當前所有者上下文中執行。 如果模組沒有指定的所有者,則使用模組架構的所有者。 不能為 DDL 或登入觸發器指定 OWNER。
--' user_name '
--指定模組內的語句在 user_name 指定的使用者的上下文中執行。 將根據 user_name 來驗證對模組內任意物件的許可權。 不能為具有伺服器作用域的 DDL 觸發器或登入觸發器指定 user_name。 請改用 login_name。
--user_name 必須存在於當前資料庫中,並且必須是單一例項帳戶。 user_name 不能為組、角色、證書、金鑰或內建帳戶,如 NT AUTHORITY\LocalService、NT AUTHORITY\NetworkService 或 NT AUTHORITY\LocalSystem。
--執行上下文的使用者 ID 儲存在元資料中,可以在 sys.sql_modules 或 sys.assembly_modules 目錄檢視的 execute_as_principal_id 列檢視。
execute as 'EIFM\tangxiaogang'

--FOR | AFTER
--AFTER 指定 DML 觸發器僅在觸發 SQL 語句中指定的所有操作都已成功執行時才被觸發。 所有的引用級聯操作和約束檢查也必須在激發此觸發器之前成功完成。
--如果僅指定 FOR 關鍵字,則 AFTER 為預設值。
--不能對檢視定義 AFTER 觸發器。
{ for | after }

--登入觸發器識別符號
logon


as
begin
sql_statement;
end

示例:本示例演示伺服器只允許登入三個人,超過第三個人不允許登入。

--登入觸發器在伺服器物件-》觸發器中檢視

--宣告資料庫引用
use testss;
go

--判斷是否存在登入觸發器,如果存在則刪除
if exists(select * from sys.server_triggers where name='logintri')
drop trigger logintri on all server;
go

--建立觸發器
create

--觸發器識別符號
trigger

--觸發器名稱
logintri

on

--適用範圍: SQL Server 2008 到 SQL Server 2017。
--將 DDL 或登入觸發器的作用域應用於當前伺服器。 如果指定了此引數,則只要當前伺服器中的任何位置出現 event_type 或 event_group,就會激發該觸發器。
all server

with

--適用範圍: SQL Server 2008 到 SQL Server 2017。
--對 CREATE TRIGGER 語句的文字進行模糊處理。 使用 WITH ENCRYPTION 可以防止將觸發器作為 SQL Server 複製的一部分進行釋出。 不能為 CLR 觸發器指定 WITH ENCRYPTION。
encryption,

--EXECUTE AS Clause
--{ EXEC | EXECUTE } AS { SELF | OWNER | 'user_name' }
--CALLER
--指定模組內的語句在模組呼叫方的上下文中執行。 執行模組的使用者不僅必須對模組本身擁有適當的許可權,還要對模組引用的任何資料庫物件擁有適當許可權。
--CALLER 是除佇列外的所有模組的預設值,與 SQL Server 2005 行為相同。
--CALLER 不能在 CREATE QUEUE 或 ALTER QUEUE 語句中指定。
--SELF
--EXECUTE AS SELF 與 EXECUTE AS user_name 等價,其中指定使用者是建立或更改模組的使用者。 建立或更改模組的使用者的實際使用者 ID 儲存在 sys.sql_modules 或 sys.service_queues 目錄檢視的 execute_as_principal_id 列中。
--SELF 是佇列的預設值。
--OWNER
--指定模組內的語句在模組的當前所有者上下文中執行。 如果模組沒有指定的所有者,則使用模組架構的所有者。 不能為 DDL 或登入觸發器指定 OWNER。
--' user_name '
--指定模組內的語句在 user_name 指定的使用者的上下文中執行。 將根據 user_name 來驗證對模組內任意物件的許可權。 不能為具有伺服器作用域的 DDL 觸發器或登入觸發器指定 user_name。 請改用 login_name。
--user_name 必須存在於當前資料庫中,並且必須是單一例項帳戶。 user_name 不能為組、角色、證書、金鑰或內建帳戶,如 NT AUTHORITY\LocalService、NT AUTHORITY\NetworkService 或 NT AUTHORITY\LocalSystem。
--執行上下文的使用者 ID 儲存在元資料中,可以在 sys.sql_modules 或 sys.assembly_modules 目錄檢視的 execute_as_principal_id 列檢視。
execute as 登入名

--FOR | AFTER
--AFTER 指定 DML 觸發器僅在觸發 SQL 語句中指定的所有操作都已成功執行時才被觸發。 所有的引用級聯操作和約束檢查也必須在激發此觸發器之前成功完成。
--如果僅指定 FOR 關鍵字,則 AFTER 為預設值。
--不能對檢視定義 AFTER 觸發器。
for

--登入觸發器識別符號
logon
as
begin
if (select count(1) from sys.dm_exec_sessions where is_user_process=1 and original_login_name=登入名) >3 and original_login()=登入名
begin
rollback;
end
end

示例結果:

LOGON登入觸發器優缺點

優點:

1、可以使用登入觸發器來稽核和控制伺服器會話。

2、通過跟蹤登入活動、限制 SQL Server的登入名或限制特定登入名的會話數。

3、防止資料庫賬號密碼洩露或者不合法的IP登入。

缺點:

1、登入可能引起不必要的觸發邏輯。

3、登入觸發器建立的會話是例項級別,並且應用於所有伺服器,可能會對新建資料庫和會話產生不必要的影響。