@@ -805,7 +805,7 @@ public async Task CloudAdapterCreateConversation()
805
805
Assert . Equal ( expectedChannelId , actualChannelId ) ;
806
806
}
807
807
808
- [ Fact ( Skip = "Expired token not working anymore, disabling it until fixed." ) ]
808
+ [ Fact ]
809
809
public async Task ExpiredTokenShouldThrowUnauthorizedAccessException ( )
810
810
{
811
811
// Arrange
@@ -824,9 +824,29 @@ public async Task ExpiredTokenShouldThrowUnauthorizedAccessException()
824
824
// }
825
825
// (Invoke-WebRequest -Uri 'https://login.microsoftonline.com/botframework.com/oauth2/v2.0/token' -Method Post -Form $Form).Content
826
826
// - delete the app
827
- var token = "Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Ii1LSTNROW5OUjdiUm9meG1lWm9YcWJIWkdldyIsImtpZCI6Ii1LSTNROW5OUjdiUm9meG1lWm9YcWJIWkdldyJ9.eyJhdWQiOiJodHRwczovL2FwaS5ib3RmcmFtZXdvcmsuY29tIiwiaXNzIjoiaHR0cHM6Ly9zdHMud2luZG93cy5uZXQvZDZkNDk0MjAtZjM5Yi00ZGY3LWExZGMtZDU5YTkzNTg3MWRiLyIsImlhdCI6MTY5Mjg3MDMwMiwibmJmIjoxNjkyODcwMzAyLCJleHAiOjE2OTI5NTcwMDIsImFpbyI6IkUyRmdZUGhhdFZ6czVydGFFYTlWbDN2ZnIyQ2JBZ0E9IiwiYXBwaWQiOiIxNWYwMTZmZS00ODhjLTQwZTktOWNiZS00Yjk0OGY5OGUyMmMiLCJhcHBpZGFjciI6IjEiLCJpZHAiOiJodHRwczovL3N0cy53aW5kb3dzLm5ldC9kNmQ0OTQyMC1mMzliLTRkZjctYTFkYy1kNTlhOTM1ODcxZGIvIiwicmgiOiIwLkFXNEFJSlRVMXB2ejkwMmgzTldhazFoeDIwSXpMWTBwejFsSmxYY09EcS05RnJ4dUFBQS4iLCJ0aWQiOiJkNmQ0OTQyMC1mMzliLTRkZjctYTFkYy1kNTlhOTM1ODcxZGIiLCJ1dGkiOiJkenVwa1dWd2FVT2x1RldkbnlvLUFBIiwidmVyIjoiMS4wIn0.sbQH997Q2GDKiiYd6l5MIz_XNfXypJd6zLY9xjtvEgXMBB0x0Vu3fv9W0nM57_ZipQiZDTZuSQA5BE30KBBwU-ZVqQ7MgiTkmE9eF6Ngie_5HwSr9xMK3EiDghHiOP9pIj3oEwGOSyjR5L9n-7tLSdUbKVyV14nS8OQtoPd1LZfoZI3e7tVu3vx8Lx3KzudanXX8Vz7RKaYndj3RyRi4wEN5hV9ab40d7fQsUzygFd5n_PXC2rs0OhjZJzjCOTC0VLQEn1KwiTkSH1E-OSzkrMltn1sbhD2tv_H-4rqQd51vAEJ7esC76qQjz_pfDRLs6T2jvJyhd5MZrN_MT0TqlA" ;
828
827
829
- headerDictionaryMock . Setup ( h => h [ It . Is < string > ( v => v == "Authorization" ) ] ) . Returns < string > ( ( _ ) => token ) ;
828
+ // Fake expired token
829
+ var tid = Guid . NewGuid ( ) . ToString ( ) ;
830
+ var header = new { alg = "RS256" , typ = "JWT" , kid = Guid . NewGuid ( ) . ToString ( ) } ;
831
+ var payload = new
832
+ {
833
+ aud = "https://api.botframework.com" ,
834
+ iss = $ "https://sts.windows.net/{ tid } /",
835
+ iat = DateTimeOffset . UtcNow . AddHours ( - 2 ) . ToUnixTimeSeconds ( ) ,
836
+ nbf = DateTimeOffset . UtcNow . AddHours ( - 2 ) . ToUnixTimeSeconds ( ) ,
837
+ exp = DateTimeOffset . UtcNow . AddHours ( - 1 ) . ToUnixTimeSeconds ( ) ,
838
+ tid ,
839
+ ver = "1.0"
840
+ } ;
841
+
842
+ var headerBase64 = Base64UrlEncode ( JsonConvert . SerializeObject ( header ) ) ;
843
+ var payloadBase64 = Base64UrlEncode ( JsonConvert . SerializeObject ( payload ) ) ;
844
+ var rawSignature = "dummySignature" ;
845
+ var bearerToken = $ "Bearer { headerBase64 } .{ payloadBase64 } .{ rawSignature } ";
846
+
847
+ headerDictionaryMock
848
+ . Setup ( h => h [ It . Is < string > ( v => v == "Authorization" ) ] )
849
+ . Returns < string > ( ( _ ) => bearerToken ) ;
830
850
831
851
var httpRequestMock = new Mock < HttpRequest > ( ) ;
832
852
httpRequestMock . Setup ( r => r . Method ) . Returns ( HttpMethods . Post ) ;
@@ -912,6 +932,16 @@ private static Stream CreateStream(Activity activity)
912
932
return stream ;
913
933
}
914
934
935
+ // Helper method for Base64Url encoding
936
+ private string Base64UrlEncode ( string input )
937
+ {
938
+ var bytes = System . Text . Encoding . UTF8 . GetBytes ( input ) ;
939
+ return Convert . ToBase64String ( bytes )
940
+ . TrimEnd ( '=' ) // Remove padding
941
+ . Replace ( '+' , '-' ) // Replace '+' with '-'
942
+ . Replace ( '/' , '_' ) ; // Replace '/' with '_'
943
+ }
944
+
915
945
private class InvokeResponseBot : IBot
916
946
{
917
947
public async Task OnTurnAsync ( ITurnContext turnContext , CancellationToken cancellationToken = default ( CancellationToken ) )
0 commit comments