Spring Security:MessageSource未初始化 - 在通过上下文访问消息之前调用'refresh'

时间:2011-12-29 18:52:54

标签: spring spring-mvc spring-security

我知道这个错误的原因(可能是配置问题,或更现实的springframework / spring安全问题),但我不知道如何修复它。

这是堆栈跟踪(仅包含原因类):

...
at org.springframework.context.support.AbstractApplic ationContext.getMessageSource(AbstractApplicationC ontext.java:1224)
at org.springframework.context.support.AbstractApplic ationContext.getMessage(AbstractApplicationContext .java:1206)
at org.springframework.context.support.MessageSourceA ccessor.getMessage(MessageSourceAccessor.java:83)
at org.springframework.security.access.vote.Affirmati veBased.decide(AffirmativeBased.java:83)
at org.springframework.security.config.http.DefaultFi lterChainValidator.checkLoginPageIsntProtected(DefaultFilterChainValidator.java:170)
at org.springframework.security.config.http.DefaultFi lterChainValidator.validate(DefaultFilterChainValidator.java:35)
at org.springframework.security.web.FilterChainProxy. afterPropertiesSet(FilterChainProxy.java:148)
...

原因如下:

  1. / signin URL受保护,因此DefaultFilterChainValidator.checkLoginPageIsntProt ected()失败,
  2. AffirmativeBased.decide()尝试抛出异常:

    ...
    if (deny > 0) {
    throw new AccessDeniedException(messages.getMessage("AbstractAccessDecisionManager.accessDenied",
    "Access is denied"));
    }
    ...
    
  3. 此处提取消息,SpringSecurityMessageSource类用于此目的:

    public class SpringSecurityMessageSource extends ResourceBundleMessageSource {
    
    
    public SpringSecurityMessageSource() {
    setBasename("org.springframework.security.messages ");
    }
    
    public static MessageSourceAccessor getAccessor() {
        return new MessageSourceAccessor(new SpringSecurityMessageSource());
    }
    }
    
  4. 实际上如果AbstractAccessDecisionManager没有实现MessageSourceAware,一切都应该工作,因为(参见附件截图),由于未知原因XmlWebApplicationContext正在尝试重写有效的初始化MessageSourceAccessor(再次参见截图)(是的,XmlWebApplicationContext实现了MessageSource)实际上),但这种行为很奇怪(或者我错过了什么?)。

    当然,在此初始化之后,messageSource为null,并且无法检索所需的消息。

    这个特定的问题可以通过提供访问(permitAll)到/ signin(真正必须做的事情)来修复,但这不是案例,案例是如何解决这个问题,在错误的情况下,我可以看到将使用详细消息和org.springframework.security.message,但不会覆盖。

    最后一点,< debug />如果您有兴趣,请使用。我使用spring security 3.1.0.RELEASE和spring framework 3.1.0.RELEASE。 Spring Security MessageSource

2 个答案:

答案 0 :(得分:1)

Spring Framework和Spring Security之间存在冲突,虽然在不同的发布计划中,但恰好恰好具有相同的版本。 Spring Security依赖于Spring Framework 3.0.6,并且Maven在排除这些旧的依赖项方面做得不是很好。

需要从Spring Security依赖项中明确排除Spring Framework工件,如下所示:

    <dependency>
        <groupId>org.springframework.security</groupId>
        <artifactId>spring-security-core</artifactId>
        <version>3.1.0.RELEASE</version>
        <exclusions>
            <exclusion>
                <groupId>org.springframework</groupId>
                <artifactId>spring-expression</artifactId>
            </exclusion>
            <exclusion>
                <groupId>org.springframework</groupId>
                <artifactId>spring-context</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    <dependency>
        <groupId>org.springframework.security</groupId>
        <artifactId>spring-security-web</artifactId>
        <version>3.1.0.RELEASE</version>
        <exclusions>
            <exclusion>
                <groupId>org.springframework</groupId>
                <artifactId>spring-expression</artifactId>
            </exclusion>
            <exclusion>
                <groupId>org.springframework</groupId>
                <artifactId>spring-context</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    <dependency>
        <groupId>org.springframework.security</groupId>
        <artifactId>spring-security-config</artifactId>
        <version>3.1.0.RELEASE</version>
        <exclusions>
            <exclusion>
                <groupId>org.springframework</groupId>
                <artifactId>spring-context</artifactId>
            </exclusion>
        </exclusions>
    </dependency>

来自http://raibledesigns.com/rd/entry/upgrading_appfuse_to_spring_security

答案 1 :(得分:0)

如果ApplicationContext声明的类路径出现错误,也可能发生此错误:

private ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
                                                                            ^ ^