Java Tomcat 7和AbstractSecurityWebApplicationInitializer不在一起工作

Java Tomcat 7和AbstractSecurityWebApplicationInitializer不在一起工作,java,spring-security,tomcat7,servlet-3.0,Java,Spring Security,Tomcat7,Servlet 3.0,我遵循这一点,尝试在不使用web.xml的情况下使用基本的http身份验证 我使用的是Tomcat 7.0.41,这些是我对gradle的依赖: ext.springVersion = "3.2.1.RELEASE" compile "org.springframework:spring-jdbc:$springVersion", "org.springframework:spring-context:$springVersion", "org.

我遵循这一点,尝试在不使用web.xml的情况下使用基本的http身份验证

我使用的是Tomcat 7.0.41,这些是我对gradle的依赖:

  ext.springVersion =  "3.2.1.RELEASE"
  compile "org.springframework:spring-jdbc:$springVersion",
          "org.springframework:spring-context:$springVersion",
          "org.springframework:spring-web:$springVersion",
          "org.springframework:spring-webmvc:$springVersion",
          "org.springframework.security:spring-security-core:3.2.0.M2",
          "org.springframework.security:spring-security-web:3.2.0.M2",
          "org.springframework.security:spring-security-config:3.2.0.M2",
根据教程,我定义了以下内容

@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

    @Override
    protected void registerAuthentication(AuthenticationManagerBuilder auth)
            throws Exception {
        auth.inMemoryAuthentication().withUser("admin").password("admin")
                .roles("USER");
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeUrls().antMatchers("/").hasRole("USER")
                .and().httpBasic();
    }

}
然后将该类添加到初始值设定项中,如下所示:

@Order(1)
public class ServletConfiguration extends
        AbstractAnnotationConfigDispatcherServletInitializer {

    @Override
    protected Class<?>[] getRootConfigClasses() {
        return new Class[] { SecurityConfiguration.class };
        // return null;
    }

    @Override
    protected Class<?>[] getServletConfigClasses() {
        return new Class[] { AppConfiguration.class };
    }

    @Override
    protected String[] getServletMappings() {
        return new String[] { "/" };
    }

//  @Override
//  protected Dynamic registerServletFilter(ServletContext servletContext,
//          Filter filter) {
//      Dynamic securityFilter = servletContext.addFilter(
//              "springSecurityFilterChain", DelegatingFilterProxy.class);
//      securityFilter.addMappingForUrlPatterns(
//              EnumSet.allOf(DispatcherType.class), false, "/*");
//      return securityFilter;
//  }

}
但我总是犯这样的错误:

DEBUG: org.springframework.jndi.JndiPropertySource - JNDI lookup for name [spring.liveBeansView.mbeanDomain] threw NamingException with message: Name [spring.liveBeansView.mbeanDomain] is not bound in this Context. Unable to find [spring.liveBeansView.mbeanDomain].. Returning null.
Jul 11, 2013 9:22:24 PM org.apache.catalina.core.StandardContext filterStart
SEVERE: Exception starting filter springSecurityFilterChain
org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'springSecurityFilterChain' is defined
我不知道为什么,因为在调试服务器初始化时,实际上调用了以下两种方法:

@Override
public final void onStartup(ServletContext servletContext)
        throws ServletException {
    if(enableHttpSessionEventPublisher()) {
        servletContext.addListener(HttpSessionEventPublisher.class);
    }
    insertSpringSecurityFilterChain(servletContext);
    afterSpringSecurityFilterChain(servletContext);
}
然后

所以实际上过滤器是被创建的。但是它会在某个地方丢失

我试着玩
@Order
,但没有任何效果,所以我尝试使用
registerServletFilter
方法注册
springSecurityFilterChain
,但我没有得到任何http身份验证请求。
而且,
SecurityConfiguration
甚至没有被加载。

SecurityInitializer创建DelegatingFilterProxy,用于以springSecurityFilterChain的名称查找bean。springSecurityFilterChain是使用@EnableWebSecurity创建的。问题是您缺少
@Configuration
注释(没有注释,根ApplicationContext甚至不会尝试加载SecurityConfiguration)。具体而言,您希望执行以下操作:

@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
...
}
需要指出的其他几点:

  • 您不需要使用
    @Order
    ,因为您没有添加任何其他筛选器
  • 您唯一保护的URL是上下文根(即/)
  • 您将希望了解上讨论的httpBasic()的错误
  • 更新:我还应该指出,我已经登录以支持
    @Enable*
    注释,而没有
    @Configuration
    。解决后,您的问题将神奇地消失

非常感谢!我读了很多遍。虽然这个问题对于了解bug很有用。再次感谢!没有问题@dierre:)注意,我添加了一个更新,涉及到另一个JIRA,一旦解决,将为您解决此问题。我发现SPR-10660在2.5年后仍未解决。@DerekMahar这实际上是作为另一个问题解决的(请参阅问题的更新)。你用Spring4.0+试过吗?没有,我没有用Spring4.0+试过。事实上,我从来没有遇到过这个问题!我只是路过这里,正在寻找另一个问题的解决方案,其中一个SpringMVC和安全应用程序两次实例化同一个bean。我通过更好地理解
@ComponentScan
的工作原理以及springmvc中root和dispatcher上下文之间的关系来解决这个问题。与这里的问题不太相关。无论如何,感谢您解析SPR-10660。
private void insertSpringSecurityFilterChain(ServletContext servletContext) {
    String filterName = "springSecurityFilterChain";
    DelegatingFilterProxy springSecurityFilterChain = new DelegatingFilterProxy(filterName);
    String contextAttribute = getWebApplicationContextAttribute();
    if(contextAttribute != null) {
        springSecurityFilterChain.setContextAttribute(contextAttribute);
    }
    registerFilter(servletContext, true, filterName, springSecurityFilterChain);
}
@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
...
}