@@ -13,8 +13,6 @@ namespace DarkLoop.Azure.Functions.Authorize.Filters
13
13
{
14
14
internal class FunctionsAuthorizeFilter : IFunctionsAuthorizeFilter
15
15
{
16
- private const string AuthInvokedKey = "__WebJobAuthInvoked" ;
17
-
18
16
public IEnumerable < IAuthorizeData > AuthorizeData { get ; }
19
17
20
18
public IAuthenticationSchemeProvider SchemeProvider { get ; }
@@ -23,99 +21,67 @@ internal class FunctionsAuthorizeFilter : IFunctionsAuthorizeFilter
23
21
24
22
public AuthorizationPolicy Policy { get ; }
25
23
26
- public FunctionsAuthorizeFilter ( IEnumerable < IAuthorizeData > authorizeData )
27
- {
28
- this . AuthorizeData = authorizeData ;
29
- }
30
-
31
24
public FunctionsAuthorizeFilter (
32
25
IAuthenticationSchemeProvider schemeProvider ,
33
26
IAuthorizationPolicyProvider policyProvider ,
34
27
IEnumerable < IAuthorizeData > authorizeData )
35
- : this ( authorizeData )
36
28
{
37
29
this . SchemeProvider = schemeProvider ;
38
30
this . PolicyProvider = policyProvider ;
39
- }
40
-
41
- public FunctionsAuthorizeFilter ( string policy )
42
- #pragma warning disable CS0618 // Type or member is obsolete
43
- : this ( new [ ] { new FunctionAuthorizeAttribute ( policy ) } ) { }
44
- #pragma warning restore CS0618 // Type or member is obsolete
31
+ this . AuthorizeData = authorizeData ;
45
32
46
- public async Task AuthorizeAsync ( FunctionAuthorizationContext context )
33
+ this . IntegrateSchemes ( ) ;
34
+ this . Policy = this . ComputePolicyAsync ( ) . GetAwaiter ( ) . GetResult ( ) ;
35
+ }
36
+
37
+ private void IntegrateSchemes ( )
47
38
{
48
- if ( context is null ) throw new ArgumentNullException ( nameof ( context ) ) ;
39
+ var schemes = this . SchemeProvider . GetAllSchemesAsync ( ) . GetAwaiter ( ) . GetResult ( ) ;
40
+ var strSchemes = string . Join ( ',' ,
41
+ from scheme in schemes
42
+ where scheme . Name != Constants . WebJobsAuthScheme
43
+ select scheme . Name ) ;
49
44
50
- if ( context . HttpContext . Items . ContainsKey ( AuthInvokedKey ) )
45
+ foreach ( var data in this . AuthorizeData )
51
46
{
52
- return ;
47
+ // only setting auth schemes if they have not been specified already
48
+ if ( string . IsNullOrWhiteSpace ( data . AuthenticationSchemes ) )
49
+ {
50
+ data . AuthenticationSchemes = strSchemes ;
51
+ }
53
52
}
53
+ }
54
54
55
- var effectivePolicy = await this . ComputePolicyAsync ( ) ;
55
+ public async Task AuthorizeAsync ( FunctionAuthorizationContext context )
56
+ {
57
+ if ( context is null ) throw new ArgumentNullException ( nameof ( context ) ) ;
56
58
57
- if ( effectivePolicy is null )
59
+ if ( context . HttpContext . Items . ContainsKey ( Constants . AuthInvokedKey ) )
58
60
{
59
61
return ;
60
62
}
61
63
62
64
var httpContext = context . HttpContext ;
63
- await this . AuthenticateRequestAsync ( context ) ;
64
65
var evaluator = httpContext . RequestServices . GetRequiredService < IPolicyEvaluator > ( ) ;
65
- var authenticateResult = await evaluator . AuthenticateAsync ( effectivePolicy , context . HttpContext ) ;
66
- var authorizeResult = await evaluator . AuthorizeAsync ( effectivePolicy , authenticateResult , context . HttpContext , context ) ;
66
+ var authenticateResult = await evaluator . AuthenticateAsync ( this . Policy , httpContext ) ;
67
+ var authorizeResult = await evaluator . AuthorizeAsync ( this . Policy , authenticateResult , httpContext , context ) ;
67
68
68
69
if ( authorizeResult . Challenged )
69
70
{
70
- context . Result = new ChallengeResult ( effectivePolicy . AuthenticationSchemes . ToArray ( ) ) ;
71
+ context . Result = new ChallengeResult ( this . Policy . AuthenticationSchemes . ToArray ( ) ) ;
71
72
}
72
73
else if ( authorizeResult . Forbidden )
73
74
{
74
- context . Result = new ForbidResult ( effectivePolicy . AuthenticationSchemes . ToArray ( ) ) ;
75
+ context . Result = new ForbidResult ( this . Policy . AuthenticationSchemes . ToArray ( ) ) ;
75
76
}
76
-
77
- }
78
-
79
- private async Task < AuthenticateResult > AuthenticateRequestAsync ( FunctionAuthorizationContext context )
80
- {
81
- var httpContext = context . HttpContext ;
82
- var handlers = httpContext . RequestServices . GetService < IAuthenticationHandlerProvider > ( ) ;
83
-
84
- foreach ( var scheme in await this . SchemeProvider . GetRequestHandlerSchemesAsync ( ) )
77
+ else if ( ! authorizeResult . Succeeded )
85
78
{
86
- var handler = await handlers . GetHandlerAsync ( httpContext , scheme . Name ) as IAuthenticationRequestHandler ;
87
- if ( handler != null )
88
- {
89
- var result = await handler . AuthenticateAsync ( ) ;
90
- if ( result . Succeeded )
91
- {
92
- httpContext . User = result . Principal ;
93
- return result ;
94
- }
95
- }
79
+ context . Result = new UnauthorizedResult ( ) ;
96
80
}
97
-
98
- var defaultAuthenticate = await this . SchemeProvider . GetDefaultAuthenticateSchemeAsync ( ) ;
99
- if ( defaultAuthenticate != null )
100
- {
101
- var result = await httpContext . AuthenticateAsync ( defaultAuthenticate . Name ) ;
102
- if ( result ? . Principal != null )
103
- {
104
- httpContext . User = result . Principal ;
105
- return result ;
106
- }
107
- }
108
-
109
- return AuthenticateResult . NoResult ( ) ;
110
81
}
111
82
112
83
private Task < AuthorizationPolicy > ComputePolicyAsync ( )
113
84
{
114
- if ( this . Policy != null )
115
- {
116
- return Task . FromResult ( this . Policy ) ;
117
- }
118
-
119
85
if ( this . PolicyProvider == null )
120
86
{
121
87
throw new InvalidOperationException ( "Policy cannot be created." ) ;
0 commit comments