3
3
4
4
using System ;
5
5
using System . Collections . Generic ;
6
+ using System . Linq ;
6
7
using System . Threading . Tasks ;
7
8
using Microsoft . AspNetCore . Http ;
8
9
using Microsoft . Extensions . Options ;
@@ -49,6 +50,9 @@ protected AuthenticationSchemeProvider(IOptions<AuthenticationOptions> options,
49
50
50
51
private readonly IDictionary < string , AuthenticationScheme > _schemes ;
51
52
private readonly List < AuthenticationScheme > _requestHandlers ;
53
+ // Used as a safe return value for enumeration apis
54
+ private IEnumerable < AuthenticationScheme > _schemesCopy = Array . Empty < AuthenticationScheme > ( ) ;
55
+ private IEnumerable < AuthenticationScheme > _requestHandlersCopy = Array . Empty < AuthenticationScheme > ( ) ;
52
56
53
57
private Task < AuthenticationScheme > GetDefaultSchemeAsync ( )
54
58
=> _options . DefaultScheme != null
@@ -123,7 +127,7 @@ public virtual Task<AuthenticationScheme> GetSchemeAsync(string name)
123
127
/// </summary>
124
128
/// <returns>The schemes in priority order for request handling</returns>
125
129
public virtual Task < IEnumerable < AuthenticationScheme > > GetRequestHandlerSchemesAsync ( )
126
- => Task . FromResult < IEnumerable < AuthenticationScheme > > ( _requestHandlers ) ;
130
+ => Task . FromResult ( _requestHandlersCopy ) ;
127
131
128
132
/// <summary>
129
133
/// Registers a scheme for use by <see cref="IAuthenticationService"/>.
@@ -144,8 +148,10 @@ public virtual void AddScheme(AuthenticationScheme scheme)
144
148
if ( typeof ( IAuthenticationRequestHandler ) . IsAssignableFrom ( scheme . HandlerType ) )
145
149
{
146
150
_requestHandlers . Add ( scheme ) ;
151
+ _requestHandlersCopy = _requestHandlers . ToArray ( ) ;
147
152
}
148
153
_schemes [ scheme . Name ] = scheme ;
154
+ _schemesCopy = _schemes . Values . ToArray ( ) ;
149
155
}
150
156
}
151
157
@@ -164,13 +170,17 @@ public virtual void RemoveScheme(string name)
164
170
if ( _schemes . ContainsKey ( name ) )
165
171
{
166
172
var scheme = _schemes [ name ] ;
167
- _requestHandlers . Remove ( scheme ) ;
173
+ if ( _requestHandlers . Remove ( scheme ) )
174
+ {
175
+ _requestHandlersCopy = _requestHandlers . ToArray ( ) ;
176
+ }
168
177
_schemes . Remove ( name ) ;
178
+ _schemesCopy = _schemes . Values . ToArray ( ) ;
169
179
}
170
180
}
171
181
}
172
182
173
183
public virtual Task < IEnumerable < AuthenticationScheme > > GetAllSchemesAsync ( )
174
- => Task . FromResult < IEnumerable < AuthenticationScheme > > ( _schemes . Values ) ;
184
+ => Task . FromResult ( _schemesCopy ) ;
175
185
}
176
186
}
0 commit comments