mirror of
https://github.com/Microsoft/sql-server-samples.git
synced 2025-12-08 14:58:54 +00:00
adding RLS
This commit is contained in:
+33
@@ -0,0 +1,33 @@
|
||||
-- Demonstrate Row Level Security -- Window 2
|
||||
|
||||
|
||||
-- Right-click this query window and change connection
|
||||
-- Log on as SQL login Website with password SQLRocks!00
|
||||
|
||||
-- Ensure we are logged on as the website user
|
||||
|
||||
SELECT SUSER_SNAME();
|
||||
GO
|
||||
|
||||
-- Note that no customers are visible as yet
|
||||
SELECT * FROM Sales.Customers;
|
||||
GO
|
||||
|
||||
-- Set the session context (the website would set this on behalf of the user)
|
||||
EXEC sp_set_session_context N'SalesTerritory', N'Great Lakes', @read_only = 1;
|
||||
GO
|
||||
|
||||
-- Check the value that was set
|
||||
SELECT SESSION_CONTEXT(N'SalesTerritory');
|
||||
GO
|
||||
|
||||
-- Note that the user can now access the users based upon the sales territory in the session_context
|
||||
SELECT * FROM Sales.Customers;
|
||||
GO
|
||||
|
||||
USE tempdb;
|
||||
GO
|
||||
|
||||
-- Right-click this window and from the connection menu, disconnect
|
||||
|
||||
-- Switch back to the main window to tidy up
|
||||
+156
@@ -0,0 +1,156 @@
|
||||
-- Demonstrate Row Level Security
|
||||
|
||||
|
||||
USE master;
|
||||
GO
|
||||
|
||||
IF NOT EXISTS (SELECT 1 FROM sys.server_principals WHERE name = N'GreatLakesUser')
|
||||
BEGIN
|
||||
CREATE LOGIN GreatLakesUser
|
||||
WITH PASSWORD = N'SQLRocks!00',
|
||||
CHECK_POLICY = OFF,
|
||||
CHECK_EXPIRATION = OFF,
|
||||
DEFAULT_DATABASE = WideWorldImporters;
|
||||
END;
|
||||
GO
|
||||
|
||||
IF NOT EXISTS (SELECT 1 FROM sys.server_principals WHERE name = N'Website')
|
||||
BEGIN
|
||||
CREATE LOGIN Website
|
||||
WITH PASSWORD = N'SQLRocks!00',
|
||||
CHECK_POLICY = OFF,
|
||||
CHECK_EXPIRATION = OFF,
|
||||
DEFAULT_DATABASE = WideWorldImporters;
|
||||
END;
|
||||
GO
|
||||
|
||||
USE WideWorldImporters;
|
||||
GO
|
||||
|
||||
CREATE USER GreatLakesUser FOR LOGIN GreatLakesUser;
|
||||
GO
|
||||
|
||||
CREATE USER Website FOR LOGIN Website;
|
||||
GO
|
||||
|
||||
ALTER ROLE [Great Lakes Sales] ADD MEMBER GreatLakesUser;
|
||||
GO
|
||||
|
||||
-- Ensure that the policy has been applied
|
||||
EXEC [Application].Configuration_ApplyRowLevelSecurity;
|
||||
GO
|
||||
|
||||
-- The function that has been applied is as follows:
|
||||
--
|
||||
-- CREATE FUNCTION [Application].DetermineCustomerAccess(@CityID int)
|
||||
-- RETURNS TABLE
|
||||
-- WITH SCHEMABINDING
|
||||
-- AS
|
||||
-- RETURN (SELECT 1 AS AccessResult
|
||||
-- WHERE IS_ROLEMEMBER(N'db_owner') <> 0
|
||||
-- OR IS_ROLEMEMBER((SELECT sp.SalesTerritory
|
||||
-- FROM [Application].Cities AS c
|
||||
-- INNER JOIN [Application].StateProvinces AS sp
|
||||
-- ON c.StateProvinceID = sp.StateProvinceID
|
||||
-- WHERE c.CityID = @CityID) + N' Sales') <> 0
|
||||
-- OR (ORIGINAL_LOGIN() = N'Website'
|
||||
-- AND EXISTS (SELECT 1
|
||||
-- FROM [Application].Cities AS c
|
||||
-- INNER JOIN [Application].StateProvinces AS sp
|
||||
-- ON c.StateProvinceID = sp.StateProvinceID
|
||||
-- WHERE c.CityID = @CityID
|
||||
-- AND sp.SalesTerritory = SESSION_CONTEXT(N'SalesTerritory'))));
|
||||
-- GO
|
||||
|
||||
-- The security policy that has been applied is as follows:
|
||||
--
|
||||
-- CREATE SECURITY POLICY [Application].FilterCustomersBySalesTerritoryRole
|
||||
-- ADD FILTER PREDICATE [Application].DetermineCustomerAccess(DeliveryCityID)
|
||||
-- ON Sales.Customers,
|
||||
-- ADD BLOCK PREDICATE [Application].DetermineCustomerAccess(DeliveryCityID)
|
||||
-- ON Sales.Customers AFTER UPDATE;
|
||||
-- GO
|
||||
|
||||
SELECT * FROM sys.database_principals; -- not the role for Great Lakes and the user for Great Lakes
|
||||
GO
|
||||
|
||||
SELECT * FROM Sales.Customers; -- and note count
|
||||
GO
|
||||
|
||||
GRANT SELECT, UPDATE ON Sales.Customers TO [Great Lakes Sales];
|
||||
GRANT SELECT ON [Application].Cities TO [Great Lakes Sales];
|
||||
GRANT SELECT ON [Application].Countries TO [Great Lakes Sales];
|
||||
GO
|
||||
|
||||
EXECUTE AS USER = 'GreatLakesUser';
|
||||
GO
|
||||
|
||||
-- Now note the count and which rows are returned
|
||||
-- even though we have not changed the command
|
||||
|
||||
SELECT * FROM Sales.Customers;
|
||||
GO
|
||||
|
||||
-- where are those customers?
|
||||
-- note the spatial results tab
|
||||
|
||||
SELECT c.Border
|
||||
FROM [Application].Countries AS c
|
||||
WHERE c.CountryName = N'United States'
|
||||
UNION ALL
|
||||
SELECT c.DeliveryLocation
|
||||
FROM Sales.Customers AS c;
|
||||
GO
|
||||
|
||||
-- updating rows that are accessible to a non-accessible row is blocked
|
||||
|
||||
UPDATE Sales.Customers -- Attempt to update
|
||||
SET DeliveryCityID = 3 -- to a city that is not in the Great Lakes Sales Territory
|
||||
WHERE DeliveryCityID = 32887; -- for a customer that is in the Great Lakes Sales Territory
|
||||
|
||||
REVERT;
|
||||
GO
|
||||
|
||||
-- Remove the user from the role
|
||||
ALTER ROLE [Great Lakes Sales] DROP MEMBER GreatLakesUser;
|
||||
GO
|
||||
|
||||
-- Instead of permission for a role, let's give permissions to the website user
|
||||
GRANT SELECT, UPDATE ON Sales.Customers TO [Website];
|
||||
GRANT SELECT ON [Application].Cities TO [Website];
|
||||
GRANT SELECT ON [Application].Countries TO [Website];
|
||||
GO
|
||||
|
||||
-- Open the second RLS demo window and follow the instructions there
|
||||
|
||||
-- Finally, tidy up (optional)
|
||||
|
||||
REVOKE SELECT, UPDATE ON Sales.Customers FROM [Great Lakes Sales];
|
||||
REVOKE SELECT ON [Application].Cities FROM [Great Lakes Sales];
|
||||
REVOKE SELECT ON [Application].Countries FROM [Great Lakes Sales];
|
||||
REVOKE SELECT, UPDATE ON Sales.Customers FROM [Website];
|
||||
REVOKE SELECT ON [Application].Cities FROM [Website];
|
||||
REVOKE SELECT ON [Application].Countries FROM [Website];
|
||||
GO
|
||||
|
||||
EXEC [Application].Configuration_RemoveRowLevelSecurity;
|
||||
GO
|
||||
|
||||
DROP USER GreatLakesUser;
|
||||
GO
|
||||
|
||||
DROP USER Website;
|
||||
GO
|
||||
|
||||
USE master;
|
||||
GO
|
||||
|
||||
DROP LOGIN GreatLakesUser;
|
||||
GO
|
||||
|
||||
DROP LOGIN Website;
|
||||
GO
|
||||
|
||||
USE tempdb;
|
||||
GO
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
# Sample for use of Row-Level Security in WideWorldImporters
|
||||
|
||||
This script demonstrates the use of Row-Level Security to restrict access to certains rows in the table to certain users.
|
||||
|
||||
|
||||
### Contents
|
||||
|
||||
[About this sample](#about-this-sample)<br/>
|
||||
[Before you begin](#before-you-begin)<br/>
|
||||
[Running the sample](#run-this-sample)<br/>
|
||||
[Sample details](#sample-details)<br/>
|
||||
[Disclaimers](#disclaimers)<br/>
|
||||
[Related links](#related-links)<br/>
|
||||
|
||||
|
||||
<a name=about-this-sample></a>
|
||||
|
||||
## About this sample
|
||||
|
||||
<!-- Delete the ones that don't apply -->
|
||||
1. **Applies to:** SQL Server 2016 (or higher), Azure SQL Database
|
||||
1. **Key features:** Row-Level Security
|
||||
1. **Workload:** OLTP
|
||||
1. **Programming Language:** T-SQL
|
||||
1. **Authors:** Greg Low, Jos de Bruijn
|
||||
1. **Update history:** 26 May 2016 - initial revision
|
||||
|
||||
<a name=before-you-begin></a>
|
||||
|
||||
## Before you begin
|
||||
|
||||
To run this sample, you need the following prerequisites.
|
||||
|
||||
**Software prerequisites:**
|
||||
|
||||
<!-- Examples -->
|
||||
1. SQL Server 2016 (or higher) or Azure SQL Database.
|
||||
- With SQL Server, make sure SQL authentication is enabled.
|
||||
2. SQL Server Management Studio
|
||||
3. The WideWorldImporters database.
|
||||
|
||||
<a name=run-this-sample></a>
|
||||
|
||||
## Running the sample
|
||||
|
||||
1. Open both scripts in different windows or tabs in Management Studio.
|
||||
|
||||
2. Follow the instructions in the main script DemonstrateRLS.sql.
|
||||
|
||||
## Sample details
|
||||
|
||||
The sample adds a new table with sensitive data about suppliers. This sensitive data is always encrypted.
|
||||
|
||||
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.
|
||||
|
||||
<a name=disclaimers></a>
|
||||
|
||||
## Disclaimers
|
||||
The code included in this sample is not intended to be used for production purposes.
|
||||
|
||||
<a name=related-links></a>
|
||||
|
||||
## Related Links
|
||||
<!-- Links to more articles. Remember to delete "en-us" from the link path. -->
|
||||
TBD
|
||||
|
||||
Reference in New Issue
Block a user