6

我正在尝试将 Spring-Security 4 实现到我的 Spring MVC web 和 rest 应用程序中。我添加了 2 个类来启用 Spring Security 的 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 {

}

春季文档说:

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

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

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

4

3 回答 3

3

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

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

于 2015-06-03T06:54:25.487 回答
2

假设您想要让 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>
于 2015-06-01T11:45:10.980 回答
0

在 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" />
于 2018-06-17T09:52:44.473 回答