Skip to content

Commit 978181e

Browse files
committed
Apply Additional Feedback
- This Removes the auto-post page for OTT - This uses the now-public AccessDeniedHandler - This also does not change the default AuthenticationEntryPoint This also walks back certain things added to smooth the usage of MFA for WebAuthn, OTT, and X.509. I believe there are ways outside of MFA to do each of these that will make the considerations moot. That said, this commit does keep one change for X.509 that I believe to be the original purpose of the line that sets a shared AuthenticationEntryPoint. This would likely not be in this PR, but it simplifies the tests while I'm investigating this claim.
1 parent 3dc3b89 commit 978181e

File tree

10 files changed

+30
-62
lines changed

10 files changed

+30
-62
lines changed

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

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
package org.springframework.security.config.annotation.web.configurers;
1818

1919
import java.util.LinkedHashMap;
20-
import java.util.Map;
2120
import java.util.function.Consumer;
2221

2322
import org.jspecify.annotations.Nullable;
@@ -80,10 +79,8 @@ public final class ExceptionHandlingConfigurer<H extends HttpSecurityBuilder<H>>
8079

8180
private LinkedHashMap<RequestMatcher, AccessDeniedHandler> defaultDeniedHandlerMappings = new LinkedHashMap<>();
8281

83-
private Map<String, LinkedHashMap<RequestMatcher, AuthenticationEntryPoint>> entryPoints = new LinkedHashMap<>();
84-
85-
private DelegatingMissingAuthorityAccessDeniedHandler.Builder missingAuthoritiesHandlerBuilder =
86-
DelegatingMissingAuthorityAccessDeniedHandler.builder();
82+
private final DelegatingMissingAuthorityAccessDeniedHandler.Builder missingAuthoritiesHandlerBuilder = DelegatingMissingAuthorityAccessDeniedHandler
83+
.builder();
8784

8885
/**
8986
* Creates a new instance
@@ -106,7 +103,8 @@ public ExceptionHandlingConfigurer<H> accessDeniedPage(String accessDeniedUrl) {
106103
return accessDeniedHandler(accessDeniedHandler);
107104
}
108105

109-
public ExceptionHandlingConfigurer<H> missingAuthoritiesHandler(Consumer<DelegatingMissingAuthorityAccessDeniedHandler.Builder> consumer) {
106+
public ExceptionHandlingConfigurer<H> missingAuthoritiesHandler(
107+
Consumer<DelegatingMissingAuthorityAccessDeniedHandler.Builder> consumer) {
110108
consumer.accept(this.missingAuthoritiesHandlerBuilder);
111109
return this;
112110
}
@@ -243,9 +241,6 @@ AuthenticationEntryPoint getAuthenticationEntryPoint(H http) {
243241

244242
private AccessDeniedHandler createDefaultDeniedHandler(H http) {
245243
AccessDeniedHandler defaults = createDefaultAccessDeniedHandler(http);
246-
if (this.entryPoints.isEmpty()) {
247-
return defaults;
248-
}
249244
DelegatingMissingAuthorityAccessDeniedHandler deniedHandler = this.missingAuthoritiesHandlerBuilder.build();
250245
deniedHandler.setRequestCache(getRequestCache(http));
251246
deniedHandler.setDefaultAccessDeniedHandler(defaults);

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

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -233,11 +233,9 @@ public void init(H http) throws Exception {
233233
initDefaultLoginFilter(http);
234234
ExceptionHandlingConfigurer<H> exceptions = http.getConfigurer(ExceptionHandlingConfigurer.class);
235235
if (exceptions != null) {
236-
exceptions.missingAuthoritiesHandler((commence) -> commence
237-
.authorities("FACTOR_PASSWORD")
238-
.whenRequestMatches(getAuthenticationEntryPointMatcher(http))
239-
.commence(getAuthenticationEntryPoint())
240-
);
236+
exceptions.missingAuthoritiesHandler((commence) -> commence.authorities("FACTOR_PASSWORD")
237+
.whenRequestMatches(getAuthenticationEntryPointMatcher(http))
238+
.commence(getAuthenticationEntryPoint()));
241239
}
242240
}
243241

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

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -194,11 +194,9 @@ private void registerDefaultEntryPoint(B http, RequestMatcher preferredMatcher)
194194
}
195195
AuthenticationEntryPoint entryPoint = postProcess(this.authenticationEntryPoint);
196196
exceptionHandling.defaultAuthenticationEntryPointFor(entryPoint, preferredMatcher);
197-
exceptionHandling.missingAuthoritiesHandler((handler) -> handler
198-
.authorities("FACTOR_PASSWORD")
199-
.whenRequestMatches(preferredMatcher)
200-
.commence(entryPoint)
201-
);
197+
exceptionHandling.missingAuthoritiesHandler((handler) -> handler.authorities("FACTOR_PASSWORD")
198+
.whenRequestMatches(preferredMatcher)
199+
.commence(entryPoint));
202200
}
203201

204202
private void registerDefaultLogoutSuccessHandler(B http, RequestMatcher preferredMatcher) {

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

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -155,10 +155,8 @@ public WebAuthnConfigurer<H> creationOptionsRepository(
155155
public void init(H http) throws Exception {
156156
ExceptionHandlingConfigurer<H> exceptions = http.getConfigurer(ExceptionHandlingConfigurer.class);
157157
if (exceptions != null) {
158-
exceptions.missingAuthoritiesHandler((handler) -> handler
159-
.authorities("FACTOR_WEBAUTHN")
160-
.commence(new LoginUrlAuthenticationEntryPoint("/login"))
161-
);
158+
exceptions.missingAuthoritiesHandler((handler) -> handler.authorities("FACTOR_WEBAUTHN")
159+
.commence(new LoginUrlAuthenticationEntryPoint("/login")));
162160
}
163161
}
164162

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
import org.springframework.security.web.authentication.preauth.x509.X509AuthenticationFilter;
3939
import org.springframework.security.web.authentication.preauth.x509.X509PrincipalExtractor;
4040
import org.springframework.security.web.context.RequestAttributeSecurityContextRepository;
41+
import org.springframework.security.web.util.matcher.AnyRequestMatcher;
4142

4243
/**
4344
* Adds X509 based pre authentication to an application. Since validating the certificate
@@ -183,10 +184,9 @@ public void init(H http) {
183184
.setSharedObject(AuthenticationEntryPoint.class, new Http403ForbiddenEntryPoint());
184185
ExceptionHandlingConfigurer<H> exceptions = http.getConfigurer(ExceptionHandlingConfigurer.class);
185186
if (exceptions != null) {
186-
exceptions.missingAuthoritiesHandler((handler) -> handler
187-
.authorities("FACTOR_X509")
188-
.commence(new Http403ForbiddenEntryPoint())
189-
);
187+
exceptions.defaultAuthenticationEntryPointFor(new Http403ForbiddenEntryPoint(), AnyRequestMatcher.INSTANCE);
188+
exceptions.missingAuthoritiesHandler(
189+
(handler) -> handler.authorities("FACTOR_X509").commence(new Http403ForbiddenEntryPoint()));
190190
}
191191
}
192192

config/src/main/java/org/springframework/security/config/annotation/web/configurers/oauth2/client/OAuth2LoginConfigurer.java

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -564,11 +564,9 @@ private AuthenticationEntryPoint getLoginEntryPoint(B http, String providerLogin
564564
// @formatter:on
565565
ExceptionHandlingConfigurer<B> exceptions = http.getConfigurer(ExceptionHandlingConfigurer.class);
566566
if (exceptions != null) {
567-
exceptions.missingAuthoritiesHandler((handler) -> handler
568-
.authorities("FACTOR_AUTHORIZATION_CODE")
569-
.whenRequestMatches(getAuthenticationEntryPointMatcher(http))
570-
.commence(loginEntryPoint)
571-
);
567+
exceptions.missingAuthoritiesHandler((handler) -> handler.authorities("FACTOR_AUTHORIZATION_CODE")
568+
.whenRequestMatches(getAuthenticationEntryPointMatcher(http))
569+
.commence(loginEntryPoint));
572570
}
573571
return loginEntryPoint;
574572
}

config/src/main/java/org/springframework/security/config/annotation/web/configurers/oauth2/server/resource/OAuth2ResourceServerConfigurer.java

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -327,11 +327,9 @@ private void registerDefaultEntryPoint(H http) {
327327
RequestMatcher preferredMatcher = new OrRequestMatcher(
328328
Arrays.asList(this.requestMatcher, X_REQUESTED_WITH, restNotHtmlMatcher, allMatcher));
329329
exceptionHandling.defaultAuthenticationEntryPointFor(this.authenticationEntryPoint, preferredMatcher);
330-
exceptionHandling.missingAuthoritiesHandler((handler) -> handler
331-
.authorities("FACTOR_BEARER")
332-
.whenRequestMatches(preferredMatcher)
333-
.commence(this.authenticationEntryPoint)
334-
);
330+
exceptionHandling.missingAuthoritiesHandler((handler) -> handler.authorities("FACTOR_BEARER")
331+
.whenRequestMatches(preferredMatcher)
332+
.commence(this.authenticationEntryPoint));
335333
}
336334
}
337335

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

Lines changed: 3 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,10 @@
1616

1717
package org.springframework.security.config.annotation.web.configurers.ott;
1818

19-
import java.io.IOException;
2019
import java.util.Collections;
2120
import java.util.Map;
22-
import java.util.function.Function;
23-
import java.util.stream.Collectors;
2421

25-
import jakarta.servlet.ServletException;
2622
import jakarta.servlet.http.HttpServletRequest;
27-
import jakarta.servlet.http.HttpServletResponse;
2823

2924
import org.springframework.context.ApplicationContext;
3025
import org.springframework.http.HttpMethod;
@@ -42,13 +37,7 @@
4237
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
4338
import org.springframework.security.config.annotation.web.configurers.ExceptionHandlingConfigurer;
4439
import org.springframework.security.core.Authentication;
45-
import org.springframework.security.core.AuthenticationException;
46-
import org.springframework.security.core.context.SecurityContextHolder;
47-
import org.springframework.security.core.context.SecurityContextHolderStrategy;
4840
import org.springframework.security.core.userdetails.UserDetailsService;
49-
import org.springframework.security.web.AuthenticationEntryPoint;
50-
import org.springframework.security.web.FormPostRedirectStrategy;
51-
import org.springframework.security.web.RedirectStrategy;
5241
import org.springframework.security.web.authentication.AuthenticationConverter;
5342
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
5443
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
@@ -67,7 +56,6 @@
6756
import org.springframework.security.web.util.matcher.RequestMatcher;
6857
import org.springframework.util.Assert;
6958
import org.springframework.util.StringUtils;
70-
import org.springframework.web.util.UriComponentsBuilder;
7159

7260
/**
7361
* An {@link AbstractHttpConfigurer} for One-Time Token Login.
@@ -149,11 +137,9 @@ public void init(H http) throws Exception {
149137
intiDefaultLoginFilter(http);
150138
ExceptionHandlingConfigurer<H> exceptions = http.getConfigurer(ExceptionHandlingConfigurer.class);
151139
if (exceptions != null) {
152-
exceptions.missingAuthoritiesHandler((handler) -> handler
153-
.authorities("FACTOR_OTT")
154-
.whenRequestMatches(getAuthenticationEntryPointMatcher(http))
155-
.commence(getAuthenticationEntryPoint())
156-
);
140+
exceptions.missingAuthoritiesHandler((handler) -> handler.authorities("FACTOR_OTT")
141+
.whenRequestMatches(getAuthenticationEntryPointMatcher(http))
142+
.commence(getAuthenticationEntryPoint()));
157143
}
158144
}
159145

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

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -351,10 +351,9 @@ private AuthenticationEntryPoint getLoginEntryPoint(B http, String providerLogin
351351
// @formatter:on
352352
ExceptionHandlingConfigurer<B> exceptions = http.getConfigurer(ExceptionHandlingConfigurer.class);
353353
if (exceptions != null) {
354-
exceptions.missingAuthoritiesHandler((handler) -> handler
355-
.authorities("FACTOR_SAML_RESPONSE")
356-
.whenRequestMatches(getAuthenticationEntryPointMatcher(http))
357-
.commence(loginEntryPoint));
354+
exceptions.missingAuthoritiesHandler((handler) -> handler.authorities("FACTOR_SAML_RESPONSE")
355+
.whenRequestMatches(getAuthenticationEntryPointMatcher(http))
356+
.commence(loginEntryPoint));
358357
}
359358
return loginEntryPoint;
360359
}

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

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,6 @@
7373
import org.springframework.web.bind.annotation.RestController;
7474
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
7575

76-
import static org.hamcrest.Matchers.containsString;
7776
import static org.mockito.ArgumentMatchers.any;
7877
import static org.mockito.BDDMockito.given;
7978
import static org.mockito.Mockito.atLeastOnce;
@@ -88,7 +87,6 @@
8887
import static org.springframework.security.test.web.servlet.response.SecurityMockMvcResultMatchers.authenticated;
8988
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
9089
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
91-
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
9290
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.forwardedUrl;
9391
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.redirectedUrl;
9492
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@@ -432,8 +430,8 @@ void requestWhenUnauthenticatedThenRequiresTwoSteps() throws Exception {
432430
.andExpect(redirectedUrl("http://localhost/login"));
433431
user = PasswordEncodedUser.withUserDetails(user).authorities("profile:read", "FACTOR_PASSWORD").build();
434432
this.mockMvc.perform(get("/profile").with(user(user)))
435-
.andExpect(status().isOk())
436-
.andExpect(content().string(containsString("/ott/generate")));
433+
.andExpect(status().is3xxRedirection())
434+
.andExpect(redirectedUrl("http://localhost/login"));
437435
user = PasswordEncodedUser.withUserDetails(user)
438436
.authorities("profile:read", "FACTOR_PASSWORD", "FACTOR_OTT")
439437
.build();

0 commit comments

Comments
 (0)