在Spring的嵌入式Jetty上配置Spring Security [英] Configure Spring Security on embedded Jetty in Spring

查看:97
本文介绍了在Spring的嵌入式Jetty上配置Spring Security的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个Spring bean定义文件,如下所示

<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"设置到filter bean上,但这不足为奇,不足为奇.

相关: 如何将Jetty嵌入Spring并使其使用与嵌入的相同的AppContext?

解决方案

我正在运行Jetty 6.1.4和Spring 3.0.5,但是我使用WEB-INF/web.xml以老式的方式进行操作. /p>

采用这种方法,将导致零问题.

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();
}

I have a Spring beans definition file, as below

<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>

When trying to start the context, I get the following exception

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)

This is using Spring 3.0.5.RELEASE

The exception is understandable, looking at the code and JavaDocs for DelegatingFilterProxy#findWebApplicationContext, which says

The WebApplicationContext must have already been loaded and stored in the ServletContext before this filter gets initialized (or invoked).

because I'm trying to create the filter as a (sub)property of the context handler, so it seems sensible that the context has not yet been initialized and thus neither has the Spring WAC.

What I'd like to know is how can I configure Spring Security in an embedded Jetty container that Spring itself is assembling?

It seems like there's a catch 22 scenario that just needs a late initialisation, but I can't find a suitable flag to twiddle. I've tried setting lazy-init="true" onto the filter bean, but that didn't seem to achieve much, unsurprisingly.

Related: How to embed Jetty into Spring and make it use the same AppContext it was embedded into?

解决方案

I am running Jetty 6.1.4 and Spring 3.0.5, but I am doing it the old fashioned way, with WEB-INF/web.xml.

With that approach, it's causing zero problems.

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();
}

这篇关于在Spring的嵌入式Jetty上配置Spring Security的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆