【问题标题】:Extending SpringBootWebSecurityConfiguration with custom HttpSecurity configuration使用自定义 HttpSecurity 配置扩展 SpringBootWebSecurityConfiguration
【发布时间】:2016-04-01 23:33:22
【问题描述】:

我正在尝试更好地了解 Spring Boot 的自动配置。特别是,我需要添加一些自定义 spring 安全配置来禁用 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-method 和springs 自动配置都已执行,但看起来我的http-configuration 优先。

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

这个场景的最佳实践是什么?

【问题讨论】:

  • 你的 SecurityConfiguration 类不应该也用@EnableWebSecurity 注释吗?

标签: spring spring-security spring-boot


【解决方案1】:

您可以创建一个新的 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>

【讨论】:

  • 我一直在寻找一种可以让我扩展 Spring Boot 配置的解决方案。相反,您建议配置 Spring Boot 已经为我处理的过滤器映射。
【解决方案2】:

你不能这样做的原因是你缺少注释@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:

【讨论】:

  • 不,这不是原因,这将导致 Spring Boot 不使用自己的配置。我想扩展配置,而不是完全替换它。
猜你喜欢
  • 1970-01-01
  • 2012-11-08
  • 1970-01-01
  • 1970-01-01
  • 2015-10-28
  • 1970-01-01
  • 1970-01-01
  • 2015-07-13
  • 1970-01-01
相关资源
最近更新 更多