Skip to content

Commit f813201

Browse files
committed
Merge branch '6.4.x'
TestOneTimeTokenGenerationSuccessHandler.lastToken to non-static variable Closes gh-16472
2 parents 09b6e4c + 751b558 commit f813201

File tree

2 files changed

+76
-28
lines changed

2 files changed

+76
-28
lines changed

config/src/test/java/org/springframework/security/config/annotation/web/configurers/ott/OneTimeTokenLoginConfigurerTests.java

+44-14
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ void oneTimeTokenWhenCorrectTokenThenCanAuthenticate() throws Exception {
7878
this.mvc.perform(post("/ott/generate").param("username", "user").with(csrf()))
7979
.andExpectAll(status().isFound(), redirectedUrl("/login/ott"));
8080

81-
String token = TestOneTimeTokenGenerationSuccessHandler.lastToken.getTokenValue();
81+
String token = getLastToken().getTokenValue();
8282

8383
this.mvc.perform(post("/login/ott").param("token", token).with(csrf()))
8484
.andExpectAll(status().isFound(), redirectedUrl("/"), authenticated());
@@ -90,7 +90,7 @@ void oneTimeTokenWhenDifferentAuthenticationUrlsThenCanAuthenticate() throws Exc
9090
this.mvc.perform(post("/generateurl").param("username", "user").with(csrf()))
9191
.andExpectAll(status().isFound(), redirectedUrl("/redirected"));
9292

93-
String token = TestOneTimeTokenGenerationSuccessHandler.lastToken.getTokenValue();
93+
String token = getLastToken().getTokenValue();
9494

9595
this.mvc.perform(post("/loginprocessingurl").param("token", token).with(csrf()))
9696
.andExpectAll(status().isFound(), redirectedUrl("/authenticated"), authenticated());
@@ -102,7 +102,7 @@ void oneTimeTokenWhenCorrectTokenUsedTwiceThenSecondTimeFails() throws Exception
102102
this.mvc.perform(post("/ott/generate").param("username", "user").with(csrf()))
103103
.andExpectAll(status().isFound(), redirectedUrl("/login/ott"));
104104

105-
String token = TestOneTimeTokenGenerationSuccessHandler.lastToken.getTokenValue();
105+
String token = getLastToken().getTokenValue();
106106

107107
this.mvc.perform(post("/login/ott").param("token", token).with(csrf()))
108108
.andExpectAll(status().isFound(), redirectedUrl("/"), authenticated());
@@ -206,7 +206,7 @@ void oneTimeTokenWhenCustomTokenExpirationTimeSetThenAuthenticate() throws Excep
206206
this.mvc.perform(post("/ott/generate").param("username", "user").with(csrf()))
207207
.andExpectAll(status().isFound(), redirectedUrl("/login/ott"));
208208

209-
OneTimeToken token = TestOneTimeTokenGenerationSuccessHandler.lastToken;
209+
OneTimeToken token = getLastToken();
210210

211211
this.mvc.perform(post("/login/ott").param("token", token.getTokenValue()).with(csrf()))
212212
.andExpectAll(status().isFound(), redirectedUrl("/"), authenticated());
@@ -219,25 +219,37 @@ private int getCurrentMinutes(Instant expiresAt) {
219219
return expiresMinutes - currentMinutes;
220220
}
221221

222+
private OneTimeToken getLastToken() {
223+
OneTimeToken lastToken = this.spring.getContext()
224+
.getBean(TestOneTimeTokenGenerationSuccessHandler.class).lastToken;
225+
return lastToken;
226+
}
227+
222228
@Configuration(proxyBeanMethods = false)
223229
@EnableWebSecurity
224230
@Import(UserDetailsServiceConfig.class)
225231
static class OneTimeTokenConfigWithCustomTokenExpirationTime {
226232

227233
@Bean
228-
SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
234+
SecurityFilterChain securityFilterChain(HttpSecurity http,
235+
OneTimeTokenGenerationSuccessHandler ottSuccessHandler) throws Exception {
229236
// @formatter:off
230237
http
231238
.authorizeHttpRequests((authz) -> authz
232239
.anyRequest().authenticated()
233240
)
234241
.oneTimeTokenLogin((ott) -> ott
235-
.tokenGenerationSuccessHandler(new TestOneTimeTokenGenerationSuccessHandler())
242+
.tokenGenerationSuccessHandler(ottSuccessHandler)
236243
);
237244
// @formatter:on
238245
return http.build();
239246
}
240247

248+
@Bean
249+
TestOneTimeTokenGenerationSuccessHandler ottSuccessHandler() {
250+
return new TestOneTimeTokenGenerationSuccessHandler();
251+
}
252+
241253
@Bean
242254
GenerateOneTimeTokenRequestResolver generateOneTimeTokenRequestResolver() {
243255
DefaultGenerateOneTimeTokenRequestResolver delegate = new DefaultGenerateOneTimeTokenRequestResolver();
@@ -255,19 +267,25 @@ GenerateOneTimeTokenRequestResolver generateOneTimeTokenRequestResolver() {
255267
static class OneTimeTokenDefaultConfig {
256268

257269
@Bean
258-
SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
270+
SecurityFilterChain securityFilterChain(HttpSecurity http,
271+
OneTimeTokenGenerationSuccessHandler ottSuccessHandler) throws Exception {
259272
// @formatter:off
260273
http
261274
.authorizeHttpRequests((authz) -> authz
262275
.anyRequest().authenticated()
263276
)
264277
.oneTimeTokenLogin((ott) -> ott
265-
.tokenGenerationSuccessHandler(new TestOneTimeTokenGenerationSuccessHandler())
278+
.tokenGenerationSuccessHandler(ottSuccessHandler)
266279
);
267280
// @formatter:on
268281
return http.build();
269282
}
270283

284+
@Bean
285+
TestOneTimeTokenGenerationSuccessHandler ottSuccessHandler() {
286+
return new TestOneTimeTokenGenerationSuccessHandler();
287+
}
288+
271289
}
272290

273291
@Configuration(proxyBeanMethods = false)
@@ -276,22 +294,28 @@ SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
276294
static class OneTimeTokenDifferentUrlsConfig {
277295

278296
@Bean
279-
SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
297+
SecurityFilterChain securityFilterChain(HttpSecurity http,
298+
OneTimeTokenGenerationSuccessHandler ottSuccessHandler) throws Exception {
280299
// @formatter:off
281300
http
282301
.authorizeHttpRequests((authz) -> authz
283302
.anyRequest().authenticated()
284303
)
285304
.oneTimeTokenLogin((ott) -> ott
286305
.tokenGeneratingUrl("/generateurl")
287-
.tokenGenerationSuccessHandler(new TestOneTimeTokenGenerationSuccessHandler("/redirected"))
306+
.tokenGenerationSuccessHandler(ottSuccessHandler)
288307
.loginProcessingUrl("/loginprocessingurl")
289308
.authenticationSuccessHandler(new SimpleUrlAuthenticationSuccessHandler("/authenticated"))
290309
);
291310
// @formatter:on
292311
return http.build();
293312
}
294313

314+
@Bean
315+
TestOneTimeTokenGenerationSuccessHandler ottSuccessHandler() {
316+
return new TestOneTimeTokenGenerationSuccessHandler("/redirected");
317+
}
318+
295319
}
296320

297321
@Configuration(proxyBeanMethods = false)
@@ -300,20 +324,26 @@ SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
300324
static class OneTimeTokenFormLoginConfig {
301325

302326
@Bean
303-
SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
327+
SecurityFilterChain securityFilterChain(HttpSecurity http,
328+
OneTimeTokenGenerationSuccessHandler ottSuccessHandler) throws Exception {
304329
// @formatter:off
305330
http
306331
.authorizeHttpRequests((authz) -> authz
307332
.anyRequest().authenticated()
308333
)
309334
.formLogin(Customizer.withDefaults())
310335
.oneTimeTokenLogin((ott) -> ott
311-
.tokenGenerationSuccessHandler(new TestOneTimeTokenGenerationSuccessHandler())
336+
.tokenGenerationSuccessHandler(ottSuccessHandler)
312337
);
313338
// @formatter:on
314339
return http.build();
315340
}
316341

342+
@Bean
343+
TestOneTimeTokenGenerationSuccessHandler ottSuccessHandler() {
344+
return new TestOneTimeTokenGenerationSuccessHandler();
345+
}
346+
317347
}
318348

319349
@Configuration(proxyBeanMethods = false)
@@ -337,7 +367,7 @@ SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
337367

338368
static class TestOneTimeTokenGenerationSuccessHandler implements OneTimeTokenGenerationSuccessHandler {
339369

340-
private static OneTimeToken lastToken;
370+
private OneTimeToken lastToken;
341371

342372
private final OneTimeTokenGenerationSuccessHandler delegate;
343373

@@ -352,7 +382,7 @@ static class TestOneTimeTokenGenerationSuccessHandler implements OneTimeTokenGen
352382
@Override
353383
public void handle(HttpServletRequest request, HttpServletResponse response, OneTimeToken oneTimeToken)
354384
throws IOException, ServletException {
355-
lastToken = oneTimeToken;
385+
this.lastToken = oneTimeToken;
356386
this.delegate.handle(request, response, oneTimeToken);
357387
}
358388

config/src/test/kotlin/org/springframework/security/config/annotation/web/OneTimeTokenLoginDslTests.kt

+32-14
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ class OneTimeTokenLoginDslTests {
7474
.redirectedUrl("/login/ott")
7575
)
7676

77-
val token = TestOneTimeTokenGenerationSuccessHandler.lastToken?.tokenValue
77+
val token = getLastToken().tokenValue
7878

7979
this.mockMvc.perform(
8080
MockMvcRequestBuilders.post("/login/ott").param("token", token)
@@ -96,7 +96,7 @@ class OneTimeTokenLoginDslTests {
9696
)
9797
.andExpectAll(MockMvcResultMatchers.status().isFound(), MockMvcResultMatchers.redirectedUrl("/redirected"))
9898

99-
val token = TestOneTimeTokenGenerationSuccessHandler.lastToken?.tokenValue
99+
val token = getLastToken().tokenValue
100100

101101
this.mockMvc.perform(
102102
MockMvcRequestBuilders.post("/loginprocessingurl").param("token", token)
@@ -124,7 +124,7 @@ class OneTimeTokenLoginDslTests {
124124
.redirectedUrl("/login/ott")
125125
)
126126

127-
val token = TestOneTimeTokenGenerationSuccessHandler.lastToken
127+
val token = getLastToken()
128128

129129
assertThat(getCurrentMinutes(token!!.expiresAt)).isEqualTo(10)
130130
}
@@ -135,25 +135,36 @@ class OneTimeTokenLoginDslTests {
135135
return expiresMinutes - currentMinutes
136136
}
137137

138+
private fun getLastToken(): OneTimeToken {
139+
val lastToken = spring.context
140+
.getBean(TestOneTimeTokenGenerationSuccessHandler::class.java).lastToken
141+
return lastToken!!
142+
}
143+
138144
@Configuration
139145
@EnableWebSecurity
140146
@Import(UserDetailsServiceConfig::class)
141147
open class OneTimeTokenConfig {
142148

143149
@Bean
144-
open fun securityFilterChain(http: HttpSecurity): SecurityFilterChain {
150+
open fun securityFilterChain(http: HttpSecurity, ottSuccessHandler: OneTimeTokenGenerationSuccessHandler): SecurityFilterChain {
145151
// @formatter:off
146152
http {
147153
authorizeHttpRequests {
148154
authorize(anyRequest, authenticated)
149155
}
150156
oneTimeTokenLogin {
151-
oneTimeTokenGenerationSuccessHandler = TestOneTimeTokenGenerationSuccessHandler()
157+
oneTimeTokenGenerationSuccessHandler = ottSuccessHandler
152158
}
153159
}
154160
// @formatter:on
155161
return http.build()
156162
}
163+
164+
@Bean
165+
open fun ottSuccessHandler(): TestOneTimeTokenGenerationSuccessHandler {
166+
return TestOneTimeTokenGenerationSuccessHandler()
167+
}
157168
}
158169

159170
@Configuration
@@ -162,14 +173,14 @@ class OneTimeTokenLoginDslTests {
162173
open class OneTimeTokenConfigWithCustomTokenResolver {
163174

164175
@Bean
165-
open fun securityFilterChain(http: HttpSecurity): SecurityFilterChain {
176+
open fun securityFilterChain(http: HttpSecurity, ottSuccessHandler: OneTimeTokenGenerationSuccessHandler): SecurityFilterChain {
166177
// @formatter:off
167178
http {
168179
authorizeHttpRequests {
169180
authorize(anyRequest, authenticated)
170181
}
171182
oneTimeTokenLogin {
172-
oneTimeTokenGenerationSuccessHandler = TestOneTimeTokenGenerationSuccessHandler()
183+
oneTimeTokenGenerationSuccessHandler = ottSuccessHandler
173184
generateRequestResolver = DefaultGenerateOneTimeTokenRequestResolver().apply {
174185
this.setExpiresIn(Duration.ofMinutes(10))
175186
}
@@ -179,6 +190,10 @@ class OneTimeTokenLoginDslTests {
179190
return http.build()
180191
}
181192

193+
@Bean
194+
open fun ottSuccessHandler(): TestOneTimeTokenGenerationSuccessHandler {
195+
return TestOneTimeTokenGenerationSuccessHandler()
196+
}
182197

183198
}
184199

@@ -187,22 +202,27 @@ class OneTimeTokenLoginDslTests {
187202
@Import(UserDetailsServiceConfig::class)
188203
open class OneTimeTokenDifferentUrlsConfig {
189204
@Bean
190-
open fun securityFilterChain(http: HttpSecurity): SecurityFilterChain {
205+
open fun securityFilterChain(http: HttpSecurity, ottSuccessHandler: OneTimeTokenGenerationSuccessHandler): SecurityFilterChain {
191206
// @formatter:off
192207
http {
193208
authorizeHttpRequests {
194209
authorize(anyRequest, authenticated)
195210
}
196211
oneTimeTokenLogin {
197212
tokenGeneratingUrl = "/generateurl"
198-
oneTimeTokenGenerationSuccessHandler = TestOneTimeTokenGenerationSuccessHandler("/redirected")
213+
oneTimeTokenGenerationSuccessHandler = ottSuccessHandler
199214
loginProcessingUrl = "/loginprocessingurl"
200215
authenticationSuccessHandler = SimpleUrlAuthenticationSuccessHandler("/authenticated")
201216
}
202217
}
203218
// @formatter:on
204219
return http.build()
205220
}
221+
222+
@Bean
223+
open fun ottSuccessHandler(): TestOneTimeTokenGenerationSuccessHandler {
224+
return TestOneTimeTokenGenerationSuccessHandler("/redirected")
225+
}
206226
}
207227

208228
@Configuration(proxyBeanMethods = false)
@@ -213,9 +233,10 @@ class OneTimeTokenLoginDslTests {
213233
InMemoryUserDetailsManager(PasswordEncodedUser.user(), PasswordEncodedUser.admin())
214234
}
215235

216-
private class TestOneTimeTokenGenerationSuccessHandler :
236+
class TestOneTimeTokenGenerationSuccessHandler :
217237
OneTimeTokenGenerationSuccessHandler {
218238
private val delegate: OneTimeTokenGenerationSuccessHandler
239+
var lastToken: OneTimeToken? = null
219240

220241
constructor() {
221242
this.delegate =
@@ -232,12 +253,9 @@ class OneTimeTokenLoginDslTests {
232253
}
233254

234255
override fun handle(request: HttpServletRequest, response: HttpServletResponse, oneTimeToken: OneTimeToken) {
235-
lastToken = oneTimeToken
256+
this.lastToken = oneTimeToken
236257
delegate.handle(request, response, oneTimeToken)
237258
}
238259

239-
companion object {
240-
var lastToken: OneTimeToken? = null
241-
}
242260
}
243261
}

0 commit comments

Comments
 (0)