4

出于某种原因(我真的不记得为什么 :))我决定只使用 Java 来配置 Spring 应用程序。另外我会尽量避免使用 web.xml

我从以下两个 java 配置文件开始。应用程序引导程序.java

public class ApplicationBootstrap implements WebApplicationInitializer {
    //public class Initializer 
    public void onStartup(ServletContext servletContext) throws ServletException {
        AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext();
        rootContext.register(ApplicationConfig.class);
        rootContext.refresh();

    // Manage the lifecycle of the root appcontext
    servletContext.addListener(new ContextLoaderListener(rootContext));
    servletContext.setInitParameter("defaultHtmlEscape", "true");
    servletContext.setInitParameter("spring.profiles.active", "Production");


     // now the config for the Dispatcher servlet
    AnnotationConfigWebApplicationContext mvcContext = new AnnotationConfigWebApplicationContext();
        mvcContext.register(ApplicationConfig.class);
        mvcContext.getEnvironment().setActiveProfiles("Production");
        mvcContext.getEnvironment().setDefaultProfiles("Production");

    ServletRegistration.Dynamic dispatcher = servletContext.addServlet("dispatcher", new DispatcherServlet(mvcContext));
        dispatcher.setLoadOnStartup(1);
        dispatcher.addMapping("/api/*");


}

和 ApplicationConfig.java

@Configuration()
@Profile({"Production", "ControllerUnitTest"})
@EnableWebMvc
@ComponentScan( basePackages = "com.consius.activework.server"  ) 
@EnableAspectJAutoProxy
public class ApplicationConfig extends WebMvcConfigurerAdapter {


}

这按预期工作。没有我的问题开始了。我的想法是使用 spring-security,我寻找一种使用 Java 配置 spring-security 的方法。一段时间后我放弃了,我发现无法使用 Java 配置 spring-security。我决定回到 XML 进行安全配置。

我创建了一个包含以下内容的 web.xml:

   <filter>
        <filter-name>filterChainProxy</filter-name>
        <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>filterChainProxy</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

我在 ApplicationConfig.java 中添加了:

 @ImportResource( { "classpath:/spring-security.xml" } )

并创建了一个名为 spring-security.xml 的新 xml 文件

<security:http auto-config='true' create-session="never" realm="Restricted Service" use-expressions="true">
    <security:intercept-url pattern="/rest/**" access="permitAll()" />               
</security:http>

根据文档,这是最低配置。

尝试运行它会出现以下错误(我不明白为什么)

SEVERE: Exception starting filter filterChainProxy
org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'filterChainProxy' is defined
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanDefinition(DefaultListableBeanFactory.java:549)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getMergedLocalBeanDefinition(AbstractBeanFactory.java:1096)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:278)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:198)
    at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1121)
    at org.springframework.web.filter.DelegatingFilterProxy.initDelegate(DelegatingFilterProxy.java:326)
    at org.springframework.web.filter.DelegatingFilterProxy.initFilterBean(DelegatingFilterProxy.java:236)
    at org.springframework.web.filter.GenericFilterBean.init(GenericFilterBean.java:194)
    at org.apache.catalina.core.ApplicationFilterConfig.initFilter(ApplicationFilterConfig.java:281)

谁能帮我?我想我做了一些明显的错误,但我看不到它。

//lg

4

4 回答 4

11

坚持使用 Java 配置怎么样?

@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    // ...
}

public class WebSecurityInitializer 
        extends AbstractSecurityWebApplicationInitializer {
}

方便的是,WebSecurityInitializer 将为您注册 Spring Security Servlet 过滤器!这是一个很好的解释,有很多细节:

http://docs.spring.io/spring-security/site/docs/3.2.x/guides/helloworld.html

顺便说一句......如果没有上述内容,也可以手动进行注册:

public class DispatcherServletInitializer 
        extends AbstractAnnotationConfigDispatcherServletInitializer {

    @Override
    public void onStartup(ServletContext servletContext) 
            throws ServletException {
        servletContext
            .addFilter("securityFilter", 
                       new DelegatingFilterProxy("springSecurityFilterChain"))
            .addMappingForUrlPatterns(null, false, "/*");

        super.onStartup(servletContext);
    }

    // Various other required methods...

}

这样,您就可以忘记烦人的 web.xml。:)

于 2014-01-14T14:14:42.130 回答
6

安全过滤器的名称应该是springSecurityFilterChain,即 Spring-security 命名空间分配给 Spring bean 的名称。

<filter>
    <filter-name>springSecurityFilterChain</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
    <filter-name>springSecurityFilterChain</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

此外,您已经使用ApplicationConfig了根上下文(通过 ContextLoaderListener 加载)和 Web 应用程序上下文(通过 DispatcherServlet 加载),最好为两者保留不同的上下文并仅通过根上下文加载 Spring 安全性

更新 为了澄清您在评论中的问题 - Spring MVC 应用程序通常加载了 2 个应用程序上下文,您使用ContextLoaderListener(称为) 指定的一个,以及使用(称为 a )Root Web Application Context加载的第二个,这实际上是根上下文的子节点,并且在根上下文中定义了对它可见的 bean。根上下文包含与应用程序相关的核心 bean(服务、存储库、实体管理器、安全性等),而 servlet 应用程序上下文仅包含 Spring MVC 所需的东西(控制器、视图解析器等)。现在,在您的情况下,您已指定作为根上下文和 servlet 上下文的一部分,这不是必需的。您可以改为使用DispatcherServletServlet Web Application ContextApplicationConfigApplicationConfig只是作为根上下文并为 Web 应用程序上下文使用不同的 MVC 特定上下文。

于 2013-02-16T15:02:55.530 回答
1

如果您使用的是 Spring 3.1+,那么您可以尝试将上下文配置片段添加到 web.xml;这会将它们联系在一起。为了简单地让它在没有 web 配置的情况下工作,请尝试以下操作:

servletContext.addFilter(
            "springSecurityFilterChain",
            new DelegatingFilterProxy("springSecurityFilterChain"))
        .addMappingForUrlPatterns(null, false, "/*");
于 2013-04-24T01:38:06.410 回答
0

From DeleagatingFilterProxy doc

Proxy for a standard Servlet 2.3 Filter, delegating to a Spring-managed bean that implements the Filter interface.

By default, this implementation will delegate all calls to a bean with the same name as the filter. (in your case it is filterChainProxy). So you need to define a bean named filterChainProxy and this bean must implement the Filter interface

But Spring Security provides a bean named springSecurityFilterChain implementing Filter and suitable for spring security. So change the name of your filter to springSecurityFilterChain.

This link may help you

于 2013-02-16T14:55:38.877 回答