使用自定义HttpSecurity配置扩展SpringBootWebSecurityConfiguration

时间:2016-04-01 14:54:42

标签: spring spring-security spring-boot

我正在努力更好地了解弹簧靴的自动配置。特别是我需要添加一些自定义弹簧安全配置来禁用HTTP OPTIONS动词的身份验证,以便让我的CORS请求正常工作。

默认情况下,没有任何自定义配置,SpringBootWebSecurityConfiguration由Spring Boot的自动配置加载。

我想要做的是继续使用此自动配置,但添加一些额外的http配置。我试过这个:

@Configuration
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

    Logger logger = LogManager.getLogger (SecurityConfiguration.class);
    @Override
    protected void configure (HttpSecurity http) throws Exception {
        logger.info ("--- ALLOW all HTTP OPTIONS Requests");
        http.authorizeRequests ().antMatchers (HttpMethod.OPTIONS, "*//**").permitAll ();
    }
}

但这不是例外。当我通过SpringBootWebSecurityConfiguration以及上面的代码进行调试时,我可以看到我的configure - 方法和弹簧自动配置都已执行,但它看起来像我的http - 配置优先。

这是否意味着自动配置仅以 all-or-nothing 方式提供?或者我可以使用自动配置,但仍然使用一些自定义antMatcher扩展它吗?

此方案的最佳做法是什么?

2 个答案:

答案 0 :(得分:0)

您可以创建一个新的servlet过滤器并将其放在Spring安全过滤器之前。例如:

@Component("CORSFilter")
public class CORSFilter implements Filter {

    public void doFilter(
        ServletRequest req, 
        ServletResponse res, 
        FilterChain chain) throws IOException,  ServletException {

        HttpServletRequest request = (HttpServletRequest) req;

        HttpServletResponse response = (HttpServletResponse) res;
        response.setHeader("Access-Control-Allow-Credentials", "true");
        response.setHeader("Access-Control-Allow-Origin", "THE_HOST_YOU_WANT_TO_ALLOW_HERE");
        response.setHeader("Access-Control-Allow-Methods", "POST, GET, DELETE, PUT, PATCH, OPTIONS");
        response.setHeader("Access-Control-Max-Age", "3600");
        response.setHeader("Access-Control-Allow-Headers",
                "origin, content-type, accept, x-requested-with, authorization");

        if (request.getMethod().equals("OPTIONS")) {
            try {
                response.getWriter().print("OK");
                response.getWriter().flush();
            } catch (IOException e) { 
                 //... 
            }
         } else {
             chain.doFilter(req, res);
        }

    }

    public void init(FilterConfig filterConfig) {
        //...
    }

    public void destroy() {
        //...
    }

}

然后将其添加到您的web.xml(如果您仅使用Java配置,则在WebInitializer中配置):

<filter>
    <filter-name>CORSFilter</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
    <init-param>
        <param-name>contextAttribute</param-name>
        <param-value>org.springframework.web.servlet.FrameworkServlet.CONTEXT.[YOUR_SERVLET_NAME]</param-value>
    </init-param>
</filter>
<filter-mapping>
    <filter-name>CORSFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

答案 1 :(得分:0)

你不能这样做的原因是你缺少注释@EnableWebSecurity,看看javadoc:

 * Add this annotation to an {@code @Configuration} class to have the Spring Security
 * configuration defined in any {@link WebSecurityConfigurer} or more likely by extending
 * the {@link WebSecurityConfigurerAdapter} base class and overriding individual methods: