After some digging and using @TheGameiswar's answer, I came up with this solution
1- Create a read-only user
Create user user_reader without login
2- , user_reader
Create schema reader
ALTER AUTHORIZATION ON Schema::reader TO user_reader
3 - user_reader
GRANT SELECT TO user_reader
4- user_reader, . , , user_reader , .
GRANT EXECUTE ON Schema::reader TO user_reader
5 sql, user_reader. " user = 'user_reader"
public override DataTable ExecuteQuery(string query)
{
SqlConnection connection = new SqlConnection(ConnectionString);
StringBuilder readOnlyQuery = new StringBuilder();
readOnlyQuery .AppendLine("execute as user = 'user_reader';");
readOnlyQuery .AppendLine(query);
query = readOnlyQuery .ToString();
SqlCommand command = new SqlCommand(query, connection);
...Execute the command
}
CREATE TABLE [dbo].[TestTable](
[TestField] [int] NOT NULL
)
GO
CREATE PROCEDURE USP_INSERT
@input int
AS
BEGIN
INSERT INTO TestTable VALUES (@input)
END
GO
CREATE PROCEDURE reader.USP_READ
AS
BEGIN
SELECT * FROM TestTable
END
GO
CREATE PROCEDURE reader.USP_INSERT
@input int
AS
BEGIN
INSERT INTO TestTable VALUES (@input)
END
:
insert into TestTable VALUES (2)
INSERT "TestTable", 'Test', 'dbo'.
select * from TestTable
OK
exec usp_read
EXECUTE 'USP_READ', 'Test', 'dbo'.
exec usp_insert 1
EXECUTE 'USP_INSERT', 'Test', 'dbo'.
exec reader.usp_insert 1
INSERT "TestTable", 'Test', 'dbo'.
exec reader.usp_read
OK
select name
from sys.procedures
where SCHEMA_NAME(schema_id) = 'reader'
, , , .