11using System ;
2- using System . Collections ;
3- using System . Linq ;
4- using System . Reflection ;
5- using System . Security . Cryptography ;
6- using System . Text ;
2+ using Microsoft . Data . SqlClient . ManualTesting . Tests . SQL . Common . SystemDataInternals ;
73using Xunit ;
84using Xunit . Abstractions ;
95
@@ -21,21 +17,19 @@ public AADFedAuthTokenRefreshTest(ITestOutputHelper testOutputHelper)
2117 [ ConditionalFact ( typeof ( DataTestUtility ) , nameof ( DataTestUtility . IsAADPasswordConnStrSetup ) ) ]
2218 public void FedAuthTokenRefreshTest ( )
2319 {
24- string connStr = DataTestUtility . AADPasswordConnectionString ;
20+ string connectionString = DataTestUtility . AADPasswordConnectionString ;
2521
26- // Create a new connection object and open it
27- using ( SqlConnection connection = new SqlConnection ( connStr ) )
22+ using ( SqlConnection connection = new SqlConnection ( connectionString ) )
2823 {
2924 connection . Open ( ) ;
3025
31- // Set the token expiry to expire in 1 minute from now to force token refresh
32- string tokenHash1 = "" ;
33- DateTime ? oldExpiry = GetOrSetTokenExpiryDateTime ( connection , true , out tokenHash1 ) ;
34- Assert . True ( oldExpiry != null , "Failed to make token expiry to expire in one minute." ) ;
26+ string oldTokenHash = "" ;
27+ DateTime ? oldExpiryDateTime = FedAuthTokenHelper . SetTokenExpiryDateTime ( connection , minutesToExpire : 1 , out oldTokenHash ) ;
28+ Assert . True ( oldExpiryDateTime != null , "Failed to make token expiry to expire in one minute." ) ;
3529
3630 // Convert and display the old expiry into local time which should be in 1 minute from now
37- DateTime oldLocalExpiryTime = TimeZoneInfo . ConvertTimeFromUtc ( ( DateTime ) oldExpiry , TimeZoneInfo . Local ) ;
38- LogInfo ( $ "Token: { tokenHash1 } Old Expiry: { oldLocalExpiryTime } ") ;
31+ DateTime oldLocalExpiryTime = TimeZoneInfo . ConvertTimeFromUtc ( ( DateTime ) oldExpiryDateTime , TimeZoneInfo . Local ) ;
32+ LogInfo ( $ "Token: { oldTokenHash } Old Expiry: { oldLocalExpiryTime } ") ;
3933 TimeSpan timeDiff = oldLocalExpiryTime - DateTime . Now ;
4034 Assert . True ( timeDiff . TotalSeconds <= 60 , "Failed to set expiry after 1 minute from current time." ) ;
4135
@@ -47,24 +41,22 @@ public void FedAuthTokenRefreshTest()
4741 Assert . True ( result != string . Empty , "The connection's command must return a value" ) ;
4842
4943 // The new connection will use the same FedAuthToken but will refresh it first as it will expire in 1 minute.
50- using ( SqlConnection connection2 = new SqlConnection ( connStr ) )
44+ using ( SqlConnection connection2 = new SqlConnection ( connectionString ) )
5145 {
5246 connection2 . Open ( ) ;
5347
54- // Check again if connection is alive
48+ // Check if connection is alive
5549 cmd = connection2 . CreateCommand ( ) ;
5650 cmd . CommandText = "select 1" ;
5751 result = $ "{ cmd . ExecuteScalar ( ) } ";
5852 Assert . True ( result != string . Empty , "The connection's command must return a value after a token refresh." ) ;
5953
60- // Get the refreshed token expiry
61- string tokenHash2 = "" ;
62- DateTime ? newExpiry = GetOrSetTokenExpiryDateTime ( connection2 , false , out tokenHash2 ) ;
63- // Display new expiry in local time
64- DateTime newLocalExpiryTime = TimeZoneInfo . ConvertTimeFromUtc ( ( DateTime ) newExpiry , TimeZoneInfo . Local ) ;
65- LogInfo ( $ "Token: { tokenHash2 } New Expiry: { newLocalExpiryTime } ") ;
54+ string newTokenHash = "" ;
55+ DateTime ? newExpiryDateTime = FedAuthTokenHelper . GetTokenExpiryDateTime ( connection2 , out newTokenHash ) ;
56+ DateTime newLocalExpiryTime = TimeZoneInfo . ConvertTimeFromUtc ( ( DateTime ) newExpiryDateTime , TimeZoneInfo . Local ) ;
57+ LogInfo ( $ "Token: { newTokenHash } New Expiry: { newLocalExpiryTime } ") ;
6658
67- Assert . True ( tokenHash1 == tokenHash2 , "The token's hash before and after token refresh must be identical." ) ;
59+ Assert . True ( oldTokenHash == newTokenHash , "The token's hash before and after token refresh must be identical." ) ;
6860 Assert . True ( newLocalExpiryTime > oldLocalExpiryTime , "The refreshed token must have a new or later expiry time." ) ;
6961 }
7062 }
@@ -74,60 +66,5 @@ private void LogInfo(string message)
7466 {
7567 _testOutputHelper . WriteLine ( message ) ;
7668 }
77-
78- private DateTime ? GetOrSetTokenExpiryDateTime ( SqlConnection connection , bool setExpiry , out string tokenHash )
79- {
80- try
81- {
82- // Get the inner connection
83- object innerConnectionObj = connection . GetType ( ) . GetProperty ( "InnerConnection" , BindingFlags . NonPublic | BindingFlags . Instance ) . GetValue ( connection ) ;
84-
85- // Get the db connection pool
86- object poolObj = innerConnectionObj . GetType ( ) . GetProperty ( "Pool" , BindingFlags . NonPublic | BindingFlags . Instance ) . GetValue ( innerConnectionObj ) ;
87-
88- // Get the Authentication Contexts
89- IEnumerable authContextCollection = ( IEnumerable ) poolObj . GetType ( ) . GetProperty ( "AuthenticationContexts" , BindingFlags . NonPublic | BindingFlags . Instance ) . GetValue ( poolObj , null ) ;
90-
91- // Get the first authentication context
92- object authContextObj = authContextCollection . Cast < object > ( ) . FirstOrDefault ( ) ;
93-
94- // Get the token object from the authentication context
95- object tokenObj = authContextObj . GetType ( ) . GetProperty ( "Value" ) . GetValue ( authContextObj , null ) ;
96-
97- DateTime expiry = ( DateTime ) tokenObj . GetType ( ) . GetProperty ( "ExpirationTime" , BindingFlags . NonPublic | BindingFlags . Instance ) . GetValue ( tokenObj , null ) ;
98-
99- if ( setExpiry )
100- {
101- // Forcing 1 minute expiry to trigger token refresh.
102- expiry = DateTime . UtcNow . AddMinutes ( 1 ) ;
103-
104- // Apply the expiry to the token object
105- FieldInfo expirationTime = tokenObj . GetType ( ) . GetField ( "_expirationTime" , BindingFlags . NonPublic | BindingFlags . Instance ) ;
106- expirationTime . SetValue ( tokenObj , expiry ) ;
107- }
108-
109- byte [ ] tokenBytes = ( byte [ ] ) tokenObj . GetType ( ) . GetProperty ( "AccessToken" , BindingFlags . NonPublic | BindingFlags . Instance ) . GetValue ( tokenObj , null ) ;
110-
111- tokenHash = GetTokenHash ( tokenBytes ) ;
112-
113- return expiry ;
114- }
115- catch ( Exception )
116- {
117- tokenHash = "" ;
118- return null ;
119- }
120- }
121-
122- private string GetTokenHash ( byte [ ] tokenBytes )
123- {
124- string token = Encoding . Unicode . GetString ( tokenBytes ) ;
125- var bytesInUtf8 = Encoding . UTF8 . GetBytes ( token ) ;
126- using ( var sha256 = SHA256 . Create ( ) )
127- {
128- var hash = sha256 . ComputeHash ( bytesInUtf8 ) ;
129- return Convert . ToBase64String ( hash ) ;
130- }
131- }
13269 }
13370}
0 commit comments