OneTimeToken Missing Token Propagates Request

Closes gh-16780
This commit is contained in:
Josh Cummings 2025-03-20 17:15:04 -06:00
parent 8199015e79
commit 861a9a914e
No known key found for this signature in database
GPG Key ID: 869B37A20E876129
2 changed files with 5 additions and 38 deletions

View File

@ -16,19 +16,8 @@
package org.springframework.security.web.authentication.ott; package org.springframework.security.web.authentication.ott;
import java.io.IOException;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter; import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
import org.springframework.security.web.authentication.AuthenticationConverter;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher; import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.util.Assert;
/** /**
* Filter that processes a one-time token for log in. * Filter that processes a one-time token for log in.
@ -43,31 +32,9 @@ public final class OneTimeTokenAuthenticationFilter extends AbstractAuthenticati
public static final String DEFAULT_LOGIN_PROCESSING_URL = "/login/ott"; public static final String DEFAULT_LOGIN_PROCESSING_URL = "/login/ott";
private AuthenticationConverter authenticationConverter = new OneTimeTokenAuthenticationConverter();
public OneTimeTokenAuthenticationFilter() { public OneTimeTokenAuthenticationFilter() {
super(new AntPathRequestMatcher(DEFAULT_LOGIN_PROCESSING_URL, "POST")); super(new AntPathRequestMatcher(DEFAULT_LOGIN_PROCESSING_URL, "POST"));
} setAuthenticationConverter(new OneTimeTokenAuthenticationConverter());
@Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
throws AuthenticationException, IOException, ServletException {
Authentication authentication = this.authenticationConverter.convert(request);
if (authentication == null) {
throw new BadCredentialsException("Unable to authenticate with the one-time token");
}
return getAuthenticationManager().authenticate(authentication);
}
/**
* Use this {@link AuthenticationConverter} when converting incoming requests to an
* {@link Authentication}. By default, the {@link OneTimeTokenAuthenticationConverter}
* is used.
* @param authenticationConverter the {@link AuthenticationConverter} to use
*/
public void setAuthenticationConverter(AuthenticationConverter authenticationConverter) {
Assert.notNull(authenticationConverter, "authenticationConverter cannot be null");
this.authenticationConverter = authenticationConverter;
} }
} }

View File

@ -95,10 +95,10 @@ class OneTimeTokenAuthenticationFilterTests {
} }
@Test @Test
void doFilterWhenMissingTokenThenUnauthorized() throws ServletException, IOException { void doFilterWhenMissingTokenThenPropagatesRequest() throws ServletException, IOException {
this.filter.doFilter(post("/login/ott").buildRequest(new MockServletContext()), this.response, this.chain); FilterChain chain = mock(FilterChain.class);
assertThat(this.response.getStatus()).isEqualTo(HttpStatus.UNAUTHORIZED.value()); this.filter.doFilter(post("/login/ott").buildRequest(new MockServletContext()), this.response, chain);
verifyNoInteractions(this.chain); verify(chain).doFilter(any(), any());
} }
@Test @Test