Tôi rất vui vì bạn đã giải quyết vấn đề này, nhưng chuỗi sở hữu không phải là giải pháp được đề xuất. Vì bạn có vẻ quan tâm một cách hợp lệ về bảo mật và mức độ chi tiết phù hợp của các quyền liên quan, nên tôi thêm câu trả lời này, mặc dù muộn, như một tài liệu tham khảo về những gì đang xảy ra và cách giải quyết vấn đề này.
EXECUTE NHƯ phạm vi mạo danh
Các mệnh đề EXECUTE AS có hai loại: EXECUTE AS LOGIN và EXECUTE AS USER. EXECUTE AS LOGIN được xác thực bởi máy chủ và là bối cảnh mạo danh được tin cậy bởi toàn bộ phiên bản SQL (phạm vi máy chủ):
Khi mạo danh hiệu trưởng bằng cách sử dụng câu lệnh EXECUTE AS LOGIN hoặc trong mô-đun phạm vi máy chủ bằng cách sử dụng mệnh đề EXECUTE AS, phạm vi của mạo danh là toàn máy chủ. Điều này có nghĩa là sau khi chuyển đổi ngữ cảnh, bất kỳ tài nguyên nào trong máy chủ đăng nhập được mạo danh đều có quyền truy cập.
EXECUTE AS USER được xác thực bởi cơ sở dữ liệu và là bối cảnh mạo danh chỉ được cơ sở dữ liệu đó tin cậy (phạm vi cơ sở dữ liệu):
Tuy nhiên, khi mạo danh hiệu trưởng bằng cách sử dụng câu lệnh EXECUTE AS USER hoặc trong mô-đun phạm vi cơ sở dữ liệu bằng cách sử dụng mệnh đề EXECUTE AS, phạm vi mạo danh được giới hạn trong cơ sở dữ liệu theo mặc định. Điều này có nghĩa là các tham chiếu đến các đối tượng nằm ngoài phạm vi của cơ sở dữ liệu sẽ trả về lỗi.
Một thủ tục được lưu trữ có mệnh đề EXECUTE AS sẽ tạo ra một bối cảnh mạo danh phạm vi cơ sở dữ liệu và do đó sẽ không thể tham chiếu các đối tượng bên ngoài cơ sở dữ liệu, trong trường hợp bạn sẽ không thể tham chiếu msdb.dbo.sp_start_job
vì trong đó msdb
. Có nhiều ví dụ khác có sẵn, như cố gắng truy cập DMV phạm vi máy chủ, cố gắng sử dụng máy chủ được liên kết hoặc cố gắng gửi thông điệp Nhà môi giới dịch vụ vào cơ sở dữ liệu khác.
Việc cho phép một cơ sở dữ liệu phạm vi mạo danh để truy cập vào một tài nguyên thường không được phép xác thực của bối cảnh mạo danh phải được tin cậy. Đối với một cơ sở dữ liệu phạm vi mạo danh, trình xác thực là cơ sở dữ liệu dbo. Điều này có thể đạt được bằng hai phương tiện có thể:
- Bằng cách bật thuộc tính TRUSTWORTHY trên cơ sở dữ liệu đã xác thực bối cảnh mạo danh (ví dụ: cơ sở dữ liệu có mệnh đề EXECUTE AS được ban hành).
- Bằng cách sử dụng chữ ký mã.
Các chi tiết này được mô tả trong MSDN: Mở rộng mạo danh cơ sở dữ liệu bằng cách sử dụng EXECUTE AS .
Khi bạn giải quyết vấn đề thông qua chuỗi sở hữu cơ sở dữ liệu chéo, bạn đã kích hoạt chuỗi liên kết chéo ở toàn bộ cấp độ máy chủ, được coi là rủi ro bảo mật. Cách kiểm soát tốt nhất, chi tiết hơn để đạt được kết quả mong muốn là sử dụng ký mã:
- Trong cơ sở dữ liệu ứng dụng tạo chứng chỉ tự ký
- ký tên
dbo.StartAgentJob
với chứng chỉ này
- đánh rơi khóa riêng của chứng chỉ
- xuất chứng chỉ ra đĩa
- nhập chứng chỉ vào
msdb
- tạo người dùng xuất phát từ chứng chỉ đã nhập trong
msdb
- cấp quyền AUTHENTICATE cho người dùng dẫn xuất trong
msdb
Các bước này đảm bảo rằng bối cảnh EXECUTE AS của dbo.StartAgentJob
thủ tục hiện được tin cậy msdb
, bởi vì bối cảnh được ký bởi một hiệu trưởng có sự cho phép AUTHENTICATE msdb
. Điều này giải quyết một nửa câu đố. Nửa còn lại là thực sự cấp quyền EXECUTE cho msdb.dbo.sp_start_job
bối cảnh mạo danh đáng tin cậy hiện nay. Có một số cách có thể được thực hiện:
- ánh xạ người dùng mạo nhận
agentProxy
người dùng trong msdb
và cấp cho ông thực thi điều khoản trênmsdb.dbo.sp_start_job
- cấp quyền thực thi cho
msdb
người dùng chứng chỉ dẫn xuất
- thêm chữ ký mới vào thủ tục, tạo ra một người dùng cho nó
msdb
và cấp quyền thực thi cho người dùng dẫn xuất này
Tùy chọn 1. đơn giản, nhưng có một nhược điểm lớn: agentProxy
người dùng hiện có thể thực hiện msdb.dbo.sp_start_job
theo ý mình, anh ta thực sự được cấp quyền truy cập msdb
và có quyền thực thi.
Lựa chọn 3 là đúng đắn, nhưng tôi cảm thấy không cần thiết quá mức.
Vì vậy, ưu tiên của tôi là Tùy chọn 2: cấp quyền EXECUTE cho msdb.dbo.sp_start_job
người dùng xuất phát chứng chỉ được tạo trong msdb
.
Đây là SQL tương ứng:
use [<appdb>];
go
create certificate agentProxy
ENCRYPTION BY PASSWORD = 'pGFD4bb925DGvbd2439587y'
with subject = 'agentProxy'
, start_date='01/01/2009';
go
ADD SIGNATURE TO OBJECT::[StartAgentJob]
BY CERTIFICATE [agentProxy]
WITH PASSWORD = 'pGFD4bb925DGvbd2439587y';
go
alter certificate [agentProxy]
remove private key;
go
backup certificate [agentProxy]
to file='c:\temp\agentProxy.cer';
go
use msdb
go
create certificate [agentProxy]
from file='c:\temp\agentProxy.cer';
go
create user [agentProxyAuthenticator]
from certificate [agentProxy];
go
grant authenticate to [agentProxyAuthenticator];
grant execute on msdb.dbo.sp_start_job to [agentProxyAuthenticator];
go
use [<appdb>];
go
exec dbo.StartAgentJob;
go
Blog của tôi có một số bài viết về chủ đề này, được viết trong bối cảnh các quy trình được kích hoạt của Nhà môi giới dịch vụ (vì chúng yêu cầu một điều khoản EXECUTE AS):
BTW, nếu bạn đang cố kiểm tra kịch bản của tôi và bạn sống ở bán cầu đông hoặc vào mùa hè ở Vương quốc Anh, chắc chắn đọc bài viết cuối cùng mà tôi đã liên kết trước khi thử nghiệm.