Embedded Jetty 无法识别 Spring MVC 安全性

Posted

技术标签:

【中文标题】Embedded Jetty 无法识别 Spring MVC 安全性【英文标题】:Embedded Jetty doesn't recognise Spring MVC Security 【发布时间】:2015-09-04 19:46:29 【问题描述】:

我正在开发一个启动嵌入式 Jetty 服务器的 Spring 应用程序。然后它将 Spring MVC Web 应用程序“部署”到此 Jetty 服务器。

所有控制器都可以很好地使用多个控制器,但我无法将 Spring Security 添加到 Web 应用程序。 我使用编程和基于注释的配置,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);

我还创建了一个扩展 WebSecurityConfigurerAdapter 的类 com.mypackage.web.SecurityConfig 并覆盖了 configure 方法,如下所示:

@Configuration
@EnableWebMvcSecurity  
public class SecurityConfig extends WebSecurityConfigurerAdapter 

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

据我了解文档,这应该足以“锁定”我的应用程序。当我在调试模式下启动应用程序时,在配置方法中遇到了一个断点,所以 Spring 似乎检测到了配置类。

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

我是否需要告诉 Jetty Servlet 容器有关此配置的信息,或者我是否遗漏了其他内容?

【问题讨论】:

【参考方案1】:

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

不过,可以手动将过滤器代理添加到 Jetty,在此 comment 中解释了一个调用:

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。

【讨论】:

这篇文章挽救了我的生命,但我会尝试改进它,建议使用 AbstractSecurityWebApplicationInitializer.DEFAULT_FILTER_NAME 而不是“springSecurityFilterChain”硬编码字符串 要启用会话,new ServletContextHandler(ServletContextHandler.SESSIONS) 适合我。

以上是关于Embedded Jetty 无法识别 Spring MVC 安全性的主要内容,如果未能解决你的问题,请参考以下文章

Embedded Jetty 从 6.1.7 升级到 9.4.43 的问题

Embedded Jetty - 禁用外部 URL 的 URL 重写

Embedded Jetty HTTP/2 不适用于 Firefox/Chrome,但在 Safari 上似乎没问题

Embedded Jetty:在安全的 https 服务器中,ContextHandler 重定向到 http URI

Spring Boot 使用Jar打包发布, 并使用 Embedded Jetty/Tomcat 容器

GWT+Jetty JSP 编译器问题的解决方法? (Java 1.5 源代码级别无法识别)