我正在尝试使用嵌入 Jetty 将摘要身份验证添加到通过 HTTP 提供的 API。我没有 web.xml,这不是 webapp。该应用程序通过从我的文件“spring-config.xml”创建一个 ClassPathXmlApplicationContext 对象来启动。在“spring-config.xml”中,我为服务等定义了许多 bean,还定义了一个用于启动 Jetty 服务器的 bean。
Jetty 服务器配置了一个 DispatcherServlet(实际上是一个 DispatcherServletWrapper 类,它实现了 ApplicationContextAware 并将 ClassPathXmlApplicationContext 对象设置为它创建的 GenericWebApplicationContext 的父级,这样它就可以访问我的 spring-config.xml 文件中定义的 bean)。
这一切都有效,它失败的地方是尝试添加身份验证。我添加了所有用于设置摘要身份验证的 spring-security 配置,但我不知道如何让 Jetty 了解过滤器链。
我的 spring-config.xml 的相关部分如下所示:
<bean id="restApiController" class="com.company.project.api.controllers.RESTfulController">
<property name="broker" ref="broker"/>
</bean>
<mvc:annotation-driven/>
<!--++++++++++++++++++++++
JETTY BEANS
+++++++++++++++++++++++-->
<security:authentication-manager alias="authenticationManager">
<security:authentication-provider>
<security:user-service id="userService">
<security:user name="apiUser" password="apiPassword" authorities="ROLE_USER"/>
</security:user-service>
</security:authentication-provider>
</security:authentication-manager>
<bean id="digestEntryPoint" class="org.springframework.security.web.authentication.www.DigestAuthenticationEntryPoint">
<property name="realmName" value="Digest Auth Realm"/>
<property name="key" value="acegi"/>
</bean>
<bean id="digestFilter" class="org.springframework.security.web.authentication.www.DigestAuthenticationFilter">
<property name="userDetailsService" ref="userService"/>
<property name="authenticationEntryPoint" ref="digestEntryPoint"/>
</bean>
<security:http create-session="stateless" use-expressions="true" entry-point-ref="digestEntryPoint">
<security:intercept-url pattern="/**" access="ROLE_USER"/>
<security:custom-filter ref="digestFilter" position="FIRST"/>
</security:http>
<bean id="JettyServer" class="org.eclipse.jetty.server.Server" init-method="start" destroy-method="stop">
<constructor-arg>
<bean id="threadPool" class="org.eclipse.jetty.util.thread.QueuedThreadPool">
<property name="minThreads" value="2"/>
<property name="maxThreads" value="10"/>
</bean>
</constructor-arg>
<property name="connectors">
<list>
<bean id="Connector" class="org.eclipse.jetty.server.ServerConnector">
<constructor-arg ref="JettyServer"/>
<property name="port" value="8090"/>
</bean>
</list>
</property>
<property name="handler">
<bean id="handlers" class="org.eclipse.jetty.server.handler.HandlerCollection">
<property name="handlers">
<list>
<bean id="servletContextHandler" class="org.eclipse.jetty.servlet.ServletContextHandler">
<property name="contextPath" value="/"/>
<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>
<!--<property name="filter" ref="digestFilter"/>-->
</bean>
</list>
</property>
<property name="filterMappings">
<list>
<bean class="org.eclipse.jetty.servlet.FilterMapping">
<property name="filterName" value="springSecurityFilterChain"/>
<property name="pathSpec"><value>/*</value></property>
</bean>
</list>
</property>
<property name="servlets">
<list>
<bean class="org.eclipse.jetty.servlet.ServletHolder">
<property name="name" value="DefaultServlet"/>
<property name="servlet">
<!--<bean class="org.springframework.web.servlet.DispatcherServlet"/>-->
<bean class="com.impulse.sessiontracker.api.DispatcherServletWrapper"/>
</property>
<!--
<property name="initParameters">
<map>
<entry key="contextConfigLocation" value="classpath:./spring-security.xml" />
</map>
</property>
-->
</bean>
</list>
</property>
<property name="servletMappings">
<list>
<bean class="org.eclipse.jetty.servlet.ServletMapping">
<property name="pathSpecs">
<list><value>/</value></list>
</property>
<property name="servletName" value="DefaultServlet"/>
</bean>
</list>
</property>
</bean>
</property>
</bean>
<bean class="org.eclipse.jetty.server.handler.RequestLogHandler">
<property name="requestLog">
<bean class="org.eclipse.jetty.server.NCSARequestLog">
<constructor-arg value="/opt/impulse/logs/jetty-yyyy_mm_dd.log"/>
<property name="extended" value="false" />
</bean>
</property>
</bean>
</list>
</property>
</bean>
</property>
</bean>
我试过直接在码头的过滤器列表中引用 DigestAuthenticationFilter ,这似乎不会导致任何事情发生。我已经尝试过上面显示的方法,我尝试引用 DelegatingFilterProxy,这会导致“ServletContext 不能为空”异常。根据我读过的一些 spring-docs 和其他问题,尝试并将其命名为“springSecurityFilterChain”是完整的猜测。
谁能告诉我如何获取 Jetty 使用的这些身份验证配置?我想做的事情有意义吗?
作为参考,我的 DispatcherServletWrapper 如下所示:
public class DispatcherServletWrapper extends DispatcherServlet implements ApplicationContextAware {
private static final long serialVersionUID = -2281511575328213502L;
private ApplicationContext appContext;
@Override
public void setApplicationContext(ApplicationContext arg0)
throws BeansException {
this.appContext = arg0;
}
protected WebApplicationContext createWebApplicationContext(WebApplicationContext arg0) {
GenericWebApplicationContext wac = new GenericWebApplicationContext();
wac.setParent(appContext);
wac.refresh();
return wac;
}
}