Browse Source

Add localization to error messages from ExceptionTranslationFilter

Fixes gh-4504
Benedikt Ritter 8 years ago
parent
commit
fffd781b03

+ 1 - 0
core/src/main/resources/org/springframework/security/messages_de.properties

@@ -28,6 +28,7 @@ DigestAuthenticationFilter.nonceExpired=Die Nonce ist nicht mehr g\u00FCltig
 DigestAuthenticationFilter.nonceNotNumeric=Das erste Element der Nonce sollte numerisch sein. Gefundener Inhalt\: {0}
 DigestAuthenticationFilter.nonceNotTwoTokens=Nonce sollte zwei Elemente beinhalten. Gefundener Inhalt\: {0}
 DigestAuthenticationFilter.usernameNotFound=Benutzername {0} wurde nicht gefunden
+ExceptionTranslationFilter.insufficientAuthentication=Vollst\u00E4ndige Authentifikation wird ben\u00f6tigt um auf diese Resource zuzugreifen
 #JdbcDaoImpl.noAuthority=User {0} has no GrantedAuthority
 #JdbcDaoImpl.notFound=User {0} not found
 LdapAuthenticationProvider.badCredentials=Ung\u00FCltige Anmeldedaten

+ 1 - 0
core/src/main/resources/org/springframework/security/messages_en.properties

@@ -28,6 +28,7 @@ DigestAuthenticationFilter.nonceExpired=Nonce has expired/timed out
 DigestAuthenticationFilter.nonceNotNumeric=Nonce token should have yielded a numeric first token, but was {0}
 DigestAuthenticationFilter.nonceNotTwoTokens=Nonce should have yielded two tokens but was {0}
 DigestAuthenticationFilter.usernameNotFound=Username {0} not found
+ExceptionTranslationFilter.insufficientAuthentication=Full authentication is required to access this resource
 JdbcDaoImpl.noAuthority=User {0} has no GrantedAuthority
 JdbcDaoImpl.notFound=User {0} not found
 LdapAuthenticationProvider.badCredentials=Bad credentials

+ 8 - 1
web/src/main/java/org/springframework/security/web/access/ExceptionTranslationFilter.java

@@ -21,6 +21,7 @@ import org.springframework.security.authentication.AuthenticationTrustResolverIm
 import org.springframework.security.authentication.InsufficientAuthenticationException;
 import org.springframework.security.core.Authentication;
 import org.springframework.security.core.AuthenticationException;
+import org.springframework.security.core.SpringSecurityMessageSource;
 import org.springframework.security.core.context.SecurityContextHolder;
 import org.springframework.security.web.AuthenticationEntryPoint;
 import org.springframework.security.web.savedrequest.HttpSessionRequestCache;
@@ -30,6 +31,8 @@ import org.springframework.security.web.util.ThrowableCauseExtractor;
 import org.springframework.util.Assert;
 import org.springframework.web.filter.GenericFilterBean;
 
+import org.springframework.context.support.MessageSourceAccessor;
+
 import javax.servlet.FilterChain;
 import javax.servlet.ServletException;
 import javax.servlet.ServletRequest;
@@ -83,6 +86,8 @@ public class ExceptionTranslationFilter extends GenericFilterBean {
 
 	private RequestCache requestCache = new HttpSessionRequestCache();
 
+	private final MessageSourceAccessor messages = SpringSecurityMessageSource.getAccessor();
+
 	public ExceptionTranslationFilter(AuthenticationEntryPoint authenticationEntryPoint) {
 		this(authenticationEntryPoint, new HttpSessionRequestCache());
 	}
@@ -179,7 +184,9 @@ public class ExceptionTranslationFilter extends GenericFilterBean {
 						response,
 						chain,
 						new InsufficientAuthenticationException(
-								"Full authentication is required to access this resource"));
+							messages.getMessage(
+								"ExceptionTranslationFilter.insufficientAuthentication",
+								"Full authentication is required to access this resource")));
 			}
 			else {
 				logger.debug(

+ 1 - 0
web/src/main/resources/org/springframework/security/web/messages_de.properties

@@ -0,0 +1 @@
+ExceptionTranslationFilter.insufficientAuthentication=Vollst\u00e4ndige Authentifikation wird ben\u00f6tigt um auf diese Resource zuzugreifen

+ 1 - 0
web/src/main/resources/org/springframework/security/web/messages_en.properties

@@ -0,0 +1 @@
+ExceptionTranslationFilter.insufficientAuthentication=Full authentication is required to access this resource

+ 32 - 0
web/src/test/java/org/springframework/security/web/access/ExceptionTranslationFilterTests.java

@@ -18,6 +18,7 @@ package org.springframework.security.web.access;
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
+import org.springframework.context.i18n.LocaleContextHolder;
 import org.springframework.mock.web.MockHttpServletRequest;
 import org.springframework.mock.web.MockHttpServletResponse;
 import org.springframework.security.MockPortResolver;
@@ -41,6 +42,7 @@ import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 import javax.servlet.http.HttpSession;
 import java.io.IOException;
+import java.util.Locale;
 
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.core.api.Assertions.fail;
@@ -167,6 +169,36 @@ public class ExceptionTranslationFilterTests {
 		assertThat(request.getAttribute(WebAttributes.ACCESS_DENIED_403)).isExactlyInstanceOf(AccessDeniedException.class);
 	}
 
+	@Test
+	public void testLocalizedErrorMessages() throws Exception {
+		// Setup our HTTP request
+		MockHttpServletRequest request = new MockHttpServletRequest();
+		request.setServletPath("/secure/page.html");
+
+		// Setup the FilterChain to thrown an access denied exception
+		FilterChain fc = mock(FilterChain.class);
+		doThrow(new AccessDeniedException("")).when(fc).doFilter(
+			any(HttpServletRequest.class), any(HttpServletResponse.class));
+
+		// Setup SecurityContextHolder, as filter needs to check if user is
+		// anonymous
+		SecurityContextHolder.getContext().setAuthentication(
+			new AnonymousAuthenticationToken("ignored", "ignored", AuthorityUtils
+				.createAuthorityList("IGNORED")));
+
+		// Test
+		ExceptionTranslationFilter filter = new ExceptionTranslationFilter(
+			(req, res, ae) -> res.sendError(403, ae.getMessage()));
+		filter.setAuthenticationTrustResolver(new AuthenticationTrustResolverImpl());
+		assertThat(filter.getAuthenticationTrustResolver()).isNotNull();
+
+		LocaleContextHolder.setDefaultLocale(Locale.GERMAN);
+		MockHttpServletResponse response = new MockHttpServletResponse();
+		filter.doFilter(request, response, fc);
+		assertThat(response.getErrorMessage())
+			.isEqualTo("Vollst\u00e4ndige Authentifikation wird ben\u00f6tigt um auf diese Resource zuzugreifen");
+	}
+
 	@Test
 	public void redirectedToLoginFormAndSessionShowsOriginalTargetWhenAuthenticationException()
 			throws Exception {