Ограничить разрешения на выполнение хранимой процедуры - PullRequest
0 голосов
/ 27 апреля 2018

Вот контекст.

  • две базы данных, база данных1 и база данных2.
  • веб-приложение asp.net, которое обращается к базе данных1, используя пользователя user1 (аутентификация SQL Server).
  • хранимая процедура sp1 в базе данных1, которая должна изменить некоторые конфиденциальные данные в базе данных2 с помощью хранимой процедуры sp2, определенной в базе данных2. Другими словами, sp1 вызывает базу данных 2...sp2.
  • Я создал логин SQL2 user2, который сопоставлен с user2 в database1 и user2 database2. user2 в базе данных2 имеет разрешение на выполнение sp2.

Я хочу, чтобы user1 мог изменять базу данных2 только через sp1. Я не хочу, чтобы user1 мог запускать: exec database2..sp2.

Вот код, который я попробовал:

USE [database2];
GO

SET  ANSI_NULLS ON;
GO
SET  QUOTED_IDENTIFIER ON;
GO

CREATE PROCEDURE [dbo].[sp2]
  WITH
  EXEC AS CALLER AS
SELECT current_user
GO
GRANT EXECUTE ON [dbo].[sp2] TO [user2]
GO

В базе данных 1 я запустил:

use database1
go      

drop procedure sp1
go

create procedure sp1 
as 

declare @m nvarchar(4000)

select current_user as usr

execute as login='user2'
begin try
execute database2.dbo.sp2 
end try
begin catch
  set @m = error_message()
  print @m
  revert
end catch

go

grant execute on dbo.sp1 to user1
go

execute as login='user1'
go

execute dbo.sp1

go
revert
go      

К сожалению, это (то есть exec dbo.sp1 в контексте login = 'user1') не работает, оно возвращает:

Невозможно выполнить роль участника-сервера, так как принципал user2 не существует, принципал этого типа не может быть олицетворен или у вас нет разрешения

Я также пытался скомпилировать sp1 с with execute as 'user2', однако, это не работает.

Есть ли другой способ сделать эту работу?

Спасибо

Обновление:

Если я запускаю это:

GRANT IMPERSONATE ON User::user2 to [User1];  
GO

тогда скрипт работает, но это означает, что пользователь1 теперь может выполнять Database2..sp2.

То, что я хочу в некотором смысле, выглядит примерно так: grant impersonate on User::user2 to [sp1], т.е. я даю разрешение на олицетворение для процедуры, но я не уверен, что это возможно.

Я нашел эту ветку , которая, я думаю, относится и к моему делу.

1 Ответ

0 голосов
/ 27 апреля 2018

хорошо, основываясь на потоке Я упоминал, что это возможно.

Вот сценарии для достижения этой цели:

use database1
go

CREATE CERTIFICATE [PermissionsCert]
AUTHORIZATION [dbo]
ENCRYPTION BY PASSWORD = 'WeakPassword'
WITH SUBJECT = 'Used to test granting permissions to code',
EXPIRY_DATE = '2099-12-31';

ADD SIGNATURE TO [dbo].[sp1]
  BY CERTIFICATE [PermissionsCert]
  WITH PASSWORD = 'WeakPassword';

BACKUP CERTIFICATE [PermissionsCert] TO FILE = 'k:\Sql_Backup\PermissionsCert.cer' 

use database2
go

CREATE CERTIFICATE PermissionsCert       
FROM FILE = 'k:\Sql_Backup\PermissionsCert.cer'  


CREATE USER [PermissionsUser] FROM CERTIFICATE [PermissionsCert];

grant execute on dbo.sp2 to [PermissionsUser]
go

Я изменил sp1 следующим образом:

alter procedure sp1 
as 
declare @m nvarchar(4000)

select current_user as usr

--execute as user='user2'
begin try
execute Database2.dbo.sp2 
end try
begin catch
  set @m = error_message()
  print @m
  revert
end catch

go

Это работает сейчас:

execute as login='user1'
go

execute dbo.sp1

go
revert
go

Однако, это терпит неудачу, чего я и хочу:

execute as login='user1'
go

execute database2.dbo.sp2

go
revert
go
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...