14
14
15
15
namespace Microsoft . Azure . WebJobs . Script . WebHost . Filters
16
16
{
17
- public sealed class AuthorizationLevelAttribute : AuthorizationFilterAttribute
17
+ [ AttributeUsage ( AttributeTargets . Class | AttributeTargets . Method , Inherited = true , AllowMultiple = true ) ]
18
+ public class AuthorizationLevelAttribute : AuthorizationFilterAttribute
18
19
{
19
20
public const string FunctionsKeyHeaderName = "x-functions-key" ;
20
21
21
- public AuthorizationLevelAttribute ( AuthorizationLevel level , string keyName = null )
22
+ public AuthorizationLevelAttribute ( AuthorizationLevel level )
22
23
{
23
24
Level = level ;
24
- KeyName = keyName ;
25
25
}
26
26
27
27
public AuthorizationLevel Level { get ; }
28
28
29
- public string KeyName { get ; }
30
-
31
29
public async override Task OnAuthorizationAsync ( HttpActionContext actionContext , CancellationToken cancellationToken )
32
30
{
33
31
if ( actionContext == null )
@@ -39,7 +37,7 @@ public async override Task OnAuthorizationAsync(HttpActionContext actionContext,
39
37
// as a request property
40
38
var secretManager = actionContext . ControllerContext . Configuration . DependencyResolver . GetService < ISecretManager > ( ) ;
41
39
var settings = actionContext . ControllerContext . Configuration . DependencyResolver . GetService < WebHostSettings > ( ) ;
42
- var requestAuthorizationLevel = await GetAuthorizationLevelAsync ( actionContext . Request , secretManager , keyName : KeyName ) ;
40
+ var requestAuthorizationLevel = await GetAuthorizationLevelAsync ( actionContext . Request , secretManager , EvaluateKeyMatch ) ;
43
41
actionContext . Request . Properties [ ScriptConstants . AzureFunctionsHttpRequestAuthorizationLevel ] = requestAuthorizationLevel ;
44
42
45
43
if ( settings . IsAuthDisabled ||
@@ -55,7 +53,15 @@ public async override Task OnAuthorizationAsync(HttpActionContext actionContext,
55
53
}
56
54
}
57
55
58
- internal static async Task < AuthorizationLevel > GetAuthorizationLevelAsync ( HttpRequestMessage request , ISecretManager secretManager , string functionName = null , string keyName = null )
56
+ protected virtual bool EvaluateKeyMatch ( IDictionary < string , string > secrets , string keyValue ) => HasMatchingKey ( secrets , keyValue ) ;
57
+
58
+ internal static Task < AuthorizationLevel > GetAuthorizationLevelAsync ( HttpRequestMessage request , ISecretManager secretManager , string functionName = null )
59
+ {
60
+ return GetAuthorizationLevelAsync ( request , secretManager , HasMatchingKey , functionName ) ;
61
+ }
62
+
63
+ internal static async Task < AuthorizationLevel > GetAuthorizationLevelAsync ( HttpRequestMessage request , ISecretManager secretManager ,
64
+ Func < IDictionary < string , string > , string , bool > matchEvaluator , string functionName = null )
59
65
{
60
66
// first see if a key value is specified via headers or query string (header takes precedence)
61
67
IEnumerable < string > values ;
@@ -80,13 +86,13 @@ internal static async Task<AuthorizationLevel> GetAuthorizationLevelAsync(HttpRe
80
86
return AuthorizationLevel . Admin ;
81
87
}
82
88
83
- if ( HasMatchingKey ( hostSecrets . SystemKeys , keyValue , keyName ) )
89
+ if ( matchEvaluator ( hostSecrets . SystemKeys , keyValue ) )
84
90
{
85
91
return AuthorizationLevel . System ;
86
92
}
87
93
88
94
// see if the key specified matches the host function key
89
- if ( HasMatchingKey ( hostSecrets . FunctionKeys , keyValue , keyName ) )
95
+ if ( matchEvaluator ( hostSecrets . FunctionKeys , keyValue ) )
90
96
{
91
97
return AuthorizationLevel . Function ;
92
98
}
@@ -95,7 +101,7 @@ internal static async Task<AuthorizationLevel> GetAuthorizationLevelAsync(HttpRe
95
101
if ( functionName != null )
96
102
{
97
103
IDictionary < string , string > functionSecrets = await secretManager . GetFunctionSecretsAsync ( functionName ) ;
98
- if ( HasMatchingKey ( functionSecrets , keyValue , keyName ) )
104
+ if ( matchEvaluator ( functionSecrets , keyValue ) )
99
105
{
100
106
return AuthorizationLevel . Function ;
101
107
}
@@ -105,9 +111,8 @@ internal static async Task<AuthorizationLevel> GetAuthorizationLevelAsync(HttpRe
105
111
return AuthorizationLevel . Anonymous ;
106
112
}
107
113
108
- private static bool HasMatchingKey ( IDictionary < string , string > secrets , string keyValue , string keyName )
109
- => secrets != null &&
110
- secrets . Any ( kvp => ( keyName == null || string . Equals ( kvp . Key , keyName , StringComparison . OrdinalIgnoreCase ) ) && Key . SecretValueEquals ( kvp . Value , keyValue ) ) ;
114
+ private static bool HasMatchingKey ( IDictionary < string , string > secrets , string keyValue )
115
+ => secrets != null && secrets . Values . Any ( s => Key . SecretValueEquals ( s , keyValue ) ) ;
111
116
112
117
internal static bool SkipAuthorization ( HttpActionContext actionContext )
113
118
{
0 commit comments