22// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
33
44using System ;
5+ using System . Collections . Generic ;
56using System . Linq ;
67using System . Security . Claims ;
78using System . Threading . Tasks ;
@@ -42,7 +43,7 @@ public async Task NoEndpoint_AnonymousUser_Allows()
4243 public async Task HasEndpointWithoutAuth_AnonymousUser_Allows ( )
4344 {
4445 // Arrange
45- var policy = new AuthorizationPolicyBuilder ( ) . RequireAssertion ( _ => true ) . Build ( ) ;
46+ var policy = new AuthorizationPolicyBuilder ( ) . RequireAuthenticatedUser ( ) . Build ( ) ;
4647 var policyProvider = new Mock < IAuthorizationPolicyProvider > ( ) ;
4748 policyProvider . Setup ( p => p . GetDefaultPolicyAsync ( ) ) . ReturnsAsync ( policy ) ;
4849 var next = new TestRequestDelegate ( ) ;
@@ -78,6 +79,27 @@ public async Task HasEndpointWithAuth_AnonymousUser_Challenges()
7879 Assert . True ( authenticationService . ChallengeCalled ) ;
7980 }
8081
82+ [ Fact ]
83+ public async Task HasEndpointWithAuth_AnonymousUser_ChallengePerScheme ( )
84+ {
85+ // Arrange
86+ var policy = new AuthorizationPolicyBuilder ( ) . RequireAuthenticatedUser ( ) . AddAuthenticationSchemes ( "schema1" , "schema2" ) . Build ( ) ;
87+ var policyProvider = new Mock < IAuthorizationPolicyProvider > ( ) ;
88+ policyProvider . Setup ( p => p . GetDefaultPolicyAsync ( ) ) . ReturnsAsync ( policy ) ;
89+ var next = new TestRequestDelegate ( ) ;
90+ var authenticationService = new TestAuthenticationService ( ) ;
91+
92+ var middleware = CreateMiddleware ( next . Invoke , policyProvider . Object ) ;
93+ var context = GetHttpContext ( anonymous : true , endpoint : CreateEndpoint ( new AuthorizeAttribute ( ) ) , authenticationService : authenticationService ) ;
94+
95+ // Act
96+ await middleware . Invoke ( context ) ;
97+
98+ // Assert
99+ Assert . False ( next . Called ) ;
100+ Assert . Equal ( 2 , authenticationService . ChallengeCount ) ;
101+ }
102+
81103 [ Fact ]
82104 public async Task OnAuthorizationAsync_WillCallPolicyProvider ( )
83105 {
@@ -255,6 +277,27 @@ public async Task Invoke_RequireUnknownRoleShouldForbid()
255277 Assert . True ( authenticationService . ForbidCalled ) ;
256278 }
257279
280+ [ Fact ]
281+ public async Task Invoke_RequireUnknownRole_ForbidPerScheme ( )
282+ {
283+ // Arrange
284+ var policy = new AuthorizationPolicyBuilder ( ) . RequireRole ( "Wut" ) . AddAuthenticationSchemes ( "Basic" , "Bearer" ) . Build ( ) ;
285+ var policyProvider = new Mock < IAuthorizationPolicyProvider > ( ) ;
286+ policyProvider . Setup ( p => p . GetDefaultPolicyAsync ( ) ) . ReturnsAsync ( policy ) ;
287+ var next = new TestRequestDelegate ( ) ;
288+ var authenticationService = new TestAuthenticationService ( ) ;
289+
290+ var middleware = CreateMiddleware ( next . Invoke , policyProvider . Object ) ;
291+ var context = GetHttpContext ( endpoint : CreateEndpoint ( new AuthorizeAttribute ( ) ) , authenticationService : authenticationService ) ;
292+
293+ // Act
294+ await middleware . Invoke ( context ) ;
295+
296+ // Assert
297+ Assert . False ( next . Called ) ;
298+ Assert . Equal ( 2 , authenticationService . ForbidCount ) ;
299+ }
300+
258301 [ Fact ]
259302 public async Task Invoke_InvalidClaimShouldForbid ( )
260303 {
@@ -315,8 +358,6 @@ private HttpContext GetHttpContext(
315358 new Claim ( ClaimTypes . NameIdentifier , "John Bear" ) } ,
316359 "Bearer" ) ;
317360
318- var bearerPrincipal = new ClaimsPrincipal ( bearerIdentity ) ;
319-
320361 validUser . AddIdentity ( bearerIdentity ) ;
321362
322363 // ServiceProvider
@@ -329,10 +370,7 @@ private HttpContext GetHttpContext(
329370 serviceCollection . AddLogging ( ) ;
330371 serviceCollection . AddAuthorization ( ) ;
331372 serviceCollection . AddAuthorizationPolicyEvaluator ( ) ;
332- if ( registerServices != null )
333- {
334- registerServices ( serviceCollection ) ;
335- }
373+ registerServices ? . Invoke ( serviceCollection ) ;
336374
337375 var serviceProvider = serviceCollection . BuildServiceProvider ( ) ;
338376
@@ -356,25 +394,36 @@ private HttpContext GetHttpContext(
356394
357395 private class TestAuthenticationService : IAuthenticationService
358396 {
359- public bool ChallengeCalled { get ; private set ; }
360- public bool ForbidCalled { get ; private set ; }
361- public bool AuthenticateCalled { get ; private set ; }
397+ public bool ChallengeCalled => ChallengeCount > 0 ;
398+ public bool ForbidCalled => ForbidCount > 0 ;
399+ public bool AuthenticateCalled => AuthenticateCount > 0 ;
400+
401+ public int ChallengeCount { get ; private set ; }
402+ public int ForbidCount { get ; private set ; }
403+ public int AuthenticateCount { get ; private set ; }
362404
363405 public Task < AuthenticateResult > AuthenticateAsync ( HttpContext context , string scheme )
364406 {
365- AuthenticateCalled = true ;
407+ AuthenticateCount ++ ;
408+
409+ var identity = context . User . Identities . SingleOrDefault ( i => i . AuthenticationType == scheme ) ;
410+ if ( identity != null )
411+ {
412+ return Task . FromResult ( AuthenticateResult . Success ( new AuthenticationTicket ( new ClaimsPrincipal ( identity ) , scheme ) ) ) ;
413+ }
414+
366415 return Task . FromResult ( AuthenticateResult . Fail ( "Denied" ) ) ;
367416 }
368417
369418 public Task ChallengeAsync ( HttpContext context , string scheme , AuthenticationProperties properties )
370419 {
371- ChallengeCalled = true ;
420+ ChallengeCount ++ ;
372421 return Task . CompletedTask ;
373422 }
374423
375424 public Task ForbidAsync ( HttpContext context , string scheme , AuthenticationProperties properties )
376425 {
377- ForbidCalled = true ;
426+ ForbidCount ++ ;
378427 return Task . CompletedTask ;
379428 }
380429
0 commit comments