1
0
mirror of synced 2026-08-07 10:47:49 +00:00

Integration Test for DefaultLoginPageGeneratingFilterTests

Add a minimal test to ensure that
DelegatingMissingAuthorityAccessDeniedHandler and
DefaultLoginPageGeneratingFilterTests work together properly.

Issue gh-18002
This commit is contained in:
Rob Winch
2025-10-03 14:05:28 -05:00
parent 2473378fcd
commit 9595d37c14
@@ -17,7 +17,9 @@
package org.springframework.security.web.authentication;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
@@ -27,9 +29,15 @@ import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.TestAuthentication;
import org.springframework.security.authorization.AuthorizationDeniedException;
import org.springframework.security.authorization.FactorAuthorizationDecision;
import org.springframework.security.authorization.RequiredFactor;
import org.springframework.security.authorization.RequiredFactorError;
import org.springframework.security.core.GrantedAuthorities;
import org.springframework.security.core.context.SecurityContextHolderStrategy;
import org.springframework.security.core.context.SecurityContextImpl;
import org.springframework.security.web.WebAttributes;
import org.springframework.security.web.access.DelegatingMissingAuthorityAccessDeniedHandler;
import org.springframework.security.web.authentication.ui.DefaultLoginPageGeneratingFilter;
import org.springframework.security.web.servlet.TestMockHttpServletRequests;
@@ -204,8 +212,9 @@ public class DefaultLoginPageGeneratingFilterTests {
filter.setOneTimeTokenEnabled(true);
filter.setOneTimeTokenGenerationUrl("/ott/authenticate");
MockHttpServletResponse response = new MockHttpServletResponse();
filter.doFilter(TestMockHttpServletRequests.get("/login?factor.type=ott&factor.reason=missing").build(),
response, this.chain);
MockHttpServletRequest loginRequest = createLoginRequestFromMissingAuthority(
GrantedAuthorities.FACTOR_OTT_AUTHORITY);
filter.doFilter(loginRequest, response, this.chain);
assertThat(response.getContentAsString()).contains("Request a One-Time Token");
assertThat(response.getContentAsString()).contains("""
<form id="ott-form" class="login-form" method="post" action="/ott/authenticate">
@@ -251,6 +260,24 @@ public class DefaultLoginPageGeneratingFilterTests {
assertThat(response.getContentAsString()).contains("Password");
}
private MockHttpServletRequest createLoginRequestFromMissingAuthority(String factorAuthority)
throws ServletException, IOException {
LoginUrlAuthenticationEntryPoint entryPoint = new LoginUrlAuthenticationEntryPoint("/login");
List<RequiredFactorError> factorErrors = new ArrayList<>();
DelegatingMissingAuthorityAccessDeniedHandler.Builder handlerBldr = DelegatingMissingAuthorityAccessDeniedHandler
.builder();
handlerBldr.addEntryPointFor(entryPoint, factorAuthority);
RequiredFactor requiredFactor = RequiredFactor.withAuthority(factorAuthority).build();
RequiredFactorError factorError = RequiredFactorError.createMissing(requiredFactor);
factorErrors.add(factorError);
DelegatingMissingAuthorityAccessDeniedHandler handler = handlerBldr.build();
MockHttpServletRequest request = new MockHttpServletRequest();
MockHttpServletResponse response = new MockHttpServletResponse();
FactorAuthorizationDecision decision = new FactorAuthorizationDecision(factorErrors);
handler.handle(request, response, new AuthorizationDeniedException("", decision));
return TestMockHttpServletRequests.get(response.getRedirectedUrl()).build();
}
@Test
public void generateWhenAuthenticatedThenReadOnlyUsername() throws Exception {
SecurityContextHolderStrategy strategy = mock(SecurityContextHolderStrategy.class);