由于某种原因(我真的不能记住为什么:))我决定只使用Java来配置Spring应用程序。另外我会尽量避免使用web.xml
我从接下来的两个java配置文件开始。 ApplicationBootstrap.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
答案 0 :(得分: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
btw ...如果没有上述内容,也可以手动进行注册:
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。 :)
答案 1 :(得分: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
指定的应用程序上下文(称之为Root Web Application Context
),第二个使用DispatcherServlet
(称之为Servlet Web Application Context
),它实际上是根上下文的子项,并且在根上下文中定义了bean。根上下文包含与核心应用程序相关的bean(服务,存储库,entityManagers,安全性等),而servlet应用程序上下文仅包含Spring MVC(控制器,视图解析器等)所需的内容。现在,在您的情况下,您已将ApplicationConfig
指定为根上下文和servlet上下文的一部分,这不是必需的。您可以使用ApplicationConfig
作为根上下文,并为Web应用程序上下文使用不同的MVC特定上下文。
答案 2 :(得分:1)
如果您使用的是Spring 3.1+,那么您可以尝试将上下文配置片段添加到web.xml;将它们捆绑在一起。为了简单地让它在没有web配置的情况下工作,请尝试以下内容:
servletContext.addFilter(
"springSecurityFilterChain",
new DelegatingFilterProxy("springSecurityFilterChain"))
.addMappingForUrlPatterns(null, false, "/*");
答案 3 :(得分:0)
来自DeleagatingFilterProxy doc
标准Servlet 2.3 Filter的代理,委托给实现Filter接口的Spring管理的bean。
默认情况下,此实现将委托对bean的所有调用与过滤器同名。 (在你的情况下是filterChainProxy
)。所以你需要定义一个名为filterChainProxy
的bean,这个bean必须实现Filter
接口
但Spring Security提供了一个名为springSecurityFilterChain
的bean,它实现了Filter
,适用于spring安全性。因此,请将过滤器的名称更改为springSecurityFilterChain
。
此link可能会对您有所帮助