Skip to content

Commit 664dfd9

Browse files
committed
Defer Anonymous Filter Construction
By delaying when the AnonymousAuthenticationFilter is constructed, it's now possible to call the principal and filter methods inside of a custom DSL implementation. This does not extend to setting the key or the authentication provider though, as these must be set during the init phase. Closes gh-14941
1 parent 82ea085 commit 664dfd9

File tree

2 files changed

+49
-9
lines changed

2 files changed

+49
-9
lines changed

config/src/main/java/org/springframework/security/config/annotation/web/configurers/AnonymousConfigurer.java

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2022 the original author or authors.
2+
* Copyright 2002-2024 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -53,6 +53,8 @@ public final class AnonymousConfigurer<H extends HttpSecurityBuilder<H>>
5353

5454
private List<GrantedAuthority> authorities = AuthorityUtils.createAuthorityList("ROLE_ANONYMOUS");
5555

56+
private String computedKey;
57+
5658
/**
5759
* Creates a new instance
5860
* @see HttpSecurity#anonymous()
@@ -144,26 +146,31 @@ public void init(H http) {
144146
if (this.authenticationProvider == null) {
145147
this.authenticationProvider = new AnonymousAuthenticationProvider(getKey());
146148
}
147-
if (this.authenticationFilter == null) {
148-
this.authenticationFilter = new AnonymousAuthenticationFilter(getKey(), this.principal, this.authorities);
149-
this.authenticationFilter.setSecurityContextHolderStrategy(getSecurityContextHolderStrategy());
150-
}
151-
this.authenticationFilter.setSecurityContextHolderStrategy(getSecurityContextHolderStrategy());
152149
this.authenticationProvider = postProcess(this.authenticationProvider);
153150
http.authenticationProvider(this.authenticationProvider);
154151
}
155152

156153
@Override
157154
public void configure(H http) {
155+
if (this.authenticationFilter == null) {
156+
this.authenticationFilter = new AnonymousAuthenticationFilter(getKey(), this.principal, this.authorities);
157+
}
158+
this.authenticationFilter.setSecurityContextHolderStrategy(getSecurityContextHolderStrategy());
158159
this.authenticationFilter.afterPropertiesSet();
159160
http.addFilter(this.authenticationFilter);
160161
}
161162

162163
private String getKey() {
164+
if (this.computedKey != null) {
165+
return this.computedKey;
166+
}
163167
if (this.key == null) {
164-
this.key = UUID.randomUUID().toString();
168+
this.computedKey = UUID.randomUUID().toString();
169+
}
170+
else {
171+
this.computedKey = this.key;
165172
}
166-
return this.key;
173+
return this.computedKey;
167174
}
168175

169176
}

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

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2022 the original author or authors.
2+
* Copyright 2002-2024 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -94,6 +94,13 @@ public void requestWhenAnonymousWithDefaultsInLambdaThenRespondsWithOk() throws
9494
this.mockMvc.perform(get("/")).andExpect(status().isOk());
9595
}
9696

97+
// gh-14941
98+
@Test
99+
public void shouldReturnMyCustomAnonymousConfig() throws Exception {
100+
this.spring.register(AnonymousInCustomConfigurer.class, PrincipalController.class).autowire();
101+
this.mockMvc.perform(get("/")).andExpect(status().isOk()).andExpect(content().string("myAnonymousUser"));
102+
}
103+
97104
@Configuration
98105
@EnableWebSecurity
99106
@EnableWebMvc
@@ -181,6 +188,32 @@ UserDetailsService userDetailsService() {
181188

182189
}
183190

191+
@Configuration
192+
@EnableWebMvc
193+
@EnableWebSecurity
194+
static class AnonymousInCustomConfigurer {
195+
196+
@Bean
197+
SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
198+
// @formatter:off
199+
http
200+
.authorizeHttpRequests((authorize) -> authorize.anyRequest().permitAll())
201+
.with(new CustomDsl(), withDefaults());
202+
// @formatter:on
203+
return http.build();
204+
}
205+
206+
static class CustomDsl extends AbstractHttpConfigurer<CustomDsl, HttpSecurity> {
207+
208+
@Override
209+
public void init(HttpSecurity http) throws Exception {
210+
http.anonymous((anonymous) -> anonymous.principal("myAnonymousUser"));
211+
}
212+
213+
}
214+
215+
}
216+
184217
@RestController
185218
static class PrincipalController {
186219

0 commit comments

Comments
 (0)