我试图让Spring SecuirtyConfig使用Spring MVC和JavaConfig,我收到以下错误:
java.lang.IllegalStateException:找不到WebApplicationContext:没有注册ContextLoaderListener? org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:251)
这是我的SampleSimpleWebSecurityConfig:
@Configuration
@EnableWebSecurity
public class SampleSimpleWebSecurityConfig extends SimpleWebSecurityConfig {
private static final Logger logger = LoggerFactory.getLogger(SampleSimpleWebSecurityConfig.class);
protected void authorizeUrls(ExpressionUrlAuthorizationRegistry interceptUrls) {
logger.warn("* * Loadinging Role(s) * *");
interceptUrls
.antMatchers("/*").permitAll()
.antMatchers("/ask-union").hasRole("ROLE_VERIFIED_MEMBER");
}
protected void configure(
SecurityFilterChainSecurityBuilder springSecurityFilterChain) throws Exception {
springSecurityFilterChain
.formLogin()
.permitAll();
}
protected void registerAuthentication(AuthenticationRegistry registry) throws Exception {
registry
.inMemoryAuthentication()
.withUser("xxxx@aol.com.dev").password("testing").roles("ROLE_VERIFIED_MEMBER").and();
}
}
这是我的web.xml:
<servlet>
<servlet-name>Spring MVC Dispatcher Servlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextClass</param-name>
<param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext</param-value>
</init-param>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>org.xxxx.inquiryconfig</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Spring MVC Dispatcher Servlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<filter>
<filter-name>securityFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
<init-param>
<param-name>org.xxxx.inquiryconfig.SampleSimpleWebSecurityConfig</param-name>
<param-value>springSecurityFilterChain</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>securityFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
我的旧Spring Secuiryt XML:
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.1.xsd">
<global-method-security pre-post-annotations="enabled" />
<http use-expressions="true">
<intercept-url access="hasRole('ROLE_VERIFIED_MEMBER')" pattern="/ask**" />
<intercept-url pattern='/*' access='permitAll' />
<form-login default-target-url="/visit" />
<logout logout-success-url="/" />
</http>
<authentication-manager>
<authentication-provider>
<user-service>
<user name="XXXX@aol.com.dev" password="testing" authorities="ROLE_VERIFIED_MEMBER" />
</user-service>
</authentication-provider>
</authentication-manager>
</beans:beans>
答案 0 :(得分:4)
您的错误说明:
java.lang.IllegalStateException:找不到WebApplicationContext:没有注册ContextLoaderListener? org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:251)
所以只需在你的web.xml中注册一个ContextLoaderListener
,然后在过滤器和servlet之前注册。
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
对于applicationContext
,在web.xml中添加一个context参数
<context-param>
<param-name>contextClass</param-name>
<param-value>com.yourcompany.yourclass</param-value>
</context-param>
其中com.yourcompany.yourclass
是您的应用程序上下文配置类。
典型的Spring MVC应用程序有2个上下文,即应用程序上下文和servlet上下文,其中应用程序是根或父,servlet上下文是其子。 ContextLoaderListener侦听应用程序上下文,默认情况下可以在/WEB-INF/applicationContext.xml
中找到,这就是Spring在那里寻找它但无法找到它的原因。我假设您正在使用java @Configuration
类,因此请将其指向该类。
答案 1 :(得分:2)
Sotirios得到的这个大多是正确的。正如他所提到的,父母和孩子有两种不同的配置。我在下面发布的配置的变体可以在samples/social/src/main/webapp/WEB-INF/web.xml中找到(即使用Spring Social演示Spring Security Java Config)。
Spring Security通常在父上下文中配置。要在web.xml中使用Java Configuration执行此操作,您可以执行以下操作:
<!-- Java-based Spring container definition -->
<context-param>
<param-name>contextClass</param-name>
<param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext</param-value>
</context-param>
<!-- Location of Java @Configuration classes that configure the components that makeup this application -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>org.xxxx.inquiryconfig.SampleSimpleWebSecurityConfig</param-value>
</context-param>
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
<!-- use the springSecurityFilterChain -->
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
<!-- NOTE This does not specify its own configuration it is
loaded by the ContextLoaderListener instead -->
<!-- NOTE by default the filter name is used to
look up the Spring Security Filter Chain if you like you
can use any filter name you want, but you must specify
the bean name instead in this instance. Since we use the
springSecurityFilterChain as the filter name this is not
necessary
<init-param>
<param-name>targetBeanName</param-name>
<param-value>springSecurityFilterChain</param-value>
</init-param> -->
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
重要的是,Spring MVC配置和父上下文不会重叠,否则您将创建重复的对象(即父级中的一个和子级中的一个)。具体来说,您需要确保DispatcherServlet的contextConfigLocation不会加载与ContextLoaderListener的contextConfigLocation相同的类。
<强>更新强>
您还需要确保以正确的顺序指定您的网址。现在的问题是/ *匹配/ ask-union所做的相同的URL。请记住按顺序尝试每个模式。这意味着您应该如下所示更新配置,以便达到ask-union。您还想删除“ROLE_”部分,因为hasRole会自动将ROLE_前缀放入。
interceptUrls
.antMatchers("/ask-union").hasRole("VERIFIED_MEMBER")
.antMatchers("/*").permitAll();