Skip to content

Commit 667a08b

Browse files
committed
improved sample using jwt
1 parent feaaf87 commit 667a08b

File tree

4 files changed

+87
-31
lines changed

4 files changed

+87
-31
lines changed

app.py

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,23 +8,47 @@
88
from threading import Lock
99
from tenacity import *
1010
import logging
11+
import jwt
1112

1213
# Initialize Flask
1314
app = Flask(__name__)
1415

1516
# Setup Flask Restful framework
1617
api = Api(app)
1718
parser = reqparse.RequestParser()
18-
parser.add_argument('X-UserName', location='headers')
19+
parser.add_argument('Authorization', location='headers')
1920

2021
# Set connection string
2122
application_name = ";APP={0}".format(socket.gethostname())
2223
connection_string = os.environ['SQLAZURECONNSTR_RLS'] + application_name
2324

2425
class Queryable(Resource):
25-
def get(self):
26-
args = parser.parse_args()
27-
result = self.executeQueryJson("get", args["X-UserName"])
26+
def __authorize(self):
27+
encoded = ""
28+
user_hash_id = 0
29+
30+
request_args = parser.parse_args()
31+
authorization = request_args["Authorization"]
32+
tokens = authorization.split()
33+
34+
if tokens[0].lower() == "bearer":
35+
encoded = tokens[1]
36+
else:
37+
raise Exception("Wrong authorization schema")
38+
39+
try:
40+
secure_payload = jwt.decode(encoded, 'mySUPERs3cr3t', algorithms=['HS256'])
41+
user_hash_id = int(secure_payload["user-hash-id"])
42+
except jwt.InvalidSignatureError:
43+
user_hash_id = 0
44+
except:
45+
raise
46+
47+
return user_hash_id
48+
49+
def get(self):
50+
user_hash_id = self.__authorize()
51+
result = self.executeQueryJson("get", user_hash_id)
2852
return result, 200
2953

3054
@retry(stop=stop_after_attempt(3), wait=wait_fixed(10), retry=retry_if_exception_type(pyodbc.OperationalError), after=after_log(app.logger, logging.DEBUG))
@@ -39,11 +63,13 @@ def executeQueryJson(self, verb, username, payload=None):
3963
cursor = conn.cursor()
4064

4165
# set session context info, used by Row-Level Security
42-
cursor.execute(f"EXEC sys.sp_set_session_context @key=N'username', @value=?, @read_only=1;", username)
66+
cursor.execute(f"EXEC sys.sp_set_session_context @key=N'user-hash-id', @value=?, @read_only=1;", username)
4367

4468
if payload:
69+
print("EXEC %s %s" % (procedure, json.dumps(payload)))
4570
cursor.execute(f"EXEC {procedure} ?", json.dumps(payload))
4671
else:
72+
print("EXEC %s" % procedure)
4773
cursor.execute(f"EXEC {procedure}")
4874

4975
result = cursor.fetchone()

requirements.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,5 @@ pyodbc
22
flask
33
flask-restful
44
tenacity
5-
python-dotenv
5+
python-dotenv
6+
PyJWT

sql/SetupRLS.sql renamed to sql/00-SetupRLS.sql

Lines changed: 22 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,13 @@ drop function if exists rls.fn_SecurityPredicate;
77
drop table if exists rls.SensitiveDataPermissions;
88
drop table if exists dbo.EvenMoreSensitiveData;
99
drop table if exists dbo.SensitiveData;
10+
drop procedure if exists web.get_sensitivedata
11+
drop procedure if exists web.get_evenmoresensitivedata
12+
go
13+
14+
drop schema if exists web;
15+
go
16+
create schema web;
1017
go
1118

1219
drop schema if exists rls;
@@ -38,13 +45,16 @@ go
3845

3946
create table rls.SensitiveDataPermissions
4047
(
41-
UserName sysname not null,
48+
UserHashId bigint not null,
4249
SensitiveDataId int not null foreign key references dbo.SensitiveData(Id),
4350
HasAccess bit not null default(0),
44-
constraint pk__rls_SensitiveDataPermissions primary key clustered (UserName, SensitiveDataId)
51+
constraint pk__rls_SensitiveDataPermissions primary key nonclustered (UserHashId, SensitiveDataId)
4552
)
4653
go
4754

55+
create clustered index ixc on rls.SensitiveDataPermissions (SensitiveDataId)
56+
go
57+
4858
insert into dbo.SensitiveData values
4959
(1, 'Davide', 'Mauri', '{"SuperPowers":"Fly"}'),
5060
(2, 'John', 'Doe', '{"SuperPowers":"Laser Eyes"}')
@@ -59,8 +69,8 @@ insert into dbo.EvenMoreSensitiveData values
5969
go
6070

6171
insert into rls.SensitiveDataPermissions values
62-
('damauri', 1, 1),
63-
('jdoe', 2, 1)
72+
(-6134311, 1, 1),
73+
(1225328053, 2, 1)
6474
go
6575

6676
create function rls.fn_securitypredicate(@SensitiveDataId int)
@@ -73,32 +83,13 @@ select
7383
from
7484
rls.SensitiveDataPermissions
7585
where
76-
database_principal_id() = database_principal_id('MiddleTierUser')
86+
(database_principal_id() = database_principal_id('MiddleTierUser') or is_member('db_owner') = 1)
7787
and
78-
UserName = session_context(N'username')
88+
UserHashId = cast(session_context(N'user-hash-id') as bigint)
7989
and
8090
SensitiveDataId = @SensitiveDataId
8191
go
8292

83-
select * from dbo.SensitiveData
84-
go
85-
86-
create security policy rls.SensitiveDataPolicy
87-
add filter predicate rls.fn_SecurityPredicate(Id) on dbo.SensitiveData,
88-
add filter predicate rls.fn_SecurityPredicate(SensitiveDataId) on dbo.EvenMoreSensitiveData
89-
with (state = on);
90-
91-
select * from dbo.SensitiveData
92-
select * from dbo.EvenMoreSensitiveData
93-
go
94-
95-
exec sys.sp_set_session_context @key = N'username', @value = 'damauri', @read_only = 0;
96-
go
97-
98-
exec sys.sp_set_session_context @key = N'username', @value = 'jdoe', @read_only = 0;
99-
go
100-
101-
10293
create or alter procedure web.get_sensitivedata
10394
as
10495
select
@@ -136,3 +127,9 @@ from
136127
for
137128
json path
138129
go
130+
131+
create security policy rls.SensitiveDataPolicy
132+
add filter predicate rls.fn_SecurityPredicate(Id) on dbo.SensitiveData,
133+
add filter predicate rls.fn_SecurityPredicate(SensitiveDataId) on dbo.EvenMoreSensitiveData
134+
with (state = off);
135+

sql/01-Test.sql

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
select * from dbo.SensitiveData
2+
select * from dbo.EvenMoreSensitiveData
3+
go
4+
5+
alter security policy rls.SensitiveDataPolicy
6+
with (state = on)
7+
go
8+
9+
select * from dbo.SensitiveData
10+
select * from dbo.EvenMoreSensitiveData
11+
go
12+
13+
exec sys.sp_set_session_context @key = N'user-hash-id', @value = -6134311, @read_only = 0;
14+
go
15+
16+
select * from dbo.SensitiveData
17+
select * from dbo.EvenMoreSensitiveData
18+
go
19+
20+
exec sys.sp_set_session_context @key = N'user-hash-id', @value = 1225328053, @read_only = 0;
21+
go
22+
23+
select * from dbo.SensitiveData
24+
select * from dbo.EvenMoreSensitiveData
25+
go
26+
27+
exec sys.sp_set_session_context @key = 'user-hash-id', @value = 0, @read_only = 0;
28+
go
29+
30+
select * from dbo.SensitiveData
31+
select * from dbo.EvenMoreSensitiveData
32+
go

0 commit comments

Comments
 (0)