15
15
using Microsoft . Azure . WebJobs . Script . Extensions ;
16
16
using Microsoft . Azure . WebJobs . Script . WebHost ;
17
17
using Microsoft . Azure . WebJobs . Script . WebHost . Security . Authentication ;
18
+ using Microsoft . Azure . WebJobs . Script . WebHost . Security . Authentication . Jwt ;
19
+ using Microsoft . Extensions . DependencyInjection . Extensions ;
18
20
using Microsoft . Extensions . Logging ;
21
+ using Microsoft . Extensions . Options ;
19
22
using Microsoft . Extensions . Primitives ;
20
23
using Microsoft . IdentityModel . Tokens ;
21
24
using static Microsoft . Azure . WebJobs . Script . EnvironmentSettingNames ;
@@ -28,63 +31,68 @@ public static class ScriptJwtBearerExtensions
28
31
private static double _specialized = 0 ;
29
32
30
33
public static AuthenticationBuilder AddScriptJwtBearer ( this AuthenticationBuilder builder )
31
- => builder . AddJwtBearer ( o =>
34
+ {
35
+ builder . Services . TryAddEnumerable ( ServiceDescriptor . Singleton < IPostConfigureOptions < JwtBearerOptions > , JwtBearerPostConfigureOptions > ( ) ) ;
36
+ return builder . AddScheme < JwtBearerOptions , ScriptJwtBearerHandler > (
37
+ JwtBearerDefaults . AuthenticationScheme , displayName : null , ConfigureOptions ) ;
38
+ }
39
+
40
+ private static void ConfigureOptions ( JwtBearerOptions options )
41
+ {
42
+ options . Events = new JwtBearerEvents ( )
32
43
{
33
- o . Events = new JwtBearerEvents ( )
44
+ OnMessageReceived = c =>
34
45
{
35
- OnMessageReceived = c =>
46
+ // By default, tokens are passed via the standard Authorization Bearer header. However we also support
47
+ // passing tokens via the x-ms-site-token header.
48
+ if ( c . Request . Headers . TryGetValue ( ScriptConstants . SiteTokenHeaderName , out StringValues values ) )
36
49
{
37
- // By default, tokens are passed via the standard Authorization Bearer header. However we also support
38
- // passing tokens via the x-ms-site-token header.
39
- if ( c . Request . Headers . TryGetValue ( ScriptConstants . SiteTokenHeaderName , out StringValues values ) )
40
- {
41
- // the token we set here will be the one used - Authorization header won't be checked.
42
- c . Token = values . FirstOrDefault ( ) ;
43
- }
44
-
45
- // Temporary: Tactical fix to address specialization issues. This should likely be moved to a token validator
46
- // TODO: DI (FACAVAL) This will be fixed once the permanent fix is in place
47
- if ( _specialized == 0 && ! SystemEnvironment . Instance . IsPlaceholderModeEnabled ( ) && Interlocked . CompareExchange ( ref _specialized , 1 , 0 ) == 0 )
48
- {
49
- o . TokenValidationParameters = CreateTokenValidationParameters ( ) ;
50
- }
51
-
52
- return Task . CompletedTask ;
53
- } ,
54
- OnTokenValidated = c =>
50
+ // the token we set here will be the one used - Authorization header won't be checked.
51
+ c . Token = values . FirstOrDefault ( ) ;
52
+ }
53
+
54
+ // Temporary: Tactical fix to address specialization issues. This should likely be moved to a token validator
55
+ // TODO: DI (FACAVAL) This will be fixed once the permanent fix is in place
56
+ if ( _specialized == 0 && ! SystemEnvironment . Instance . IsPlaceholderModeEnabled ( ) && Interlocked . CompareExchange ( ref _specialized , 1 , 0 ) == 0 )
55
57
{
56
- var claims = new List < Claim >
57
- {
58
- new Claim ( SecurityConstants . AuthLevelClaimType , AuthorizationLevel . Admin . ToString ( ) )
59
- } ;
60
- if ( ! string . Equals ( c . SecurityToken . Issuer , ScriptConstants . AppServiceCoreUri , StringComparison . OrdinalIgnoreCase ) )
61
- {
62
- claims . Add ( new Claim ( SecurityConstants . InvokeClaimType , "true" ) ) ;
63
- }
64
-
65
- c . Principal . AddIdentity ( new ClaimsIdentity ( claims ) ) ;
66
-
67
- c . Success ( ) ;
68
-
69
- return Task . CompletedTask ;
70
- } ,
71
- OnAuthenticationFailed = c =>
58
+ options . TokenValidationParameters = CreateTokenValidationParameters ( ) ;
59
+ }
60
+
61
+ return Task . CompletedTask ;
62
+ } ,
63
+ OnTokenValidated = c =>
64
+ {
65
+ var claims = new List < Claim >
72
66
{
73
- LogAuthenticationFailure ( c ) ;
67
+ new Claim ( SecurityConstants . AuthLevelClaimType , AuthorizationLevel . Admin . ToString ( ) )
68
+ } ;
74
69
75
- return Task . CompletedTask ;
70
+ if ( ! string . Equals ( c . SecurityToken . Issuer , ScriptConstants . AppServiceCoreUri , StringComparison . OrdinalIgnoreCase ) )
71
+ {
72
+ claims . Add ( new Claim ( SecurityConstants . InvokeClaimType , "true" ) ) ;
76
73
}
77
- } ;
78
74
79
- o . TokenValidationParameters = CreateTokenValidationParameters ( ) ;
75
+ c . Principal . AddIdentity ( new ClaimsIdentity ( claims ) ) ;
76
+ c . Success ( ) ;
80
77
81
- // TODO: DI (FACAVAL) Remove this once the work above is completed.
82
- if ( ! SystemEnvironment . Instance . IsPlaceholderModeEnabled ( ) )
78
+ return Task . CompletedTask ;
79
+ } ,
80
+ OnAuthenticationFailed = c =>
83
81
{
84
- // We're not in standby mode, so flag as specialized
85
- _specialized = 1 ;
82
+ LogAuthenticationFailure ( c ) ;
83
+ return Task . CompletedTask ;
86
84
}
87
- } ) ;
85
+ } ;
86
+
87
+ options . TokenValidationParameters = CreateTokenValidationParameters ( ) ;
88
+
89
+ // TODO: DI (FACAVAL) Remove this once the work above is completed.
90
+ if ( ! SystemEnvironment . Instance . IsPlaceholderModeEnabled ( ) )
91
+ {
92
+ // We're not in standby mode, so flag as specialized
93
+ _specialized = 1 ;
94
+ }
95
+ }
88
96
89
97
private static IEnumerable < string > GetValidAudiences ( )
90
98
{
@@ -134,12 +142,12 @@ public static TokenValidationParameters CreateTokenValidationParameters()
134
142
result . AudienceValidator = AudienceValidator ;
135
143
result . IssuerValidator = IssuerValidator ;
136
144
result . ValidAudiences = GetValidAudiences ( ) ;
137
- result . ValidIssuers = new string [ ]
138
- {
145
+ result . ValidIssuers =
146
+ [
139
147
AppServiceCoreUri ,
140
148
string . Format ( ScmSiteUriFormat , ScriptSettingsManager . Instance . GetSetting ( AzureWebsiteName ) ) ,
141
149
string . Format ( SiteUriFormat , ScriptSettingsManager . Instance . GetSetting ( AzureWebsiteName ) )
142
- } ;
150
+ ] ;
143
151
}
144
152
145
153
return result ;
0 commit comments