Return Invalid Credentials message on login error

Closes gh-16484

Signed-off-by: tejas-teju <tejas8196@gmail.com>
This commit is contained in:
tejas-teju 2025-02-12 03:51:22 +05:30 committed by Josh Cummings
parent e42865b926
commit c4b223266c
3 changed files with 6 additions and 49 deletions

View File

@ -22,14 +22,12 @@ import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.MessageSourceAccessor;
import org.springframework.mock.web.MockHttpSession;
import org.springframework.security.config.ObjectPostProcessor;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.test.SpringTestContext;
import org.springframework.security.config.test.SpringTestContextExtension;
import org.springframework.security.core.SpringSecurityMessageSource;
import org.springframework.security.core.userdetails.PasswordEncodedUser;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
@ -77,8 +75,6 @@ public class DefaultLoginPageConfigurerTests {
@Autowired
MockMvc mvc;
MessageSourceAccessor messages = SpringSecurityMessageSource.getAccessor();
@Test
public void getWhenFormLoginEnabledThenRedirectsToLoginPage() throws Exception {
this.spring.register(DefaultLoginPageConfig.class).autowire();
@ -148,8 +144,7 @@ public class DefaultLoginPageConfigurerTests {
this.mvc.perform(get("/login?error").session((MockHttpSession) mvcResult.getRequest().getSession())
.sessionAttr(csrfAttributeName, csrfToken))
.andExpect((result) -> {
String badCredentialsLocalizedMessage = this.messages
.getMessage("AbstractUserDetailsAuthenticationProvider.badCredentials", "Bad credentials");
String defaultErrorMessage = "Invalid credentials";
CsrfToken token = (CsrfToken) result.getRequest().getAttribute(CsrfToken.class.getName());
assertThat(result.getResponse().getContentAsString()).isEqualTo("""
<!DOCTYPE html>
@ -184,7 +179,7 @@ public class DefaultLoginPageConfigurerTests {
</div>
</body>
</html>""".formatted(badCredentialsLocalizedMessage, token.getToken()));
</html>""".formatted(defaultErrorMessage, token.getToken()));
});
// @formatter:on
}

View File

@ -29,14 +29,10 @@ import jakarta.servlet.ServletRequest;
import jakarta.servlet.ServletResponse;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.WebAttributes;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.authentication.rememberme.AbstractRememberMeServices;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
import org.springframework.web.filter.GenericFilterBean;
/**
@ -221,7 +217,7 @@ public class DefaultLoginPageGeneratingFilter extends GenericFilterBean {
}
private String generateLoginPageHtml(HttpServletRequest request, boolean loginError, boolean logoutSuccess) {
String errorMsg = loginError ? getLoginErrorMessage(request) : "Invalid credentials";
String errorMsg = "Invalid credentials";
String contextPath = request.getContextPath();
return HtmlTemplates.fromTemplate(LOGIN_PAGE_TEMPLATE)
@ -358,21 +354,6 @@ public class DefaultLoginPageGeneratingFilter extends GenericFilterBean {
.render();
}
private String getLoginErrorMessage(HttpServletRequest request) {
HttpSession session = request.getSession(false);
if (session == null) {
return "Invalid credentials";
}
if (!(session
.getAttribute(WebAttributes.AUTHENTICATION_EXCEPTION) instanceof AuthenticationException exception)) {
return "Invalid credentials";
}
if (!StringUtils.hasText(exception.getMessage())) {
return "Invalid credentials";
}
return exception.getMessage();
}
private String renderHiddenInput(String name, String value) {
return HtmlTemplates.fromTemplate(HIDDEN_HTML_INPUT_TEMPLATE)
.withValue("name", name)

View File

@ -18,17 +18,14 @@ package org.springframework.security.web.authentication;
import java.io.IOException;
import java.util.Collections;
import java.util.Locale;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import org.junit.jupiter.api.Test;
import org.springframework.context.support.MessageSourceAccessor;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.core.SpringSecurityMessageSource;
import org.springframework.security.web.WebAttributes;
import org.springframework.security.web.authentication.ui.DefaultLoginPageGeneratingFilter;
@ -128,22 +125,6 @@ public class DefaultLoginPageGeneratingFilterTests {
assertThat(response.getContentAsString()).isEmpty();
}
/* SEC-1111 */
@Test
public void handlesNonIso8859CharsInErrorMessage() throws Exception {
DefaultLoginPageGeneratingFilter filter = new DefaultLoginPageGeneratingFilter(
new UsernamePasswordAuthenticationFilter());
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/login");
MockHttpServletResponse response = new MockHttpServletResponse();
request.setQueryString("error");
MessageSourceAccessor messages = SpringSecurityMessageSource.getAccessor();
String message = messages.getMessage("AbstractUserDetailsAuthenticationProvider.badCredentials",
"Bad credentials", Locale.KOREA);
request.getSession().setAttribute(WebAttributes.AUTHENTICATION_EXCEPTION, new BadCredentialsException(message));
filter.doFilter(request, response, this.chain);
assertThat(response.getContentAsString()).contains(message);
}
// gh-5394
@Test
public void generatesForOAuth2LoginAndEscapesClientName() throws Exception {
@ -244,7 +225,7 @@ public class DefaultLoginPageGeneratingFilterTests {
<div class="content">
<form class="login-form" method="post" action="null">
<h2>Please sign in</h2>
<div class="alert alert-danger" role="alert">Bad credentials</div>
<div class="alert alert-danger" role="alert">Invalid credentials</div>
<p>
<label for="username" class="screenreader">Username</label>
<input type="text" id="username" name="username" placeholder="Username" required autofocus>
@ -259,12 +240,12 @@ public class DefaultLoginPageGeneratingFilterTests {
</form>
<h2>Login with OAuth 2.0</h2>
<div class="alert alert-danger" role="alert">Bad credentials</div>
<div class="alert alert-danger" role="alert">Invalid credentials</div>
<table class="table table-striped">
<tr><td><a href="/oauth2/authorization/google">Google &lt; &gt; &quot; &#39; &amp;</a></td></tr>
</table>
<h2>Login with SAML 2.0</h2>
<div class="alert alert-danger" role="alert">Bad credentials</div>
<div class="alert alert-danger" role="alert">Invalid credentials</div>
<table class="table table-striped">
<tr><td><a href="/saml/sso/google">Google &lt; &gt; &quot; &#39; &amp;</a></td></tr>
</table>