33using System ;
44using System . Security . Claims ;
55using System . Threading . Tasks ;
6+ using Microsoft . AspNetCore . Authentication . JwtBearer ;
67using Microsoft . AspNetCore . Builder ;
78using Microsoft . AspNetCore . Hosting ;
89using Microsoft . AspNetCore . Http ;
910using Microsoft . AspNetCore . TestHost ;
1011using Microsoft . Extensions . DependencyInjection ;
1112using Microsoft . Extensions . Hosting ;
13+ using Microsoft . Extensions . Logging ;
14+ using Moq ;
1215using Xunit ;
1316
1417namespace Microsoft . AspNetCore . Authentication
@@ -54,6 +57,126 @@ public async Task OnlyInvokesCanHandleRequestHandlers()
5457 Assert . Equal ( 607 , ( int ) response . StatusCode ) ;
5558 }
5659
60+ [ Fact ]
61+ public async Task IAuthenticateResultFeature_SetOnSuccessfulAuthenticate ( )
62+ {
63+ var authenticationService = new Mock < IAuthenticationService > ( ) ;
64+ authenticationService . Setup ( s => s . AuthenticateAsync ( It . IsAny < HttpContext > ( ) , It . IsAny < string > ( ) ) )
65+ . Returns ( Task . FromResult ( AuthenticateResult . Success ( new AuthenticationTicket ( new ClaimsPrincipal ( ) , "custom" ) ) ) ) ;
66+ var schemeProvider = new Mock < IAuthenticationSchemeProvider > ( ) ;
67+ schemeProvider . Setup ( p => p . GetDefaultAuthenticateSchemeAsync ( ) )
68+ . Returns ( Task . FromResult ( new AuthenticationScheme ( "custom" , "custom" , typeof ( JwtBearerHandler ) ) ) ) ;
69+ var middleware = new AuthenticationMiddleware ( c => Task . CompletedTask , schemeProvider . Object ) ;
70+ var context = GetHttpContext ( authenticationService : authenticationService . Object ) ;
71+
72+ // Act
73+ await middleware . Invoke ( context ) ;
74+
75+ // Assert
76+ var authenticateResultFeature = context . Features . Get < IAuthenticateResultFeature > ( ) ;
77+ Assert . NotNull ( authenticateResultFeature ) ;
78+ Assert . NotNull ( authenticateResultFeature . AuthenticateResult ) ;
79+ Assert . True ( authenticateResultFeature . AuthenticateResult . Succeeded ) ;
80+ Assert . Same ( context . User , authenticateResultFeature . AuthenticateResult . Principal ) ;
81+ }
82+
83+ [ Fact ]
84+ public async Task IAuthenticateResultFeature_NotSetOnUnsuccessfulAuthenticate ( )
85+ {
86+ var authenticationService = new Mock < IAuthenticationService > ( ) ;
87+ authenticationService . Setup ( s => s . AuthenticateAsync ( It . IsAny < HttpContext > ( ) , It . IsAny < string > ( ) ) )
88+ . Returns ( Task . FromResult ( AuthenticateResult . Fail ( "not authenticated" ) ) ) ;
89+ var schemeProvider = new Mock < IAuthenticationSchemeProvider > ( ) ;
90+ schemeProvider . Setup ( p => p . GetDefaultAuthenticateSchemeAsync ( ) )
91+ . Returns ( Task . FromResult ( new AuthenticationScheme ( "custom" , "custom" , typeof ( JwtBearerHandler ) ) ) ) ;
92+ var middleware = new AuthenticationMiddleware ( c => Task . CompletedTask , schemeProvider . Object ) ;
93+ var context = GetHttpContext ( authenticationService : authenticationService . Object ) ;
94+
95+ // Act
96+ await middleware . Invoke ( context ) ;
97+
98+ // Assert
99+ var authenticateResultFeature = context . Features . Get < IAuthenticateResultFeature > ( ) ;
100+ Assert . Null ( authenticateResultFeature ) ;
101+ }
102+
103+ [ Fact ]
104+ public async Task IAuthenticateResultFeature_NullResultWhenUserSetAfter ( )
105+ {
106+ var authenticationService = new Mock < IAuthenticationService > ( ) ;
107+ authenticationService . Setup ( s => s . AuthenticateAsync ( It . IsAny < HttpContext > ( ) , It . IsAny < string > ( ) ) )
108+ . Returns ( Task . FromResult ( AuthenticateResult . Success ( new AuthenticationTicket ( new ClaimsPrincipal ( ) , "custom" ) ) ) ) ;
109+ var schemeProvider = new Mock < IAuthenticationSchemeProvider > ( ) ;
110+ schemeProvider . Setup ( p => p . GetDefaultAuthenticateSchemeAsync ( ) )
111+ . Returns ( Task . FromResult ( new AuthenticationScheme ( "custom" , "custom" , typeof ( JwtBearerHandler ) ) ) ) ;
112+ var middleware = new AuthenticationMiddleware ( c => Task . CompletedTask , schemeProvider . Object ) ;
113+ var context = GetHttpContext ( authenticationService : authenticationService . Object ) ;
114+
115+ // Act
116+ await middleware . Invoke ( context ) ;
117+
118+ // Assert
119+ var authenticateResultFeature = context . Features . Get < IAuthenticateResultFeature > ( ) ;
120+ Assert . NotNull ( authenticateResultFeature ) ;
121+ Assert . NotNull ( authenticateResultFeature . AuthenticateResult ) ;
122+ Assert . True ( authenticateResultFeature . AuthenticateResult . Succeeded ) ;
123+ Assert . Same ( context . User , authenticateResultFeature . AuthenticateResult . Principal ) ;
124+
125+ context . User = new ClaimsPrincipal ( ) ;
126+ Assert . Null ( authenticateResultFeature . AuthenticateResult ) ;
127+ }
128+
129+ [ Fact ]
130+ public async Task IAuthenticateResultFeature_SettingResultSetsUser ( )
131+ {
132+ var authenticationService = new Mock < IAuthenticationService > ( ) ;
133+ authenticationService . Setup ( s => s . AuthenticateAsync ( It . IsAny < HttpContext > ( ) , It . IsAny < string > ( ) ) )
134+ . Returns ( Task . FromResult ( AuthenticateResult . Success ( new AuthenticationTicket ( new ClaimsPrincipal ( ) , "custom" ) ) ) ) ;
135+ var schemeProvider = new Mock < IAuthenticationSchemeProvider > ( ) ;
136+ schemeProvider . Setup ( p => p . GetDefaultAuthenticateSchemeAsync ( ) )
137+ . Returns ( Task . FromResult ( new AuthenticationScheme ( "custom" , "custom" , typeof ( JwtBearerHandler ) ) ) ) ;
138+ var middleware = new AuthenticationMiddleware ( c => Task . CompletedTask , schemeProvider . Object ) ;
139+ var context = GetHttpContext ( authenticationService : authenticationService . Object ) ;
140+
141+ // Act
142+ await middleware . Invoke ( context ) ;
143+
144+ // Assert
145+ var authenticateResultFeature = context . Features . Get < IAuthenticateResultFeature > ( ) ;
146+ Assert . NotNull ( authenticateResultFeature ) ;
147+ Assert . NotNull ( authenticateResultFeature . AuthenticateResult ) ;
148+ Assert . True ( authenticateResultFeature . AuthenticateResult . Succeeded ) ;
149+ Assert . Same ( context . User , authenticateResultFeature . AuthenticateResult . Principal ) ;
150+
151+ var newTicket = new AuthenticationTicket ( new ClaimsPrincipal ( ) , "" ) ;
152+ authenticateResultFeature . AuthenticateResult = AuthenticateResult . Success ( newTicket ) ;
153+ Assert . Same ( context . User , newTicket . Principal ) ;
154+ }
155+
156+ private HttpContext GetHttpContext (
157+ Action < IServiceCollection > registerServices = null ,
158+ IAuthenticationService authenticationService = null )
159+ {
160+ // ServiceProvider
161+ var serviceCollection = new ServiceCollection ( ) ;
162+
163+ authenticationService = authenticationService ?? Mock . Of < IAuthenticationService > ( ) ;
164+
165+ serviceCollection . AddSingleton ( authenticationService ) ;
166+ serviceCollection . AddOptions ( ) ;
167+ serviceCollection . AddLogging ( ) ;
168+ serviceCollection . AddAuthentication ( ) ;
169+ registerServices ? . Invoke ( serviceCollection ) ;
170+
171+ var serviceProvider = serviceCollection . BuildServiceProvider ( ) ;
172+
173+ //// HttpContext
174+ var httpContext = new DefaultHttpContext ( ) ;
175+ httpContext . RequestServices = serviceProvider ;
176+
177+ return httpContext ;
178+ }
179+
57180 private class ThreeOhFiveHandler : StatusCodeHandler {
58181 public ThreeOhFiveHandler ( ) : base ( 305 ) { }
59182 }
@@ -77,7 +200,7 @@ public StatusCodeHandler(int code)
77200 {
78201 _code = code ;
79202 }
80-
203+
81204 public Task < AuthenticateResult > AuthenticateAsync ( )
82205 {
83206 throw new NotImplementedException ( ) ;
0 commit comments