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



我正试图将Spring-Security 4实现到我的Spring MVC web和rest应用程序中。我添加了2个类来启用java配置方式的Spring Security。我仍然想保留我的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 };
}

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

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

我想这可能是第一个问题所在:

public class SecurityWebApplicationInitializer
  extends AbstractSecurityWebApplicationInitializer {
}

spring文档说:

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

这是否意味着在我的情况下,我可以采取SecurityConfig,应该使它成为一个bean?或者它还不是一个bean,因为它可以通过@Configuration发现?

我如何使安全配置通过XML识别,同时使用新的Java配置为好?

多亏了ArunM,我重新审视了我的问题,现在有了XML和Java配置组合。Spring MVC和web应用确实使用了web.xml和default-servlet.xml以及一个导入Spring安全性的java配置应用类。

@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类,通过将所有内容包含在一起来设置应用程序上下文。

假设您想让Spring Security Java Config只与两个类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>

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

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

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

<bean name="SecurityConfig" class="com.config.security.SecurityConfig" />

最新更新