Skip to content

Commit 6024a9c

Browse files
committed
adding RLS
1 parent c31fd95 commit 6024a9c

File tree

3 files changed

+255
-0
lines changed

3 files changed

+255
-0
lines changed
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
-- Demonstrate Row Level Security -- Window 2
2+
3+
4+
-- Right-click this query window and change connection
5+
-- Log on as SQL login Website with password SQLRocks!00
6+
7+
-- Ensure we are logged on as the website user
8+
9+
SELECT SUSER_SNAME();
10+
GO
11+
12+
-- Note that no customers are visible as yet
13+
SELECT * FROM Sales.Customers;
14+
GO
15+
16+
-- Set the session context (the website would set this on behalf of the user)
17+
EXEC sp_set_session_context N'SalesTerritory', N'Great Lakes', @read_only = 1;
18+
GO
19+
20+
-- Check the value that was set
21+
SELECT SESSION_CONTEXT(N'SalesTerritory');
22+
GO
23+
24+
-- Note that the user can now access the users based upon the sales territory in the session_context
25+
SELECT * FROM Sales.Customers;
26+
GO
27+
28+
USE tempdb;
29+
GO
30+
31+
-- Right-click this window and from the connection menu, disconnect
32+
33+
-- Switch back to the main window to tidy up
Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
-- Demonstrate Row Level Security
2+
3+
4+
USE master;
5+
GO
6+
7+
IF NOT EXISTS (SELECT 1 FROM sys.server_principals WHERE name = N'GreatLakesUser')
8+
BEGIN
9+
CREATE LOGIN GreatLakesUser
10+
WITH PASSWORD = N'SQLRocks!00',
11+
CHECK_POLICY = OFF,
12+
CHECK_EXPIRATION = OFF,
13+
DEFAULT_DATABASE = WideWorldImporters;
14+
END;
15+
GO
16+
17+
IF NOT EXISTS (SELECT 1 FROM sys.server_principals WHERE name = N'Website')
18+
BEGIN
19+
CREATE LOGIN Website
20+
WITH PASSWORD = N'SQLRocks!00',
21+
CHECK_POLICY = OFF,
22+
CHECK_EXPIRATION = OFF,
23+
DEFAULT_DATABASE = WideWorldImporters;
24+
END;
25+
GO
26+
27+
USE WideWorldImporters;
28+
GO
29+
30+
CREATE USER GreatLakesUser FOR LOGIN GreatLakesUser;
31+
GO
32+
33+
CREATE USER Website FOR LOGIN Website;
34+
GO
35+
36+
ALTER ROLE [Great Lakes Sales] ADD MEMBER GreatLakesUser;
37+
GO
38+
39+
-- Ensure that the policy has been applied
40+
EXEC [Application].Configuration_ApplyRowLevelSecurity;
41+
GO
42+
43+
-- The function that has been applied is as follows:
44+
--
45+
-- CREATE FUNCTION [Application].DetermineCustomerAccess(@CityID int)
46+
-- RETURNS TABLE
47+
-- WITH SCHEMABINDING
48+
-- AS
49+
-- RETURN (SELECT 1 AS AccessResult
50+
-- WHERE IS_ROLEMEMBER(N'db_owner') <> 0
51+
-- OR IS_ROLEMEMBER((SELECT sp.SalesTerritory
52+
-- FROM [Application].Cities AS c
53+
-- INNER JOIN [Application].StateProvinces AS sp
54+
-- ON c.StateProvinceID = sp.StateProvinceID
55+
-- WHERE c.CityID = @CityID) + N' Sales') <> 0
56+
-- OR (ORIGINAL_LOGIN() = N'Website'
57+
-- AND EXISTS (SELECT 1
58+
-- FROM [Application].Cities AS c
59+
-- INNER JOIN [Application].StateProvinces AS sp
60+
-- ON c.StateProvinceID = sp.StateProvinceID
61+
-- WHERE c.CityID = @CityID
62+
-- AND sp.SalesTerritory = SESSION_CONTEXT(N'SalesTerritory'))));
63+
-- GO
64+
65+
-- The security policy that has been applied is as follows:
66+
--
67+
-- CREATE SECURITY POLICY [Application].FilterCustomersBySalesTerritoryRole
68+
-- ADD FILTER PREDICATE [Application].DetermineCustomerAccess(DeliveryCityID)
69+
-- ON Sales.Customers,
70+
-- ADD BLOCK PREDICATE [Application].DetermineCustomerAccess(DeliveryCityID)
71+
-- ON Sales.Customers AFTER UPDATE;
72+
-- GO
73+
74+
SELECT * FROM sys.database_principals; -- not the role for Great Lakes and the user for Great Lakes
75+
GO
76+
77+
SELECT * FROM Sales.Customers; -- and note count
78+
GO
79+
80+
GRANT SELECT, UPDATE ON Sales.Customers TO [Great Lakes Sales];
81+
GRANT SELECT ON [Application].Cities TO [Great Lakes Sales];
82+
GRANT SELECT ON [Application].Countries TO [Great Lakes Sales];
83+
GO
84+
85+
EXECUTE AS USER = 'GreatLakesUser';
86+
GO
87+
88+
-- Now note the count and which rows are returned
89+
-- even though we have not changed the command
90+
91+
SELECT * FROM Sales.Customers;
92+
GO
93+
94+
-- where are those customers?
95+
-- note the spatial results tab
96+
97+
SELECT c.Border
98+
FROM [Application].Countries AS c
99+
WHERE c.CountryName = N'United States'
100+
UNION ALL
101+
SELECT c.DeliveryLocation
102+
FROM Sales.Customers AS c;
103+
GO
104+
105+
-- updating rows that are accessible to a non-accessible row is blocked
106+
107+
UPDATE Sales.Customers -- Attempt to update
108+
SET DeliveryCityID = 3 -- to a city that is not in the Great Lakes Sales Territory
109+
WHERE DeliveryCityID = 32887; -- for a customer that is in the Great Lakes Sales Territory
110+
111+
REVERT;
112+
GO
113+
114+
-- Remove the user from the role
115+
ALTER ROLE [Great Lakes Sales] DROP MEMBER GreatLakesUser;
116+
GO
117+
118+
-- Instead of permission for a role, let's give permissions to the website user
119+
GRANT SELECT, UPDATE ON Sales.Customers TO [Website];
120+
GRANT SELECT ON [Application].Cities TO [Website];
121+
GRANT SELECT ON [Application].Countries TO [Website];
122+
GO
123+
124+
-- Open the second RLS demo window and follow the instructions there
125+
126+
-- Finally, tidy up (optional)
127+
128+
REVOKE SELECT, UPDATE ON Sales.Customers FROM [Great Lakes Sales];
129+
REVOKE SELECT ON [Application].Cities FROM [Great Lakes Sales];
130+
REVOKE SELECT ON [Application].Countries FROM [Great Lakes Sales];
131+
REVOKE SELECT, UPDATE ON Sales.Customers FROM [Website];
132+
REVOKE SELECT ON [Application].Cities FROM [Website];
133+
REVOKE SELECT ON [Application].Countries FROM [Website];
134+
GO
135+
136+
EXEC [Application].Configuration_RemoveRowLevelSecurity;
137+
GO
138+
139+
DROP USER GreatLakesUser;
140+
GO
141+
142+
DROP USER Website;
143+
GO
144+
145+
USE master;
146+
GO
147+
148+
DROP LOGIN GreatLakesUser;
149+
GO
150+
151+
DROP LOGIN Website;
152+
GO
153+
154+
USE tempdb;
155+
GO
156+
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
# Sample for use of Row-Level Security in WideWorldImporters
2+
3+
This script demonstrates the use of Row-Level Security to restrict access to certains rows in the table to certain users.
4+
5+
6+
### Contents
7+
8+
[About this sample](#about-this-sample)<br/>
9+
[Before you begin](#before-you-begin)<br/>
10+
[Running the sample](#run-this-sample)<br/>
11+
[Sample details](#sample-details)<br/>
12+
[Disclaimers](#disclaimers)<br/>
13+
[Related links](#related-links)<br/>
14+
15+
16+
<a name=about-this-sample></a>
17+
18+
## About this sample
19+
20+
<!-- Delete the ones that don't apply -->
21+
1. **Applies to:** SQL Server 2016 (or higher), Azure SQL Database
22+
1. **Key features:** Row-Level Security
23+
1. **Workload:** OLTP
24+
1. **Programming Language:** T-SQL
25+
1. **Authors:** Greg Low, Jos de Bruijn
26+
1. **Update history:** 26 May 2016 - initial revision
27+
28+
<a name=before-you-begin></a>
29+
30+
## Before you begin
31+
32+
To run this sample, you need the following prerequisites.
33+
34+
**Software prerequisites:**
35+
36+
<!-- Examples -->
37+
1. SQL Server 2016 (or higher) or Azure SQL Database.
38+
- With SQL Server, make sure SQL authentication is enabled.
39+
2. SQL Server Management Studio
40+
3. The WideWorldImporters database.
41+
42+
<a name=run-this-sample></a>
43+
44+
## Running the sample
45+
46+
1. Open both scripts in different windows or tabs in Management Studio.
47+
48+
2. Follow the instructions in the main script DemonstrateRLS.sql.
49+
50+
## Sample details
51+
52+
The sample adds a new table with sensitive data about suppliers. This sensitive data is always encrypted.
53+
54+
As part of the sample you create an encryption key that is saved locally (where you run SSMS). The client application inserts data into the table. With the sample scripts you will see how the data is encrypted in the table and cannot be viewed, even by a sysadmin, unless you have the encryption key.
55+
56+
<a name=disclaimers></a>
57+
58+
## Disclaimers
59+
The code included in this sample is not intended to be used for production purposes.
60+
61+
<a name=related-links></a>
62+
63+
## Related Links
64+
<!-- Links to more articles. Remember to delete "en-us" from the link path. -->
65+
TBD
66+

0 commit comments

Comments
 (0)