【问题标题】:How to implement Spring Security 4 with both XML and Java config如何使用 XML 和 Java 配置实现 Spring Security 4
【发布时间】:2015-08-12 18:06:32
【问题描述】:

我正在尝试将 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 {

}

春季文档说:

相反,我们应该使用现有的注册 Spring Security 应用程序上下文。例如,如果我们使用 Spring MVC 我们的 SecurityWebApplicationInitializer。

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

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

【问题讨论】:

  • 我无法复制您提到的完全相同的问题,但是当我尝试时,以下更改对我有用。如果您已经按照答案完成,请发布您的 web.xml 以及您的 mvc 配置

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


【解决方案1】:

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

【讨论】:

  • 在哪里添加 AppConfig 类?你有一个例子吗?我在导入上下文 xml 后无法正常工作。就像他们不存在一样
【解决方案2】:

假设您想要让 Spring Security Java Config 仅使用 2 个类 SecurityConfigSecurityWebApplicationInitializer,您需要执行以下操作才能使其正常工作。请注意,我假设您的 spring mvc 配置仍然是 XML。请注意com.mkyong.web.config 包将具有SecurityConfigclass。这将确保 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>

【讨论】:

  • 您好 ArunM,我的 contextConfigLocation 包含我的 XML 上下文文件。我将几个模块链接在一起,即 web-context.xml、service-context.xml、data-context.xml。我无法将我的 XML 文件和 SecurityConfig 类组合在一起,它给出了一个错误:BeanDefinitionStoreException: IOException parsing XML document from ServletContext resource [/ca.abc.web.security];我已经坚持了5天了。我正在尝试各种组合。似乎我的 SecurityConfig 中的 @EnableWebSecurity 没有被拾取,即使我以某种方式让它无错误加载。
  • 我也尝试使用 SecurityConfig 而不是 SecurityWebApplicationInitializer 加载它。除了 SecurityWebApplicationInitializer,我还尝试通过过滤器中的 springSecurityFilterChain 在 web.xml 中定义它。但它仍然不起作用。我也尝试过使用其他 Spring Security jar,例如 spring-security-javaconfig,有时它运行时没有错误,但 Spring Security 从未被拾取。没有任何 URL 被提示登录。
  • 我仍然认为问题在于您的 SecurityConfig 不是您的“WebApplicationContext”的一部分。验证这一点的最简单方法是在正常工作的 Spring Security 应用程序中启动并检查日志中的 bean 列表,然后与您的应用程序进行比较
  • 我建议你按照stackoverflow.com/questions/19365366/…这里的方法,使用importResource混合Java和XML配置
  • ArunM,很遗憾,我无法按照您的建议配置我的 SecurityConfig。我尝试将我的其他上下文文件导入到 SecurityConfig 中,但没有成功。我也觉得这不是在我的 SecurityConfig 中包含上下文文件的正确方法。我看到你可以通过 java config 配置 Spring,这就是你放置上下文文件的地方,但对我来说,把所有东西都放在 java 中也太过分了。我发现这个链接可以使用 web.xml 启用 Spring Security,但它也没有任何其他上下文文件:baeldung.com/spring-security-login。可能不得不求助于xml。
【解决方案3】:

在您的 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" />

【讨论】:

    猜你喜欢
    • 2014-04-06
    • 2018-01-31
    • 2015-11-19
    • 2016-10-24
    • 1970-01-01
    • 2015-07-22
    • 2016-04-01
    • 2014-01-24
    • 2015-12-04
    相关资源
    最近更新 更多