【问题标题】:Spring Security with AcceptHeaderLocaleResolver and i18n带有 AcceptHeaderLocaleResolver 和 i18n 的 Spring Security
【发布时间】:2011-09-28 04:18:51
【问题描述】:

我卡住了,可能错过了文档中的某些内容或犯了一些小错误。

Spring Security 3.0.5 已集成到我的 Spring MVC 3.0.5 应用程序中。 AcceptHeaderLocaleResolver 用于区域设置检测和本地化工作正常,但安全错误消息除外。

我从 spring 安全包中复制了 messages.properties 并重命名并添加到现有的 "messageSource" bean (ResourceBundleMessageSource) 与值列表。

如前所述,所有文本和消息都已正确本地化,除了使用硬编码英文消息的安全接缝。

有什么办法解决这个问题吗?

更新:
我的 xy-servlet.xml 包含:

...
<mvc:resources mapping="/resources/**" location="/resources/" />
...
<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
    <property name="basenames">
        <list>
            <value>defaultMessages</value>
            <value>securityMessages</value>
        </list>
    </property>
</bean>

和文件

  • defaultMessages.properties
  • defaultMessages_en.properties
  • defaultMessages_de.properties
  • defaultMessages_sl.properties

  • securityMessages.properties
  • securityMessages_en.properties
  • securityMessages_de.properties
  • securityMessages_sl.properties

但是defaultMessages 工作正常。 securityMessages 没有。我对所有 securityMessages 文件进行了小改动,但它们被忽略了,并且显示了硬编码的英文消息。

更新 v2: 我的 dispatcher-servlet.xml:

<?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:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:sec="http://www.springframework.org/schema/security"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd  
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
    http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
    http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd">

<context:component-scan base-package="com.example.sampleapp1" />
<context:annotation-config />

<mvc:annotation-driven/>

<!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the ${webappRoot}/resources/ directory -->
<mvc:resources mapping="/resources/**" location="/resources/" />

<bean id="viewResolver"
    class="org.springframework.web.servlet.view.InternalResourceViewResolver"
    p:prefix="/WEB-INF/views/" p:suffix=".jsp" />

<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
    <property name="basenames">
        <list>
            <value>defaultMessages</value>
            <value>securityMessages</value>
            <value>org/springframework/security/messages_de</value>
        </list>
    </property>
</bean> 

<!-- Persistence -->
<bean id="myPMF" class="org.springframework.orm.jdo.LocalPersistenceManagerFactoryBean">
    <property name="persistenceManagerFactoryName" value="transactions-optional"/>
</bean>     

<!-- Form Validator -->

</beans>

【问题讨论】:

    标签: java spring spring-mvc internationalization spring-security


    【解决方案1】:

    最后,解决方案!

    安全消息的 Bean 显然必须在 applicationContext-security.xml 中声明 而不是在应用程序上下文 xml 配置中......我在手册的任何地方都没有找到这个!

    在我的情况下,正确的解决方案是 applicationContext-security.xml 中的 bean:

        <b:bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
            <b:property name="basenames">
                <b:value>secMessages</b:value>
            </b:property>
        </b:bean>
    

    感谢 @bluefoot@jtoberon 提供一些想法。

    更新: 要正常工作,web.xml 必须在 springSecurityFilterChain 之前包含 localizationFilter,我的 web.xml 是:

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app version="2.5" 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/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
    
    <!-- The definition of the Root Spring Container shared by all Servlets and Filters -->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/spring/applicationContext-security.xml</param-value>
    </context-param>
    
    <!-- i18n -->
    <filter>
        <filter-name>localizationFilter</filter-name>
        <filter-class>org.springframework.web.filter.RequestContextFilter</filter-class>
    </filter>
    
    <filter>
        <filter-name>springSecurityFilterChain</filter-name>
        <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
    </filter>
    
    <!-- i18n -->
    <filter-mapping>
        <filter-name>localizationFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    
    <filter-mapping> 
      <filter-name>springSecurityFilterChain</filter-name> 
      <url-pattern>/*</url-pattern>
        <dispatcher>REQUEST</dispatcher>
        <dispatcher>FORWARD</dispatcher>
        <dispatcher>INCLUDE</dispatcher>
        <dispatcher>ERROR</dispatcher>
    </filter-mapping> 
    
    
    <!-- Creates the Spring Container shared by all Servlets and Filters -->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    
    <!-- Processes application requests -->
    <servlet>
        <servlet-name>appServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>/WEB-INF/spring/appServlet/servlet-context.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    
    <servlet-mapping>
        <servlet-name>appServlet</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
    
    </web-app>
    


    检查 i18n cmets 之后的行。

    【讨论】:

    • 我没有太多的Spring MVC经验,也不知道xy-servlet.xml这个文件不是应用上下文配置文件。无论如何,我很高兴它成功了。
    • 我正在使用 Spring 3.2,似乎也遇到了同样的问题,但不幸的是,这个解决方案似乎对我不起作用。
    【解决方案2】:

    我不知道你是怎么做到的(你没有说),但是要使用 spring security 附带的消息包(而不是硬编码的文本消息),我只需要声明一个 ResourceBundleMessageSource bean 并设置basenames 属性:

    <bean id="messageSource"
        class="org.springframework.context.support.ResourceBundleMessageSource">
        <property name="basenames">
            <list>
                <value>org/springframework/security/messages_pt_BR</value>
            </list>
        </property>
    </bean>
    

    这会将消息更改为 pt_BR,通过使用此 bean 而不是默认的 bean 来创建 spring(无需将文件复制到其他地方,当然,假设您的类路径中有 jar)。

    【讨论】:

    • @bluefoot 请检查我更新的问题。我不知道如何使用您的答案。我应该使用:&lt;value&gt;org/springframework/security/securityMessages_sl&lt;/value&gt;吗?
    • 为什么要创建自己的属性?其中一些已经进入 spring security core 的 jar 中。可能在类路径中找不到您的文件。只需删除&lt;value&gt;defaultMessages&lt;/value&gt; &lt;value&gt;securityMessages&lt;/value&gt; 并将其替换为&lt;value&gt;org/springframework/security/messages_de&lt;/value&gt;(假设xy-servlet.xml 是您的应用程序上下文配置文件),看看会发生什么。
    • 没区别,我不断收到硬编码的英文信息。仅供参考:defaultMessages 是我的应用自定义消息,多语言工作正常
    • 您能否发布您的整个应用程序上下文配置文件,以便我们看看有什么问题?
    【解决方案3】:

    这里有一些想法:

    1. 安全消息是否有可能不在类路径中?您的资源文件是否都在同一个目录中?您是否将它们放在 WEB-INF/classes 中,如果没有,那么您如何知道它们在类路径中?
    2. 您有命名空间或密钥冲突吗?换句话说,安全错误消息的默认值是否已在其他资源文件(正在工作的文件)中定义?

    【讨论】:

    • 感谢您的意见! 1. 如何检查消息是否在类路径中?所有文件都在同一个目录和 WEB-INF/classes 2. 在我的 defaultMessages 中,我不相信我有命名空间或密钥冲突。
    猜你喜欢
    • 1970-01-01
    • 2012-01-10
    • 2018-01-29
    • 2017-07-22
    • 2023-03-06
    • 2017-10-02
    • 1970-01-01
    • 1970-01-01
    • 2018-01-26
    相关资源
    最近更新 更多