如何使用XML和Java配置实现Spring Security 4

时间:2015-05-29 18:47:55

标签: spring-mvc spring-security spring-restcontroller

我正在尝试将Spring-Security 4实现到我的Spring MVC web和rest app中。我添加了2个类来启用Spring安全性的java配置方式。我仍然希望保留我的web.xml而不是将整个项目更改为使用java配置。一旦我这样做,我就会收到以下错误:

29-May-2015 08:47:12.826 SEVERE [localhost-startStop-1]  
org.apache.catalina.core.StandardContext.filterStart Exception starting   
filter springSecurityFilterChain
org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean   
named 'springSecurityFilterChain' is defined
at org.springframework.beans.factory.support.DefaultListableBeanFactory.
getBeanDefinition(DefaultListableBeanFactory.java:687)

正如您所看到的,它表示无法识别springSecurityFilterChain。这当然应该由@EnableWebSecurity启用,如下所示:

用于Spring Security的类:

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
  auth.inMemoryAuthentication().withUser("abc").password("123456").roles("USER");
  auth.inMemoryAuthentication().withUser("admin").password("123456").roles("ADMIN");
  auth.inMemoryAuthentication().withUser("dba").password("123456").roles("DBA");
}

@Override
protected void configure(HttpSecurity http) throws Exception {

  http.authorizeRequests()
    .antMatchers("/admin/**").access("hasRole('ROLE_ADMIN')")
    .antMatchers("/dba/**").access("hasRole('ROLE_ADMIN') or hasRole('ROLE_DBA')")
    .and().formLogin();

    }
}

public class SpringSecurityInitializer extends AbstractSecurityWebApplicationInitializer {
   //do nothing
}

奇怪的是,如果我将springSecurityFilterChain添加到我的web.xml,在运行时它会抱怨并说有一个重复的springSecurityFilterChain。我注意到最终在Java配置中,他们这样做:

public class MvcWebApplicationInitializer extends
    AbstractAnnotationConfigDispatcherServletInitializer {

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

他们使用MvcWebApp的Java配置注册SecurityConfig。 这基本上使它成为我相信的servlet上下文的一部分。

总而言之,我如何识别springSecurityFilterChain?我是否需要在web.xml或现有应用程序上下文中注册我的SecurityConfig类?

我认为这可能是第一个问题领域:

public class SecurityWebApplicationInitializer
  extends AbstractSecurityWebApplicationInitializer {

}

春天的文档说:

  

相反,我们应该使用现有的注册Spring Security   ApplicationContext中。例如,如果我们使用的是Spring MVC   SecurityWebApplicationInitializer。

在我的情况下,这是否意味着我可以使用SecurityConfig并且应该使它成为一个bean?或者它不是一个bean,因为它可以通过@Configuration来解决?

如何在使用新的Java配置时通过XML识别SecurityConfig?

3 个答案:

答案 0 :(得分:2)

感谢ArunM,我重新审视了我的问题,现在有了一个XML和Java配置组合。 Spring MVC和Web应用程序确实使用web.xml和default-servlet.xml PLUS导入Spring Security的java配置app类。

@Configuration
@Import({ SecurityConfig.class})
@ImportResource( {"classpath:web-context.xml",
   "classpath:service-context.xml","classpath:data-context.xml"})
public class AppConfig {
   public AppConfig() {
      super();
   }
}

我使用@Import批注导入Spring Security SecurityConfig类。

我还通过注释对我的所有上下文文件进行了contextConfigLocation扫描:@ImportResource。

诀窍不是通过contextConfigLocation加载SecurityConfig但是创建一个AppConfig类,通过将所有内容包含在一起来设置应用程序上下文。

答案 1 :(得分:1)

假设您想要的是让Spring Security Java Config只使用2个类SecurityConfigSecurityWebApplicationInitializer,您需要执行以下操作才能使其正常工作。请注意,我假设你的spring mvc配置仍然是XML。请注意,com.mkyong.web.config包将包含SecurityConfig类。这将确保Web上下文具有您的安全配置。

Web.xml如下

<context-param>
          <param-name>contextClass</param-name>
          <param-value>
              org.springframework.web.context.support.AnnotationConfigWebApplicationContext
          </param-value>
      </context-param>
      <context-param>
          <param-name>contextConfigLocation</param-name>
          <param-value>com.mkyong.web.config</param-value>
      </context-param>

   <listener>
      <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>

答案 2 :(得分:0)

在spring-context.xml中添加以下行:

SseBroadcaster

然后可以为安全配置添加bean定义。

<!-- to activate annotations in beans already registered in the application context -->
<context:annotation-config />