春季安全无web.xml中(Spring Security without web.xml)

2019-08-05 23:18发布

什么是春季安全添加到使用Spring的新的Web应用程序是推荐的方式WebApplicationInitializer接口,而不是web.xml文件的? 我在寻找相当于:

<filter>
    <filter-name>springSecurityFilterChain</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>

UPDATE
所提供的答案是合理的,但他们都认为我有一个servletContext实例。 我已经通过的等级看WebApplicationInitializer S和我没有看到对servlet上下文任何访问,除非我选择覆盖Spring的初始化方法之一。 AbstractDispatcherServletInitializer.registerServletFilter似乎是明智的选择,但它不会默认为URL模式映射和我讨厌改变注册过滤器的一切,如果有更好的方法。

Answer 1:

这是我做的方式:

container.addFilter("springSecurityFilterChain", new DelegatingFilterProxy("springSecurityFilterChain"))
                    .addMappingForUrlPatterns(null, false, "/*");

容器是的一个实例ServletContext



Answer 2:

在春季安全参考回答了这个问题和解决方案取决于您是否在使用Spring或Spring MVC结合使用Spring安全。

以Spring Security没有Spring或Spring MVC

如果你使用Spring的安全与Spring或Spring MVC(即你没有一个现有的WebApplicationInitializer ),那么你需要提供以下附加类:

import org.springframework.security.web.context.*;

public class SecurityWebApplicationInitializer
    extends AbstractSecurityWebApplicationInitializer {

    public SecurityWebApplicationInitializer() {
        super(SecurityConfig.class);
    }
}

其中SecurityConfig是你的春季安全的Java配置类。

以Spring Security使用Spring或Spring MVC

如果您使用的Spring Security使用Spring或Spring MVC(即你有一个现有的WebApplicationInitializer ),那么首先您需要提供以下附加类:

import org.springframework.security.web.context.*;

public class SecurityWebApplicationInitializer
    extends AbstractSecurityWebApplicationInitializer {
}

然后,你需要确保你的春季安全Java配置类, SecurityConfig在这个例子中,在现有的春天或Spring MVC声明WebApplicationInitializer 。 例如:

import org.springframework.web.servlet.support.*;

public class MvcWebApplicationInitializer
    extends AbstractAnnotationConfigDispatcherServletInitializer {

    @Override
    protected Class<?>[] getRootConfigClasses() {
        return new Class[] {SecurityConfig.class};
    }

    // ... other overrides ...
}


Answer 3:

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,等...



Answer 4:

一些工作之后,我发现它其实很简单:

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 Security的信息参考。

因此,我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>

我无法得到它,如果我合并的工作RootConfigWebAppConfig类逼到WebAppConfig并且具有如下:

@Override
protected Class< ? >[] getRootConfigClasses() {
    return null;
}

@Override
protected Class< ? >[] getServletConfigClasses() {
    return new Class[] { WebAppConfig.class };
}


Answer 5:

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, "/*");
    }

}

此方案是用于执行其他过滤器之前执行的过滤器。 如果你想执行后其他文件管理器通过一个过滤器trueregistration.addMappingForUrlPatterns(EnumSet.of(DispatcherType.REQUEST), true, "/*"); 。 同时检查DispatcherType异步,前进等。



Answer 6:

面对同样的问题。 合并RootConfig和WebAppConfig - 不是最好的方式 - 因为这个我没有尝试这种解决方案。 尝试了所有其他的解决方案 - everty时间得到了“org.apache.catalina.core.StandardContext.startInternal错误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文件”)。 这让我做,在初始化器类:

servletContext.addFilter("securityFilter", new DelegatingFilterProxy("springSecurityFilterChain"))
            .addMappingForUrlPatterns(null, false, "/*");


Answer 7:

这是关系到那些有兴趣在春季启动与安全:你什么都不需要,春季启动拿起@components和解决其他问题



文章来源: Spring Security without web.xml