1313using Microsoft . Azure . WebJobs . Script . Workers . Rpc ;
1414using Microsoft . Extensions . DependencyInjection ;
1515using Microsoft . Extensions . DependencyInjection . Extensions ;
16+ using Microsoft . Extensions . Logging ;
1617using Xunit ;
1718
1819namespace Microsoft . Azure . WebJobs . Script . Tests . Integration . WebHostEndToEnd
@@ -38,6 +39,7 @@ public JwtTokenAuthTests(TestFixture fixture)
3839 [ InlineData ( nameof ( HttpRequestHeader . Authorization ) , "https://testsite.azurewebsites.net" , "https://testsite.azurewebsites.net" ) ]
3940 [ InlineData ( ScriptConstants . SiteTokenHeaderName ) ]
4041 [ InlineData ( ScriptConstants . SiteTokenHeaderName , "https://appservice.core.azurewebsites.net" , "https://testsite.azurewebsites.net" ) ]
42+ [ InlineData ( ScriptConstants . SiteTokenHeaderName , "https://AppService.Core.Azurewebsites.net" , "https://TestSite.Azurewebsites.net" ) ]
4143 [ InlineData ( ScriptConstants . SiteTokenHeaderName , "https://appservice.core.azurewebsites.net" , "https://testsite.azurewebsites.net/azurefunctions" ) ]
4244 [ InlineData ( ScriptConstants . SiteTokenHeaderName , "https://testsite.scm.azurewebsites.net" , "https://testsite.azurewebsites.net" ) ]
4345 [ InlineData ( ScriptConstants . SiteTokenHeaderName , "https://testsite.scm.azurewebsites.net" , "https://testsite.azurewebsites.net/azurefunctions" ) ]
@@ -63,10 +65,10 @@ public async Task InvokeAdminApi_ValidToken_Succeeds(string headerName, string i
6365 [ Theory ]
6466 [ InlineData ( nameof ( HttpRequestHeader . Authorization ) ) ]
6567 [ InlineData ( ScriptConstants . SiteTokenHeaderName ) ]
66- public async Task InvokeAdminApi_InvalidToken_Fails ( string headerName )
68+ public async Task InvokeAdminApi_InvalidAudience_Fails ( string headerName )
6769 {
6870 HttpRequestMessage request = new HttpRequestMessage ( HttpMethod . Get , "admin/host/status" ) ;
69- string token = _fixture . Host . GenerateAdminJwtToken ( "invalid" , "invalid" ) ;
71+ string token = _fixture . Host . GenerateAdminJwtToken ( audience : "invalid" ) ;
7072
7173 if ( string . Compare ( nameof ( HttpRequestHeader . Authorization ) , headerName ) == 0 )
7274 {
@@ -77,8 +79,73 @@ public async Task InvokeAdminApi_InvalidToken_Fails(string headerName)
7779 request . Headers . Add ( headerName , token ) ;
7880 }
7981
82+ _fixture . Host . ClearLogMessages ( ) ;
83+
8084 var response = await _fixture . Host . HttpClient . SendAsync ( request ) ;
8185 Assert . Equal ( HttpStatusCode . Unauthorized , response . StatusCode ) ;
86+
87+ var validationError = _fixture . Host . GetScriptHostLogMessages ( ) . Single ( p => p . Level == LogLevel . Error ) ;
88+ Assert . Equal ( ScriptConstants . LogCategoryHostAuthentication , validationError . Category ) ;
89+ Assert . Equal ( "Token audience validation failed for audience 'invalid'." , validationError . FormattedMessage ) ;
90+ Assert . True ( validationError . Exception . Message . StartsWith ( "IDX10231: Audience validation failed." ) ) ;
91+ }
92+
93+ [ Theory ]
94+ [ InlineData ( nameof ( HttpRequestHeader . Authorization ) ) ]
95+ [ InlineData ( ScriptConstants . SiteTokenHeaderName ) ]
96+ public async Task InvokeAdminApi_InvalidIssuer_Fails ( string headerName )
97+ {
98+ HttpRequestMessage request = new HttpRequestMessage ( HttpMethod . Get , "admin/host/status" ) ;
99+ string token = _fixture . Host . GenerateAdminJwtToken ( issuer : "invalid" ) ;
100+
101+ if ( string . Compare ( nameof ( HttpRequestHeader . Authorization ) , headerName ) == 0 )
102+ {
103+ request . Headers . Authorization = new AuthenticationHeaderValue ( "Bearer" , token ) ;
104+ }
105+ else
106+ {
107+ request . Headers . Add ( headerName , token ) ;
108+ }
109+
110+ _fixture . Host . ClearLogMessages ( ) ;
111+
112+ var response = await _fixture . Host . HttpClient . SendAsync ( request ) ;
113+ Assert . Equal ( HttpStatusCode . Unauthorized , response . StatusCode ) ;
114+
115+ var validationError = _fixture . Host . GetScriptHostLogMessages ( ) . Single ( p => p . Level == LogLevel . Error ) ;
116+ Assert . Equal ( ScriptConstants . LogCategoryHostAuthentication , validationError . Category ) ;
117+ Assert . Equal ( "Token issuer validation failed for issuer 'invalid'." , validationError . FormattedMessage ) ;
118+ Assert . Equal ( "IDX10205: Issuer validation failed." , validationError . Exception . Message ) ;
119+ }
120+
121+ [ Theory ]
122+ [ InlineData ( nameof ( HttpRequestHeader . Authorization ) ) ]
123+ [ InlineData ( ScriptConstants . SiteTokenHeaderName ) ]
124+ public async Task InvokeAdminApi_InvalidSignature_Fails ( string headerName )
125+ {
126+ HttpRequestMessage request = new HttpRequestMessage ( HttpMethod . Get , "admin/host/status" ) ;
127+
128+ byte [ ] keyBytes = TestHelpers . GenerateKeyBytes ( ) ;
129+ string token = _fixture . Host . GenerateAdminJwtToken ( key : keyBytes ) ;
130+
131+ if ( string . Compare ( nameof ( HttpRequestHeader . Authorization ) , headerName ) == 0 )
132+ {
133+ request . Headers . Authorization = new AuthenticationHeaderValue ( "Bearer" , token ) ;
134+ }
135+ else
136+ {
137+ request . Headers . Add ( headerName , token ) ;
138+ }
139+
140+ _fixture . Host . ClearLogMessages ( ) ;
141+
142+ var response = await _fixture . Host . HttpClient . SendAsync ( request ) ;
143+ Assert . Equal ( HttpStatusCode . Unauthorized , response . StatusCode ) ;
144+
145+ var validationError = _fixture . Host . GetScriptHostLogMessages ( ) . Single ( p => p . Level == LogLevel . Error ) ;
146+ Assert . Equal ( ScriptConstants . LogCategoryHostAuthentication , validationError . Category ) ;
147+ Assert . Equal ( "Token validation failed." , validationError . FormattedMessage ) ;
148+ Assert . True ( validationError . Exception . Message . StartsWith ( "IDX10503: Signature validation failed." ) ) ;
82149 }
83150
84151 [ Fact ]
0 commit comments