2013-07-11 2 views
2

Я следовал этим article попробовать основной HTTP-авторизацию без использования web.xmlTomcat 7 и AbstractSecurityWebApplicationInitializer не работают вместе

Я использую 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; 
// } 

} 

и, наконец, добавили класс inizialize в 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-аутентификации. А также SecurityConfiguration doens't даже загружаться.

ответ

7

SecurityInitializer создает DelegatingFilterProxy, который используется для поиска компонента по имени springSecurityFilterChain. SpringSecurityFilterChain создается с помощью @EnableWebSecurity. Проблема в том, что вам не хватает аннотации @Configuration (без нее корневой ApplicationContext даже не пытается загрузить SecurityConfiguration). В частности вы хотите сделать следующее:

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

несколько дополнительных вещей, укажут:

  • Вам не нужно использовать @Order, потому что вы не добавления каких-либо других фильтров
  • только URL, который вы создали, является корнем контекста (т.е. /).
  • Вы хотите быть в курсе бага с httpBasic(), который обсуждается на need spring security java config example showing basic auth only
  • UPDATE: Я должен также отметить, что я уже вошел SPR-10660 поддерживать @Enable* аннотаций без @Configuration на них. После того, как это будет разрешено, ваша проблема будет волшебным образом уйти.
+0

спасибо! И я читал его больше раз. Хотя этот вопрос был полезен, чтобы узнать об ошибке. Еще раз спасибо! – dierre

+0

Нет проблем @dierre :) Примечание. Я добавил обновление, относящееся к другой JIRA, которое, как только разрешилось, устранит эту проблему для вас. –

+0

Я вижу, что SPR-10660 по-прежнему не решен спустя 2,5 года. –