From 992566b6cbb37d3266ed8e5217b6ace700ee1833 Mon Sep 17 00:00:00 2001 From: Luke Taylor Date: Sat, 14 Aug 2010 01:07:51 +0100 Subject: [PATCH] SEC-1527: Internationalization of contacts sample (Adding message resource bundle and RequestContextFilter). Re-working of L12n section of manual to mention existing localized message files and use of RequestContextFilter. --- .../manual/src/docbook/technical-overview.xml | 47 +++++++++++-------- .../applicationContext-common-business.xml | 4 ++ .../src/main/webapp/WEB-INF/jsp/include.jsp | 1 + .../contacts/src/main/webapp/WEB-INF/web.xml | 10 ++++ .../contacts/src/main/webapp/accessDenied.jsp | 10 ++-- samples/contacts/src/main/webapp/exitUser.jsp | 20 ++++---- samples/contacts/src/main/webapp/login.jsp | 2 + .../contacts/src/main/webapp/switchUser.jsp | 1 + 8 files changed, 58 insertions(+), 37 deletions(-) diff --git a/docs/manual/src/docbook/technical-overview.xml b/docs/manual/src/docbook/technical-overview.xml index 56de34db51..dd83e67f56 100644 --- a/docs/manual/src/docbook/technical-overview.xml +++ b/docs/manual/src/docbook/technical-overview.xml @@ -648,30 +648,31 @@ Successfully authenticated. Security context contains: \ anything as by default all Security Security messages are in English. If you need to support other locales, everything you need to know is contained in this section. All exception messages can be localized, including messages related to authentication - failures and access being denied (authorization failures). Exceptions and logging that - is focused on developers or system deployers (including incorrect attributes, interface - contract violations, using incorrect constructors, startup time validation, debug-level - logging) etc are not localized and instead are hard-coded in English within Spring - Security's code. + failures and access being denied (authorization failures). Exceptions and logging + messages that are focused on developers or system deployers (including incorrect + attributes, interface contract violations, using incorrect constructors, startup time + validation, debug-level logging) are not localized and instead are hard-coded in English + within Spring Security's code. Shipping in the spring-security-core-xx.jar you will find an org.springframework.security package that in turn contains a - messages.properties file. This should be referred to by your + messages.properties file, as well as localized versions for some + common languages. This should be referred to by your ApplicationContext, as Spring Security classes implement Spring's MessageSourceAware interface and expect the message resolver to be dependency injected at application context startup time. Usually all you need to do is register a bean inside your application context to refer to the messages. An example is shown below: - + - + -]]> +]]> + The messages.properties is named in accordance with standard resource bundles and represents the default language supported by Spring Security - messages. This default file is in English. If you do not register a message source, - Spring Security will still work correctly and fallback to hard-coded English versions of - the messages. + messages. This default file is in English. If you wish to customize the messages.properties file, or support other languages, you should copy the file, rename it accordingly, and register it inside the above bean definition. There are not a large number of message keys inside this @@ -679,13 +680,19 @@ Successfully authenticated. Security context contains: \ localization of this file, please consider sharing your work with the community by logging a JIRA task and attaching your appropriately-named localized version of messages.properties. - Rounding out the discussion on localization is the Spring - ThreadLocal known as - org.springframework.context.i18n.LocaleContextHolder. You should - set the LocaleContextHolder to represent the preferred - Locale of each user. Spring Security will attempt to locate a message - from the message source using the Locale obtained from this - ThreadLocal. Please refer to the Spring Framework documentation for - further details on using LocaleContextHolder. + Spring Security relies on Spring's localization support in order to actually lookup + the appropriate message. In order for this to work, you have to make sure that the + locale from the incoming request is stored in Spring's + org.springframework.context.i18n.LocaleContextHolder. Spring + MVC's DispatcherServlet does this for your application + automatically, but since Spring Security's filters are invoked before this, the + LocaleContextHolder needs to be set up to contain the correct + Locale before the filters are called. You can either do this in a + filter yourself (which must come before the Spring Security filters in + web.xml) or you can use Spring's + RequestContextFilter. Please refer to the Spring Framework + documentation for further details on using localization with Spring. + The contacts sample application is set up to use localized messages. + diff --git a/samples/contacts/src/main/resources/applicationContext-common-business.xml b/samples/contacts/src/main/resources/applicationContext-common-business.xml index 6cbfb9a375..fe96c4af9f 100644 --- a/samples/contacts/src/main/resources/applicationContext-common-business.xml +++ b/samples/contacts/src/main/resources/applicationContext-common-business.xml @@ -13,6 +13,10 @@ xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd"> + + + + diff --git a/samples/contacts/src/main/webapp/WEB-INF/jsp/include.jsp b/samples/contacts/src/main/webapp/WEB-INF/jsp/include.jsp index 738209fe39..9c306c9905 100644 --- a/samples/contacts/src/main/webapp/WEB-INF/jsp/include.jsp +++ b/samples/contacts/src/main/webapp/WEB-INF/jsp/include.jsp @@ -3,3 +3,4 @@ <%@ taglib prefix="c" uri="http://java.sun.com/jstl/core_rt" %> <%@ taglib prefix="fmt" uri="http://java.sun.com/jstl/fmt_rt" %> +<%@ page pageEncoding="UTF-8" %> diff --git a/samples/contacts/src/main/webapp/WEB-INF/web.xml b/samples/contacts/src/main/webapp/WEB-INF/web.xml index e398ea8f86..b194a05625 100644 --- a/samples/contacts/src/main/webapp/WEB-INF/web.xml +++ b/samples/contacts/src/main/webapp/WEB-INF/web.xml @@ -31,11 +31,21 @@ contacts.root + + localizationFilter + org.springframework.web.filter.RequestContextFilter + + springSecurityFilterChain org.springframework.web.filter.DelegatingFilterProxy + + localizationFilter + /* + + springSecurityFilterChain /* diff --git a/samples/contacts/src/main/webapp/accessDenied.jsp b/samples/contacts/src/main/webapp/accessDenied.jsp index a8e886b3b8..c94ae99b60 100644 --- a/samples/contacts/src/main/webapp/accessDenied.jsp +++ b/samples/contacts/src/main/webapp/accessDenied.jsp @@ -6,17 +6,17 @@ Access Denied - +

Sorry, access is denied

<%= request.getAttribute("SPRING_SECURITY_403_EXCEPTION")%>

-<% Authentication auth = SecurityContextHolder.getContext().getAuthentication(); - if (auth != null) { %> - Authentication object as a String: <%= auth.toString() %>

+<% Authentication auth = SecurityContextHolder.getContext().getAuthentication(); + if (auth != null) { %> + Authentication object as a String: <%= auth.toString() %>

<% } %>

- + diff --git a/samples/contacts/src/main/webapp/exitUser.jsp b/samples/contacts/src/main/webapp/exitUser.jsp index c343fae4b2..1a9bf16426 100644 --- a/samples/contacts/src/main/webapp/exitUser.jsp +++ b/samples/contacts/src/main/webapp/exitUser.jsp @@ -1,9 +1,8 @@ <%@ taglib prefix='c' uri='http://java.sun.com/jstl/core' %> -<%@ page import="org.springframework.security.core.context.SecurityContextHolder" %> <%@ page import="org.springframework.security.core.Authentication" %> -<%@ page import="org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter" %> -<%@ page import="org.springframework.security.core.AuthenticationException" %> +<%@ page import="org.springframework.security.core.context.SecurityContextHolder" %> +<%@ page pageEncoding="UTF-8" %> @@ -16,7 +15,7 @@ Your 'Exit User' attempt was not successful, try again.

- Reason: <%= ((AuthenticationException) session.getAttribute(AbstractAuthenticationProcessingFilter.SPRING_SECURITY_LAST_EXCEPTION_KEY)).getMessage() %> + Reason:
@@ -24,16 +23,13 @@
Current User: - <% - Authentication auth = SecurityContextHolder.getContext().getAuthentication(); - if (auth != null) { %> - - <%= auth.getPrincipal().toString() %> - - <% } %> - +<% + Authentication auth = SecurityContextHolder.getContext().getAuthentication(); + if (auth != null) { %> + <%= auth.getPrincipal().toString() %> + <% } %>
diff --git a/samples/contacts/src/main/webapp/login.jsp b/samples/contacts/src/main/webapp/login.jsp index cbeb816dd6..72158baccc 100644 --- a/samples/contacts/src/main/webapp/login.jsp +++ b/samples/contacts/src/main/webapp/login.jsp @@ -1,4 +1,5 @@ <%@ taglib prefix='c' uri='http://java.sun.com/jstl/core_rt' %> +<%@ page pageEncoding="UTF-8" %> @@ -19,6 +20,7 @@

username jane, password wombat

+

Locale is: <%= request.getLocale() %>

<%-- this form-login-page form is also used as the form-error-page to ask for a login again. --%> diff --git a/samples/contacts/src/main/webapp/switchUser.jsp b/samples/contacts/src/main/webapp/switchUser.jsp index 029c2c44da..09ec096d4e 100644 --- a/samples/contacts/src/main/webapp/switchUser.jsp +++ b/samples/contacts/src/main/webapp/switchUser.jsp @@ -1,6 +1,7 @@ <%@ taglib prefix='c' uri='http://java.sun.com/jstl/core' %> <%@ page import="org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter" %> <%@ page import="org.springframework.security.core.AuthenticationException" %> +<%@ page pageEncoding="UTF-8" %>