结合DispatcherServlet、ContextLoaderListener和SpringSecurity

5

我在这里有一个相当棘手的问题。一直在尝试将这3种技术整合到我们的webapp中。我们想使用:

  1. Spring Web
  2. 使用Spring MVC作为视图技术(带Freemarker)
  3. Spring Security作为安全层

但无论我如何配置web.xml和其他上下文文件,我都无法同时让所有东西都工作。 使用我的当前配置,除了SpringSecurity无法拦截URL模式之外,一切都可以正常工作。

通过一些搜索(和常识),我发现DispatcherServlet和ContextLoaderListener的组合可能会有问题。

以下是我的配置。 (很抱歉有这么多文字,感谢您的阅读):

web.xml:

<!-- Needed by Spring -->
<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<listener>
    <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
</listener>

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>/WEB-INF/dw-manager-context.xml</param-value>
</context-param>

<!-- Needed by Spring MVC -->
<servlet>
    <servlet-name>appServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/servlet-context.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
    <servlet-name>appServlet</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>

<!-- Needed by Spring Security -->
<filter>
    <filter-name>springSecurityFilterChain</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
    <filter-name>springSecurityFilterChain</filter-name>
    <url-pattern>/*</url-pattern>
    <dispatcher>FORWARD</dispatcher>
    <dispatcher>REQUEST</dispatcher>
</filter-mapping>

我的servlet-context.xml文件:

<!-- Scan for controllers -->
<context:component-scan base-package="dw.manager" />

<!-- Need to declare annotation driven transactions again so they are picked up above controller methods -->
<tx:annotation-driven transaction-manager="transactionManager" />

<mvc:annotation-driven />

<bean id="viewResolver"     class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver">
    <!-- ... -->
</bean>

<bean id="freemarkerConfig"
    class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
    <!-- ... -->
</bean>

我的manager-context.xml文件:

<context:annotation-config />   

    <!-- deployment-setup just loads properties (files) -->
<import resource="deployment-setup.xml" />
<import resource="spring-security-context.xml" />
<import resource="dw-manager-datasource.xml" />

<!-- Import sub-modules -->
<import resource="classpath:dw-security-context.xml" />
<!-- ... -->

Spring-Security-context.xml :

<http pattern="/login" security="none" />
<http pattern="/accessDenied" security="none" />
<http pattern="/" security="none" />

<!-- enable use of expressions, define URL patterns and login/logout forms 
    and targets) -->
<http use-expressions="true" access-denied-page="/accessDenied">
    <intercept-url pattern="/*" access="hasRole('ROLE_USER')" />
    <!-- more stuff -->
</http>

<!-- a lot more... -->

manager-datasource仅设置数据库...


感谢您阅读并希望能帮助我.. ;)


编辑:更多信息

我不能跳过ContextLoaderListener,因为它是SpringSecurity所需的。我也不能跳过contextConfigLocation,因为这是ContextLoaderListener所需的上下文。我只是自己定义名称,否则它将搜索一个applicationContext.xml。也许我可以添加一个空的contextConfigLocation?但这可能意味着底层模块无法找到要注入的bean..?


编辑2

我认为主要问题在于SpringSecurity需要一个webapp上下文(ContextLoaderListener)才能工作,但Web应用程序正在servlet上下文中运行。控制器方法由servlet上下文映射,因此在servlet上下文之外运行的spring security不会收到事件通知,过滤器也不会启动..


你能告诉我如果发送一个类似于/test的请求会发生什么吗?它会进入控制器还是被重定向到登录页面? - Arun P Johny
2012-06-11 15:31:23 PageNotFound [WARN] No mapping found for HTTP request with URI [/dw-manager/test] in DispatcherServlet with name 'appServlet' - Pete
如果您提供一个有效的URL,返回的响应是什么? - Arun P Johny
如果我输入/login,它将转到映射“/login”的控制器方法,然后返回登录页面。但/home是一个现有的页面,应该由SpringSecurity(<intercept-url pattern="/*")进行保护。它还有一个被忽略的@PreAuthorize注释...如果我忘记了某些东西,Spring Security甚至不会像通常那样抱怨没有安全上下文。 - Pete
让我们在聊天中继续这个讨论:http://chat.stackoverflow.com/rooms/12394/discussion-between-pete-and-arun-p-johny - Pete
显示剩余2条评论
1个回答

0

唉..我不知道为什么第一次没有起作用,可能是在尝试正确的解决方案时缓存了错误的解决方案..但现在它按照我发布的方式工作了。感谢你的时间,Arun。

现在唯一的问题是:spring-test-mvc不支持Spring Security的FilterChain,但这是另一个问题..


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接