@ -17,7 +17,9 @@
@@ -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;
@@ -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 {
@@ -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 {
@@ -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 ) ;