Spring Security Internationalisation des erreurs
Bonjour,
Après de nombreuses tentatives, je me tourne vers vos savants esprits. Je construis actuellement un site géré par spring (spring mvc, webflow & sécurity). Pour gérer l'internationalisation, j'ai étendu le comportement des resolvers pour pouvoir les chainer et pouvoir ainsi prioritiser la résolution des locales: je teste d'abord par paramètres de la barre d'adresse puis, par cookie et puis session.
Hélas, au grand hélas, lorsque mon authentication manager génère un message d'erreur, la gestion des langues ne s'est pas encore exécutée (appel à localeResolver et affectation de la locale dans le LocaleContextHolder) si bien que le message d'erreur est dans la locale du navigateur (Accept-Language) alors que le reste de la page est dans la langue souhaitée.
Merci beaucoup pour votre aide :),
Voici le code source:
Fichier Web:
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224
|
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
version="2.4">
<description>WebSite Web</description>
<!-- MIME -->
<mime-mapping>
<extension>jnlp</extension>
<mime-type>application/x-java-jnlp-file</mime-type>
</mime-mapping>
<mime-mapping>
<extension>jar</extension>
<mime-type>application/x-java-archive</mime-type>
</mime-mapping>
<mime-mapping>
<extension>jardiff</extension>
<mime-type>application/x-java-archive-diff</mime-type>
</mime-mapping>
<!-- FACES PARAMETER -->
<context-param>
<description>
Comma separated list of URIs of (additional) faces config
files.
</description>
<param-name>javax.faces.CONFIG_FILES</param-name>
<param-value>/WEB-INF/faces-config.xml</param-value>
</context-param>
<context-param>
<param-name>javax.faces.DEFAULT_SUFFIX</param-name>
<param-value>.xhtml</param-value>
</context-param>
<!-- IGNORING JSF implementation of JBOSS -->
<context-param>
<param-name>org.jboss.jbossfaces.WAR_BUNDLES_JSF_IMPL</param-name>
<param-value>true</param-value>
</context-param>
<!-- TAGLIB: Facelets and JSF -->
<context-param>
<param-name>facelets.LIBRARIES</param-name>
<param-value>
/WEB-INF/taglibs/security.taglib.xml;
/WEB-INF/taglibs/UIIterator.taglib.xml;
/WEB-INF/taglibs/jstlFMT.taglib.xml
</param-value>
</context-param>
<taglib>
<taglib-uri>http://www.springframework.org/security/tags</taglib-uri>
<taglib-location>/WEB-INF/taglibs/security.tld</taglib-location>
</taglib>
<!-- LOG4J -->
<context-param>
<param-name>log4jConfigLocation</param-name>
<param-value>/WEB-INF/log4j.xml</param-value>
</context-param>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/springConfig/web-application-config.xml
</param-value>
</context-param>
<context-param>
<param-name>log4jRefreshInterval</param-name>
<param-value>1000</param-value>
</context-param>
<!-- SPRING -->
<listener>
<listener-class>
org.springframework.web.util.Log4jConfigListener
</listener-class>
</listener>
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
<listener>
<listener-class>
org.springframework.web.context.request.RequestContextListener
</listener-class>
</listener>
<listener>
<listener-class>
com.sun.faces.config.ConfigureListener
</listener-class>
</listener>
<!-- Enforce UTF-8 Character Encoding -->
<filter>
<filter-name>charEncodingFilter</filter-name>
<filter-class>
org.springframework.web.filter.CharacterEncodingFilter
</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>charEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>
org.springframework.web.filter.DelegatingFilterProxy
</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>FORWARD</dispatcher>
<dispatcher>REQUEST</dispatcher>
</filter-mapping>
<!-- RICHFACES -->
<context-param>
<param-name>org.ajax4jsf.VIEW_HANDLERS</param-name>
<param-value>com.sun.facelets.FaceletViewHandler</param-value>
</context-param>
<context-param>
<param-name>org.richfaces.SKIN</param-name>
<param-value>blueSky</param-value>
</context-param>
<filter>
<filter-name>richfaces</filter-name>
<filter-class>org.ajax4jsf.Filter</filter-class>
</filter>
<filter-mapping>
<filter-name>richfaces</filter-name>
<servlet-name>FacesServlet</servlet-name>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
<dispatcher>INCLUDE</dispatcher>
</filter-mapping>
<!-- SPRING & FACES -->
<servlet>
<servlet-name>FacesServlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>FacesServlet</servlet-name>
<url-pattern>*.xhtml</url-pattern>
</servlet-mapping>
<!-- WEB SERVICES -->
<!--
<servlet> <servlet-name>AxisServlet</servlet-name>
<servlet-class>org.apache.axis.transport.http.AxisServlet
</servlet-class> <init-param>
<param-name>axis.ServerConfigFile</param-name>
<param-value>server-config.wsdd</param-value> </init-param>
<load-on-startup>1</load-on-startup> </servlet> <servlet-mapping>
<servlet-name>AxisServlet</servlet-name>
<url-pattern>/services/*</url-pattern> </servlet-mapping>
<servlet-mapping> <servlet-name>AxisServlet</servlet-name>
<url-pattern>*.jws</url-pattern> </servlet-mapping> <servlet>
<display-name>Axis Admin Servlet</display-name>
<servlet-name>AdminServlet</servlet-name> <servlet-class>
org.apache.axis.transport.http.AdminServlet </servlet-class>
<load-on-startup>1</load-on-startup> </servlet> <servlet-mapping>
<servlet-name>AdminServlet</servlet-name>
<url-pattern>/servicesAdmin/*</url-pattern> </servlet-mapping>
-->
<!-- Java Web Start -->
<servlet>
<servlet-name>JnlpDownloadServlet</servlet-name>
<!--
<servlet-class>com.sun.javaws.servlet.JnlpDownloadServlet</servlet-class>
-->
<servlet-class>jnlp.sample.servlet.JnlpDownloadServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>JnlpDownloadServlet</servlet-name>
<url-pattern>*.jnlp</url-pattern>
</servlet-mapping>
<!-- Spring controller -->
<servlet>
<servlet-name>springController</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value />
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springController</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
<!-- Welcome files -->
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
<welcome-file>index.jsf</welcome-file>
<welcome-file>index.html</welcome-file>
<welcome-file>index.xhtml</welcome-file>
</welcome-file-list>
</web-app> |
Fichier Spring général:
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
|
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:jee="http://www.springframework.org/schema/jee"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:security="http://www.springframework.org/schema/security"
xmlns:ctx="http://sannotations.sourceforge.net/context"
xmlns:web="http://www.springframework.org/schema/webflow-config"
xsi:schemaLocation="
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-2.5.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-2.5.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-2.0.4.xsd
http://sannotations.sourceforge.net/context http://sannotations.sourceforge.net/context.xsd
http://www.springframework.org/schema/webflow-config http://www.springframework.org/schema/webflow-config/spring-webflow-config-2.0.xsd"
default-autowire="byName">
<ctx:annotation-autoload />
<!-- Scans for application @Components to deploy -->
<!-- <context:component-scan base-package="be.cyberplongeurs" />-->
<!-- LOG4j -->
<bean id="loggerListener"
class="org.springframework.security.event.authentication.LoggerListener" />
<!-- Internalization - Message translation -->
<bean id="messageSource"
class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basenames">
<list>
<value>MessageResources</value>
</list>
</property>
</bean>
<!-- Internationalization - Parameter resolver -->
<bean id="localeChangeInterceptor"
class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor">
<property name="paramName" value="language" />
</bean>
<!-- Internationalization - Cookie locale resolver -->
<bean id="localeResolver"
class="be.cyberplongeurs.spring.CookieLocaleResolver">
<property name="nextLocaleResolver" ref="sessionLocaleResolver" />
</bean>
<!-- Internationalization - Session locale resolver -->
<bean id="sessionLocaleResolver"
class="be.cyberplongeurs.spring.SessionLocaleResolver">
<property name="nextLocaleResolver" ref="headerLocaleResolver" />
</bean>
<!-- Internationalization - Request locale resolver -->
<bean id="headerLocaleResolver" class="be.cyberplongeurs.spring.AcceptHeaderLocaleResolver" />
<!-- MVC - View resolver -->
<bean id="viewMappings"
class="org.springframework.web.servlet.view.ResourceBundleViewResolver">
<property name="basename" value="views" />
</bean>
<!--<bean id="exceptionResolver" class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">-->
<!-- <property name="defaultErrorView" value="/error.xhtml"/>-->
<!-- <property name="exceptionMappings">-->
<!-- <props>-->
<!-- <prop key="java.lang.NullPointerException">friendlyError</prop> -->
<!-- </props>-->
<!-- </property>-->
<!--</bean> -->
<import resource="data-access-config.xml" />
<import resource="security-config.xml" />
<import resource="webmvc-config.xml" />
</beans> |
Spring security:
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158
|
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:security="http://www.springframework.org/schema/security"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-2.0.2.xsd">
<security:global-method-security secured-annotations="enabled"
jsr250-annotations="enabled" />
<bean id="securityContext"
class="org.springframework.security.context.SecurityContextHolder"
factory-method="getContext" />
<bean id="springSecurityFilterChain"
class="org.springframework.security.util.FilterChainProxy">
<security:filter-chain-map path-type="ant">
<security:filter-chain pattern="/**"
filters="httpSessionContextIntegrationFilter,authenticationProcessingFilter,logoutFilter,rememberMeProcessingFilter,anonymousProcessingFilter,exceptionTranslationFilter,filterSecurityInterceptor" />
</security:filter-chain-map>
</bean>
<bean id="httpSessionContextIntegrationFilter"
class="org.springframework.security.context.HttpSessionContextIntegrationFilter" />
<!-- localeChangeFilter -->
<!-- <bean id="localeChangeFilter" class="be.cyberplongeurs.spring.security.LocaleChangeFilter">-->
<!-- <property name="localeChangeInterceptor" ref="localeChangeInterceptor" />-->
<!-- </bean> -->
<bean id="authenticationProcessingFilter"
class="org.springframework.security.ui.webapp.AuthenticationProcessingFilter">
<property name="authenticationManager" ref="myAuthenticationManager" />
<security:custom-filter position="AUTHENTICATION_PROCESSING_FILTER" />
<property name="authenticationFailureUrl" value="/login.do?login_error=1" />
<property name="defaultTargetUrl" value="/" />
<property name="alwaysUseDefaultTargetUrl" value="true" />
<property name="filterProcessesUrl" value="/j_spring_security_check" />
<property name="rememberMeServices" ref="rememberMeServices" />
</bean>
<bean id="anonymousProcessingFilter"
class="org.springframework.security.providers.anonymous.AnonymousProcessingFilter">
<property name="key" value="anonymousKey" />
<property name="userAttribute" value="anonymous,ROLE_ANONYMOUS" />
</bean>
<bean id="anonymousAuthenticationProvider"
class="org.springframework.security.providers.anonymous.AnonymousAuthenticationProvider">
<property name="key" value="anonymousKey" />
</bean>
<bean id="logoutFilter"
class="org.springframework.security.ui.logout.LogoutFilter">
<constructor-arg value="/" />
<constructor-arg>
<list>
<ref local="securityContextLogoutHandler" />
<ref local="rememberMeServices" />
</list>
</constructor-arg>
<property name="filterProcessesUrl" value="/logout" />
</bean>
<bean id="securityContextLogoutHandler"
class="org.springframework.security.ui.logout.SecurityContextLogoutHandler" />
<bean id="filterSecurityInterceptor"
class="org.springframework.security.intercept.web.FilterSecurityInterceptor">
<property name="authenticationManager" ref="myAuthenticationManager" />
<property name="accessDecisionManager" ref="accessDecisionManager" />
<property name="objectDefinitionSource">
<security:filter-invocation-definition-source>
<!-- TESTS -->
<security:intercept-url pattern="/login.do*"
access="ROLE_ANONYMOUS" />
<security:intercept-url pattern="/admin/*"
access="ROLE_ADMIN" />
</security:filter-invocation-definition-source>
</property>
</bean>
<bean id="accessDecisionManager"
class="org.springframework.security.vote.AffirmativeBased">
<property name="allowIfAllAbstainDecisions"
value="false" />
<property name="decisionVoters">
<list>
<bean class="org.springframework.security.vote.RoleVoter">
<property name="rolePrefix" value="ROLE_" />
</bean>
<bean class="org.springframework.security.vote.AuthenticatedVoter" />
</list>
</property>
</bean>
<security:authentication-manager alias="authenticationManager" />
<bean id="myAuthenticationManager"
class="be.cyberplongeurs.spring.security.AuthentificationManagerImpl">
<property name="sessionFactory" ref="sessionFactoryBean" />
<property name="userDetailService" ref="authenticationProvider" />
</bean>
<security:authentication-provider
user-service-ref="authenticationProvider" />
<bean id="authenticationProvider"
class="be.cyberplongeurs.spring.security.UserDetailsServiceImpl">
<property name="sessionFactory" ref="sessionFactoryBean" />
</bean>
<bean id="authenticationProcessingFilterEntryPoint"
class="org.springframework.security.ui.webapp.AuthenticationProcessingFilterEntryPoint">
<property name="loginFormUrl" value="/login.do" />
<property name="forceHttps" value="false" />
</bean>
<bean id="exceptionTranslationFilter"
class="org.springframework.security.ui.ExceptionTranslationFilter">
<property name="authenticationEntryPoint"
ref="authenticationProcessingFilterEntryPoint" />
<property name="accessDeniedHandler">
<bean class="org.springframework.security.ui.AccessDeniedHandlerImpl">
<property name="errorPage" value="/accessDenied.do" />
</bean>
</property>
</bean>
<!-- REMEMBER ME -->
<bean id="rememberMeProcessingFilter"
class="org.springframework.security.ui.rememberme.RememberMeProcessingFilter">
<property name="rememberMeServices" ref="rememberMeServices" />
<property name="authenticationManager" ref="myAuthenticationManager" />
</bean>
<bean id="rememberMeServices"
class="org.springframework.security.ui.rememberme.TokenBasedRememberMeServices">
<property name="userDetailsService" ref="authenticationProvider" />
<property name="key" value="cyberplongeurs" />
<property name="alwaysRemember" value="false" />
<property name="tokenValiditySeconds" value="864000" />
<property name="parameter" value="security_remember_me" />
</bean>
<bean id="rememberMeAuthenticationProvider"
class="org.springframework.security.providers.rememberme.RememberMeAuthenticationProvider">
<property name="key" value="cyberplongeurs" />
</bean>
<bean id="conversationScopeBean"
class="net.sourceforge.sannotations.scopes.ConversationScope" /> <!-- bean annotations -->
<bean id="flashScopeBean"
class="net.sourceforge.sannotations.scopes.FlashScope" /> <!-- bean annotations -->
<bean id="dataModelfactoryRegistry"
class="net.sourceforge.sannotations.jsf.utils.DataModelFactoryRegistry" /> <!-- bean annotations -->
</beans> |
Le code qui va déterminer la page à exécuter en fonction de l'URL:
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
|
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:beans="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:jee="http://www.springframework.org/schema/jee" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:util="http://www.springframework.org/schema/util" xmlns:security="http://www.springframework.org/schema/security"
xmlns:ctx="http://sannotations.sourceforge.net/context"
xmlns:web="http://www.springframework.org/schema/webflow-config"
xsi:schemaLocation="
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-2.5.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-2.5.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-2.0.4.xsd
http://sannotations.sourceforge.net/context http://sannotations.sourceforge.net/context.xsd
http://www.springframework.org/schema/webflow-config http://www.springframework.org/schema/webflow-config/spring-webflow-config-2.0.xsd">
<!-- Finding controller with annotation -->
<bean
class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" />
<bean
class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">
<property name="interceptors">
<list>
<ref bean="localeChangeInterceptor" />
</list>
</property>
</bean>
</beans> |