2

我正在关注这篇文章来尝试一个基本的 http-auth 而不使用 web.xml

我正在使用 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;
//  }

}

最后添加了一个类来初始化springSecurityFilterChain:

@Order(2)
public class SecurityInitializer extends AbstractSecurityWebApplicationInitializer  {
@Override
protected void afterSpringSecurityFilterChain(ServletContext servletContext) {
    System.out.println("afterSpringSecurityFilterChain");
    super.afterSpringSecurityFilterChain(servletContext);
}
}

但我总是收到这个错误:

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);
}

然后

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);
}

所以实际上过滤器被创建了。但后来它在某个地方迷路了。

我试着玩@Order,但那什么也没做,所以我尝试springSecurityFilterChain使用该registerServletFilter方法进行注册,但我没有得到任何 http-auth 请求身份验证。而且SecurityConfiguration甚至没有加载。

4

1 回答 1

7

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

@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
...
}

还有几点需要指出:

于 2013-07-11T19:51:18.693 回答