嵌入式 Jetty 无法识别 Spring MVC 安全

Embedded Jetty doesn't recognise Spring MVC Security

我正在开发启动嵌入式 Jetty 服务器的 Spring 应用程序。然后它 "deploys" 一个 Spring MVC web 应用到这个 Jetty 服务器。

在多个控制器上一切正常,但我未能向 Web 应用程序添加 Spring 安全性。 我使用基于编程和注释的配置,Jetty 服务器配置如下:

Server server = new Server(8080);
server.setStopAtShutdown(true);
AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
context.setConfigLocation("com.mypackage.web");
context.setParent(mainContext);

ServletContextHandler contextHandler = new ServletContextHandler();
contextHandler.setErrorHandler(null);
contextHandler.setContextPath("/");

DispatcherServlet dispatcherServlet = new DispatcherServlet(context);
DefaultServlet staticServlet = new DefaultServlet();

contextHandler.addServlet(new ServletHolder(dispatcherServlet), "/");
contextHandler.addServlet(new ServletHolder("staticServlet", staticServlet), "/res");
contextHandler.addEventListener(new ContextLoaderListener(context));
contextHandler.setResourceBase("webapp");

server.setHandler(contextHandler);

我还创建了一个 class com.mypackage.web.SecurityConfig 来扩展 WebSecurityConfigurerAdapter 并覆盖配置方法,如下所示:

@Configuration
@EnableWebMvcSecurity  
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
                .anyRequest().authenticated()
                .and()
            .formLogin().and()
            .httpBasic();
    }
}

据我对文档的了解,这应该足以 "lock down" 我的应用程序。当我在调试模式下启动应用程序时,在配置方法中遇到断点,因此 Spring 似乎检测到配置 class.

但是,我仍然可以访问我的应用程序中的任何页面,而无需重定向到默认登录表单。

我是否需要将此配置告知 Jetty Servlet 容器,还是我遗漏了其他内容?

好的,所以我错过的是我需要将 Spring 的 DelegatingFilterProxy 添加到 Jetty 的 ServletContextHandler。通常的 Spring 方法是扩展 AbstractSecurityWebApplicationInitializer,它将添加 Filter Proxy。 不幸的是,这也不适用于 Jetty。

不过,可以通过 comment:

中解释的调用手动将过滤器代理添加到 Jetty
import static org.springframework.security.web.context.AbstractSecurityWebApplicationInitializer.DEFAULT_FILTER_NAME;
...
ServletContextHandler contextHandler = new ServletContextHandler();
...
contextHandler.addFilter(
    new FilterHolder( new DelegatingFilterProxy( DEFAULT_FILTER_NAME ) ),
    "/*",
    EnumSet.allOf( DispatcherType.class ));

我还必须在 Jetty 中启用 Session-Handling,但这解释得很好 here