在 Spring 中在嵌入式 Jetty 上配置 Spring Security
Posted
技术标签:
【中文标题】在 Spring 中在嵌入式 Jetty 上配置 Spring Security【英文标题】:Configure Spring Security on embedded Jetty in Spring 【发布时间】:2011-10-02 23:13:52 【问题描述】:我有一个 Spring beans 定义文件,如下
<bean id="jettyZk" class="org.eclipse.jetty.server.Server" init-method="start" destroy-method="stop">
<!-- properties, threadPool, connectors -->
<property name="handler">
<bean class="org.eclipse.jetty.servlet.ServletContextHandler">
<property name="eventListeners">
<list>
<!-- my.ContextLoaderListener
* An ApplicationContextAware ContextLoaderListener that allows for using the current ApplicationContext,
* as determined by ApplicationContextAware, as the parent for the Root WebApplicationContext.
*
* Also provides for specifying the contextConfigLocation of the Root WebApplicationContext, because
* Eclipse Jetty 7 ServletContextHandler does not expose a setInitParameters method.
-->
<bean class="my.ContextLoaderListener">
<property name="contextConfigLocation" value="/META-INF/spring/applicationContext-securityZk.xml"/>
</bean>
<!-- not sure if this is needed, disabled for now -->
<!-- <bean class="org.springframework.web.context.request.RequestContextListener"/> -->
</list>
</property>
<property name="servletHandler">
<bean class="org.eclipse.jetty.servlet.ServletHandler">
<property name="filters">
<list>
<bean class="org.eclipse.jetty.servlet.FilterHolder">
<property name="name" value="springSecurityFilterChain"/>
<property name="filter">
<bean class="org.springframework.web.filter.DelegatingFilterProxy"/>
</property>
</bean>
</list>
</property>
<!-- filterMappings, servlets, servletMappings -->
</bean>
</property>
</bean>
</property>
</bean>
当尝试启动上下文时,我得到以下异常
Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: ServletContext must not be null
Caused by: java.lang.IllegalArgumentException: ServletContext must not be null
at org.springframework.util.Assert.notNull(Assert.java:112)
at org.springframework.web.context.support.WebApplicationContextUtils.getWebApplicationContext(WebApplicationContextUtils.java:109)
这是使用 Spring 3.0.5.RELEASE
异常是可以理解的,看DelegatingFilterProxy#findWebApplicationContext的代码和JavaDocs,上面写着
WebApplicationContext 必须已经加载并存储在 此过滤器被初始化(或调用)之前的 ServletContext。
因为我试图将过滤器创建为上下文处理程序的(子)属性,所以上下文尚未初始化似乎是明智的,因此 Spring WAC 也没有。
我想知道的是如何在 Spring 本身组装的嵌入式 Jetty 容器中配置 Spring Security?
似乎有一个 catch 22 场景,只需要后期初始化,但我找不到合适的标志来玩弄。我已经尝试将lazy-init="true"
设置到过滤器 bean 上,但这似乎并没有起到太大作用,这并不奇怪。
相关: How to embed Jetty into Spring and make it use the same AppContext it was embedded into?
【问题讨论】:
由于试图解决这个问题,我一直在研究 Spring JavaConfig,并且有一个相关的问题:***.com/questions/6683771/… 你有没有想出办法做到这一点?我有基本相同的问题。 我最终得到了一个基于 @Configuration 的设置 我正在处理类似的问题,您能指出任何好的信息来源或示例吗? 【参考方案1】:我正在运行 Jetty 6.1.4 和 Spring 3.0.5,但我使用的是老式的方式,使用 WEB-INF/web.xml。
使用这种方法,它会导致零问题。
public class JettyServer
public static void main(String[] args) throws Exception
Properties props = new Properties();
props.load(new FileInputStream("./etc/server.properties"));
Server server = new Server();
final String configFile = props.getProperty("server.config");
XmlConfiguration configuration =
new XmlConfiguration(new File(configFile).toURI().toURL());
configuration.configure(server);
HandlerCollection handlers = new HandlerCollection();
WebAppContext webapp = new WebAppContext();
webapp.setContextPath(props.getProperty("context.path"));
webapp.setDefaultsDescriptor(props.getProperty("default.config"));
webapp.setWar(props.getProperty("war.path"));
NCSARequestLog requestLog = new NCSARequestLog(props.getProperty("log.file"));
requestLog.setExtended(true);
RequestLogHandler requestLogHandler = new RequestLogHandler();
requestLogHandler.setRequestLog(requestLog);
handlers.setHandlers(
new Handler[] webapp, new DefaultHandler(), requestLogHandler );
server.setHandler(handlers);
server.setStopAtShutdown(true);
server.setSendServerVersion(true);
server.start();
server.join();
【讨论】:
你让 Jetty 提供一个 WAR 文件,这不是我正在做的。 思考我又花了几个小时左右调试它是如何被调用的,而且我在运行时没有可用的org.eclipse.jetty.webapp
包,所以似乎无论我在哪里实例化 Spring过滤器 afterPropertiesSet 在我的 ServletContext 初始化之前被调用。我确实注意到我在错误的容器上设置了“过滤器”,所以我会更新问题中的示例,但我仍然卡住了。不过谢谢:)以上是关于在 Spring 中在嵌入式 Jetty 上配置 Spring Security的主要内容,如果未能解决你的问题,请参考以下文章
Embedded Jetty 无法识别 Spring MVC 安全性
Spring 3.1 WebApplicationInitializer & Embedded Jetty 8 AnnotationConfiguration