|
17 | 17 | package org.springframework.security.web.authentication;
|
18 | 18 |
|
19 | 19 | import java.io.IOException;
|
| 20 | +import java.util.ArrayList; |
20 | 21 | import java.util.Collections;
|
| 22 | +import java.util.List; |
21 | 23 |
|
22 | 24 | import jakarta.servlet.FilterChain;
|
23 | 25 | import jakarta.servlet.ServletException;
|
|
27 | 29 | import org.springframework.mock.web.MockHttpServletResponse;
|
28 | 30 | import org.springframework.security.authentication.BadCredentialsException;
|
29 | 31 | import org.springframework.security.authentication.TestAuthentication;
|
| 32 | +import org.springframework.security.authorization.AuthorizationDeniedException; |
| 33 | +import org.springframework.security.authorization.FactorAuthorizationDecision; |
| 34 | +import org.springframework.security.authorization.RequiredFactor; |
| 35 | +import org.springframework.security.authorization.RequiredFactorError; |
| 36 | +import org.springframework.security.core.GrantedAuthorities; |
30 | 37 | import org.springframework.security.core.context.SecurityContextHolderStrategy;
|
31 | 38 | import org.springframework.security.core.context.SecurityContextImpl;
|
32 | 39 | import org.springframework.security.web.WebAttributes;
|
| 40 | +import org.springframework.security.web.access.DelegatingMissingAuthorityAccessDeniedHandler; |
33 | 41 | import org.springframework.security.web.authentication.ui.DefaultLoginPageGeneratingFilter;
|
34 | 42 | import org.springframework.security.web.servlet.TestMockHttpServletRequests;
|
35 | 43 |
|
@@ -204,8 +212,9 @@ public void generateWhenOneTimeTokenRequestedThenOttForm() throws Exception {
|
204 | 212 | filter.setOneTimeTokenEnabled(true);
|
205 | 213 | filter.setOneTimeTokenGenerationUrl("/ott/authenticate");
|
206 | 214 | MockHttpServletResponse response = new MockHttpServletResponse();
|
207 |
| - filter.doFilter(TestMockHttpServletRequests.get("/login?factor.type=ott&factor.reason=missing").build(), |
208 |
| - response, this.chain); |
| 215 | + MockHttpServletRequest loginRequest = createLoginRequestFromMissingAuthority( |
| 216 | + GrantedAuthorities.FACTOR_OTT_AUTHORITY); |
| 217 | + filter.doFilter(loginRequest, response, this.chain); |
209 | 218 | assertThat(response.getContentAsString()).contains("Request a One-Time Token");
|
210 | 219 | assertThat(response.getContentAsString()).contains("""
|
211 | 220 | <form id="ott-form" class="login-form" method="post" action="/ott/authenticate">
|
@@ -251,6 +260,24 @@ public void generateWhenTwoAuthoritiesRequestedThenBothForms() throws Exception
|
251 | 260 | assertThat(response.getContentAsString()).contains("Password");
|
252 | 261 | }
|
253 | 262 |
|
| 263 | + private MockHttpServletRequest createLoginRequestFromMissingAuthority(String factorAuthority) |
| 264 | + throws ServletException, IOException { |
| 265 | + LoginUrlAuthenticationEntryPoint entryPoint = new LoginUrlAuthenticationEntryPoint("/login"); |
| 266 | + List<RequiredFactorError> factorErrors = new ArrayList<>(); |
| 267 | + DelegatingMissingAuthorityAccessDeniedHandler.Builder handlerBldr = DelegatingMissingAuthorityAccessDeniedHandler |
| 268 | + .builder(); |
| 269 | + handlerBldr.addEntryPointFor(entryPoint, factorAuthority); |
| 270 | + RequiredFactor requiredFactor = RequiredFactor.withAuthority(factorAuthority).build(); |
| 271 | + RequiredFactorError factorError = RequiredFactorError.createMissing(requiredFactor); |
| 272 | + factorErrors.add(factorError); |
| 273 | + DelegatingMissingAuthorityAccessDeniedHandler handler = handlerBldr.build(); |
| 274 | + MockHttpServletRequest request = new MockHttpServletRequest(); |
| 275 | + MockHttpServletResponse response = new MockHttpServletResponse(); |
| 276 | + FactorAuthorizationDecision decision = new FactorAuthorizationDecision(factorErrors); |
| 277 | + handler.handle(request, response, new AuthorizationDeniedException("", decision)); |
| 278 | + return TestMockHttpServletRequests.get(response.getRedirectedUrl()).build(); |
| 279 | + } |
| 280 | + |
254 | 281 | @Test
|
255 | 282 | public void generateWhenAuthenticatedThenReadOnlyUsername() throws Exception {
|
256 | 283 | SecurityContextHolderStrategy strategy = mock(SecurityContextHolderStrategy.class);
|
|
0 commit comments