Reputation: 6686
I need to define a table which basically will contain an Id for a user, and a second column which will list names of tables to which the user has access. I can't think of anyway to define any relationships here in case the original table names change. All the logic will be at the application level. However, I would like to be able to define some sort of constraints. How can I do this? Also, I am open to advice regarding any other way to do this.
Upvotes: 0
Views: 60
Reputation: 1147
Since users are NOT SQL Server Logins, therefore, I guess you can use the DDL trigger to monitor table rename where you can change the table name in your custom security table. But I don't know if you can throw exception within this trigger to prevent table rename (simulating some type of constraint). Also it would be better if you store the table name in each line rather saving comma separated table names in 1 field.
If you can utilize SQL Logins then the Gordan's solution is also applicable, but sometimes you cannot create SQL Logins, in-case if you have different application databases along with hundreds of thousands of users.
Upvotes: 0
Reputation: 1586
Here's a detailed code example of how to achieve this using RLS
USE tempdb;
GO
CREATE TABLE dbo.OKTable
(
OKTableID int IDENTITY(1,1) NOT NULL
CONSTRAINT PK_dbo_OKTable PRIMARY KEY,
SecuredInfo varchar(100)
);
GO
INSERT dbo.OKTable (SecuredInfo)
VALUES ('Very'), ('Secret'), ('Stuff');
GO
CREATE TABLE dbo.NotOKTable
(
NotOKTableID int IDENTITY(1,1) NOT NULL
CONSTRAINT PK_dbo_NotOKTable PRIMARY KEY,
SecuredInfo varchar(100)
);
GO
INSERT dbo.NotOKTable (SecuredInfo)
VALUES ('Other'), ('Important'), ('Things');
GO
CREATE SCHEMA [Security] AUTHORIZATION dbo;
GO
CREATE TABLE [Security].PermittedTableUsers
(
PermittedTableUsers int IDENTITY(1,1) NOT NULL
CONSTRAINT PK_Security_PermittedTableUsers
PRIMARY KEY,
UserName sysname,
SchemaName sysname,
TableName sysname
);
GO
INSERT [Security].PermittedTableUsers (UserName, SchemaName, TableName)
VALUES (N'dbo', N'dbo', 'OKTable');
GO
ALTER FUNCTION [Security].CheckUserAccess
(
@SchemaName AS sysname,
@TableName AS sysname
)
RETURNS TABLE
WITH SCHEMABINDING
AS
RETURN SELECT 1 AS CheckUserAccessOutcome
WHERE EXISTS (SELECT 1 FROM [Security].PermittedTableUsers AS ptu
WHERE ptu.UserName = USER_NAME()
AND ptu.SchemaName = @SchemaName
AND ptu.TableName = @TableName);
GO
CREATE SECURITY POLICY OKTableAccessFilter
ADD FILTER PREDICATE [Security].CheckUserAccess (N'dbo', N'OKTable')
ON dbo.OKTable
WITH (STATE = ON);
GO
CREATE SECURITY POLICY NotOKTableAccessFilter
ADD FILTER PREDICATE [Security].CheckUserAccess (N'dbo', N'NotOKTable')
ON dbo.NotOKTable
WITH (STATE = ON);
GO
SELECT * FROM dbo.OKTable;
SELECT * FROM dbo.NotOKTable;
GO
It's described more fully in this link:
Upvotes: 0
Reputation: 1270493
I am really confused. Doesn't the grant
command do exactly what you want? This assumes that the operations you want are database operations.
If you have a more customized set of operations, then you can keep track of table name changes via DDL triggers.
Upvotes: 1