You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Fix Session Context Key set as Read_Only & maintain original roles from the JWT token (#2344)
## Why make this change?
- Fixes#2341
- The session context in SQL server is `read_only = 1` which prevents
users from doing multiple requests on the same connection.
- The row level security is not accurately implemented when using a JWT
token.
## What is this change?
Changes the session context from `read_only = 1` to `read_only = 0` to
allow multiple requests to be done in the same connection,
Creates a copy of the original 'roles' from the JWT token to use it on
the SQL Filter Predicate to accurately implement row level security.
## How was this tested?
- [ ] Integration Tests
- [x] Unit Tests
Updated `AuthorizationResolver` tests to ensure the original roles copy
is working properly.
## Sample Request(s)
Sample of a JWT token (only the relevant part)
```
{
"aud": "api://ddcf6b31-5d01-407d-97cf-8efefc455d32",
"iss": "https://sts.windows.net/9215c785-95c3-49b0-bdba-2062df5aedb5/",
"roles": [
"user",
"Allow_Customer_OPS025235",
"Allow_Customer_OPS004095"
],
"ver": "1.0"
}
```
X-MS-API-ROLE: user
before my change the extra 'roles' that do not match the X-MS-API-ROLE
header would never reach the database context.
With my change you can do things like this in SQL Predicates to filter
out only subsets of the data:
```
CREATE FUNCTION dbo.ops_fact_order_Predicate(@CustomerNo varchar(max))
RETURNS TABLE
WITH SCHEMABINDING
AS RETURN SELECT 1 AS fn_securitypredicate_result
WHERE @CustomerNo in (
select trim(replace(replace(replace([value], '"', ''), ']', ''), 'Allow_Customer_', ''))
from STRING_SPLIT (
CAST(SESSION_CONTEXT(N'original_roles') as varchar(max))
, ','
, 0)
where trim(replace(replace([value], '"', ''), ']', '')) like 'Allow_Customer%'
)
CREATE SECURITY POLICY dbo.ops_fact_order_Policy
ADD FILTER PREDICATE dbo.ops_fact_order_Predicate(CustomerNo)
ON [gold_ops].[ops_fact_order];
```
---------
Co-authored-by: KobeLenjou <[email protected]>
Co-authored-by: Aniruddh Munde <[email protected]>
Co-authored-by: Ruben Cerna <[email protected]>
Co-authored-by: RubenCerna2079 <[email protected]>
@@ -1315,6 +1316,7 @@ public void UniqueClaimsResolvedForDbPolicy_SessionCtx_Usage()
1315
1316
Assert.AreEqual(expected:"Aa_0RISCzzZ-abC1De2fGHIjKLMNo123pQ4rStUVWXY",actual:claimsInRequestContext["sub"],message:"Expected the sub claim to be present.");
1316
1317
Assert.AreEqual(expected:"55296aad-ea7f-4c44-9a4c-bb1e8d43a005",actual:claimsInRequestContext["oid"],message:"Expected the oid claim to be present.");
1317
1318
Assert.AreEqual(claimsInRequestContext[AuthenticationOptions.ROLE_CLAIM_TYPE],actual:TEST_ROLE,message:"The roles claim should have the value:"+TEST_ROLE);
1319
+
Assert.AreEqual(expected:"[\""+TEST_ROLE+"\",\"ROLE2\",\"ROLE3\"]",actual:claimsInRequestContext[AuthenticationOptions.ORIGINAL_ROLE_CLAIM_TYPE],message:"Original roles should be preserved in a new context");
1318
1320
}
1319
1321
1320
1322
/// <summary>
@@ -1365,7 +1367,7 @@ public void ValidateUnauthenticatedUserClaimsAreNotResolvedWhenProcessingUserCla
Assert.AreEqual(expected:authenticatedUserclaims.Count,actual:resolvedClaims.Count,message:"Only two claims should be present.");
1370
+
Assert.AreEqual(expected:authenticatedUserclaims.Count+1,actual:resolvedClaims.Count,message:"Only "+(authenticatedUserclaims.Count+1)+" claims should be present.");
0 commit comments