将Spring Security添加到使用Spring的新WebApplicationInitializer
接口而不是web.xml文件的Web应用程序的推荐方法是什么?我正在寻找相当于:
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
更新
提供的答案是合理的,但他们都认为我有servletContext
个实例。我查看了WebApplicationInitializer
的层次结构,除非我选择覆盖Spring的初始化方法之一,否则我看不到对servlet上下文的任何访问。 AbstractDispatcherServletInitializer.registerServletFilter
似乎是明智的选择,但它并不默认为URL模式映射,如果有更好的方法,我不想更改所有内容的过滤器注册。
答案 0 :(得分:26)
这就是我做的方式:
container.addFilter("springSecurityFilterChain", new DelegatingFilterProxy("springSecurityFilterChain"))
.addMappingForUrlPatterns(null, false, "/*");
容器是ServletContext
答案 1 :(得分:14)
Spring Security Reference回答了这个问题,解决方案取决于您是否将Spring Security与Spring或Spring MVC结合使用。
如果你不使用带有Spring或Spring MVC的Spring Security(即你没有现有的WebApplicationInitializer
),那么你需要提供以下附加类:
import org.springframework.security.web.context.*;
public class SecurityWebApplicationInitializer
extends AbstractSecurityWebApplicationInitializer {
public SecurityWebApplicationInitializer() {
super(SecurityConfig.class);
}
}
SecurityConfig
是您的Spring Security Java配置类。
如果您在Spring或Spring MVC中使用Spring Security(即您已有WebApplicationInitializer
),那么首先需要提供以下附加类:
import org.springframework.security.web.context.*;
public class SecurityWebApplicationInitializer
extends AbstractSecurityWebApplicationInitializer {
}
然后,您需要确保在现有的Spring或Spring MVC SecurityConfig
中声明了此示例中的Spring Security Java配置类WebApplicationInitializer
。例如:
import org.springframework.web.servlet.support.*;
public class MvcWebApplicationInitializer
extends AbstractAnnotationConfigDispatcherServletInitializer {
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class[] {SecurityConfig.class};
}
// ... other overrides ...
}
答案 2 :(得分:8)
Dynamic securityFilter = servletContext.addFilter(AbstractSecurityWebApplicationInitializer.DEFAULT_FILTER_NAME, DelegatingFilterProxy.class);
securityFilter.addMappingForUrlPatterns(EnumSet.allOf(DispatcherType.class), false, "/*");
EnumSet.allOf(DispatcherType.class),以确保您不仅为默认的DispatcherType.REQUEST添加映射,而且为 DispatcherType.FORWARD 等添加映射。
答案 3 :(得分:3)
经过一番努力,我发现它实际上非常简单:
public class Initialiser extends AbstractAnnotationConfigDispatcherServletInitializer implements WebApplicationInitializer {
@Override
protected Class< ? >[] getRootConfigClasses() {
return new Class[] { RootConfig.class };
}
@Override
protected Class< ? >[] getServletConfigClasses() {
return new Class[] { WebAppConfig.class };
}
@Override
protected String[] getServletMappings() {
return new String[] { "/" };
}
@Override
protected Filter[] getServletFilters() {
return new Filter[] { new DelegatingFilterProxy("springSecurityFilterChain") };
}
}
但最重要的是,必须具有根上下文(例如,在这种情况下为RootConfig
),并且必须包含对所有spring安全信息的引用。
因此,我的RootConfig
课程:
@ImportResource("classpath:spring/securityContext.xml")
@ComponentScan({ "com.example.authentication", "com.example.config" })
@Configuration
public class RootConfig {
@Bean
public DatabaseService databaseService() {
return new DefaultDatabaseService();
}
@Bean
public ExceptionMappingAuthenticationFailureHandler authExceptionMapping() {
final ExceptionMappingAuthenticationFailureHandler emafh = new ExceptionMappingAuthenticationFailureHandler();
emafh.setDefaultFailureUrl("/loginFailed");
final Map<String, String> mappings = new HashMap<>();
mappings.put(CredentialsExpiredException.class.getCanonicalName(), "/change_password");
emafh.setExceptionMappings(mappings);
return emafh;
}
}
spring/securityContext.xml
:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:security="http://www.springframework.org/schema/security"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:noNamespaceSchemaLocation="http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd">
<security:http security="none" pattern="/favicon.ico"/>
<!-- Secured pages -->
<security:http use-expressions="true">
<security:intercept-url pattern="/login" access="permitAll" />
<security:intercept-url pattern="/**" access="isAuthenticated()" />
<security:form-login default-target-url="/index" login-processing-url="/login_form" login-page="/login" authentication-failure-handler-ref="authExceptionMapping" />
</security:http>
<security:authentication-manager>
<security:authentication-provider ref="customAuthProvider" />
</security:authentication-manager>
</beans>
如果我将RootConfig
和WebAppConfig
类合并到WebAppConfig
并且具有以下内容,则无法使其工作:
@Override
protected Class< ? >[] getRootConfigClasses() {
return null;
}
@Override
protected Class< ? >[] getServletConfigClasses() {
return new Class[] { WebAppConfig.class };
}
答案 4 :(得分:2)
public class SIServerSecurityWebApplicationInitializer extends AbstractSecurityWebApplicationInitializer {
@Override
protected void beforeSpringSecurityFilterChain(ServletContext servletContext) {
Dynamic registration = servletContext.addFilter("TenantServletFilter", TenantServletFilter.class);
EnumSet<DispatcherType> dispatcherTypes = getSecurityDispatcherTypes();
registration.addMappingForUrlPatterns(EnumSet.of(DispatcherType.REQUEST), false, "/*");
}
}
此方案用于在执行其他过滤器之前执行过滤器。
如果您想在其他文件管理器在true
中通过registration.addMappingForUrlPatterns(EnumSet.of(DispatcherType.REQUEST), true, "/*");
后执行过滤器。另请检查DispatcherType ASYNC,FORWARD等。
答案 5 :(得分:0)
面临同样的问题。合并RootConfig和WebAppConfig - 不是最好的方法 - 因为我没有尝试这个解决方案。尝试了所有其他解决方案 - everty time得到了“org.apache.catalina.core.StandardContext.startInternal Error filterStart”。经过一些工作,得到这样的东西:
FilterRegistration.Dynamic enc= servletContext.addFilter("encodingFilter",
new CharacterEncodingFilter());
encodingFilter .setInitParameter("encoding", "UTF-8");
encodingFilter .setInitParameter("forceEncoding", "true");
encodingFilter .addMappingForUrlPatterns(null, true, "/*");
但是没有使用DelegatingFilterProxy()。继续寻找所有过滤器的最佳通用解决方案。
<强>更新强> 我做到了。
所以,主要问题是:如果你想使用java配置添加过滤器,特别是如果你想添加安全过滤器,比如DelegatingFilterProxy,那么你必须创建WebAppSecurityConfig:
@Configuration
@EnableWebSecurity
@ImportResource("classpath:security.xml")
public class WebAppSecurityConfig extends WebSecurityConfigurerAdapter {
}
在这种情况下,我创建WebAppSecurityConfig并创建导入资源(“security.xml”)。 这让我在Initializer类中执行此操作:
servletContext.addFilter("securityFilter", new DelegatingFilterProxy("springSecurityFilterChain"))
.addMappingForUrlPatterns(null, false, "/*");
答案 6 :(得分:0)
这与那些对安全性感兴趣的Spring Boot感兴趣:你不需要任何东西,Spring Boot选择@components并解决其他问题