JSF - Spring 安全集成问题
Posted
技术标签:
【中文标题】JSF - Spring 安全集成问题【英文标题】:JSF - Spring Security Integration issue 【发布时间】:2012-02-28 22:20:38 【问题描述】:Servlet 2.4+ API 允许我们在 <filter-mapping>
标记中使用 <dispatcher>
标记和 FORWARD
之类的值来拦截内部转发到其他资源的请求。对于一个 servlet 转发到另一个,spring 安全约束工作正常。
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>FORWARD</dispatcher>
<dispatcher>REQUEST</dispatcher>
</filter-mapping>
问题: 安全过滤器似乎不会使用 JSF Actions
拦截内部转发JSF 似乎在使用 JSF 操作(导航案例)时将请求“转发”到目标视图(页面)。这会导致 URL 比页面的实际 URL 落后一步。
这样做的副作用是 spring 安全约束(与 URL 绑定)在下一个操作之前不会生效。
示例: 当前页面网址:http://host/myapp/page1.xhtml (page1.xhtml 有一个导航到受保护的 page2 的操作)
提交时,请求被提交到呈现 page2.xhtml 的服务器,但 URL 仍保持为 http://host/myapp/page1.xhtml。 Spring Security 不拦截和保护page2.xhtml
这可以通过指定以下内容来克服:
<navigation-case>
<from-outcome>page2</from-outcome>
<to-view-id>/page2.xhtml</to-view-id>
<redirect/> <!--REDIRECT, INSTEAD OF FORWARD-->
</navigation-case>
重定向不是我们想要实现的方式。有没有更好的方法让 Spring Security 与 JSF 一起工作?
编辑:(spring config xml的相关sn-p)
<http use-expressions="true" once-per-request="false">
<intercept-url pattern="/index.xhtml" access="permitAll" />
<intercept-url pattern="/page1.xhtml" access="isAuthenticated()" />
<intercept-url pattern="/page2.xhtml" access="hasRole('supervisor')" />
<intercept-url pattern="/page3.xhtml" access="hasRole('teller')" />
<form-login login-page="/login.html" default-target-url="/page1.xhtml"/>
</http>
<authentication-manager>
<authentication-provider>
<user-service>
<user name="rod" password="rod" authorities="supervisor, user" />
<user name="dianne" password="dianne" authorities="teller, user" />
<user name="scott" password="scott" authorities="supervisor" />
<user name="peter" password="peter" authorities="user" />
</user-service>
</authentication-provider>
</authentication-manager>
【问题讨论】:
你也可以发布你的applicationContext.xml @Ravi 使用 appcontext.xml 中的内容编辑了问题有什么想法吗? 【参考方案1】:来自horse's mouth(oracle 文档)
如果导航案例不使用重定向元素,新页面将呈现为对当前请求的响应,这意味着浏览器地址字段中的 URL 不会改变,并且它将包含上一页的地址。
这似乎意味着在 JSF 生命周期中没有“向前”发生到下一页......因此 Spring Security 永远无法处理这个问题。
【讨论】:
【参考方案2】:默认情况下,FilterSecurityInterceptor 只会对每个请求执行一次,并且不会进行安全重新检查,除非 url 发生更改,但使用 JSP/JSF 转发页面将呈现为对当前请求的响应,并且浏览器中的url包含上一页的地址。因此,为此只需在 applicationContext 中的 http 元素中将每次请求属性设置为 false,从而强制重新检查安全性。
<http auto-config="true" use-expressions="true" once-per-request="false">
并在您的 web.xml 中的 springSecurityFilterChain 过滤器映射中添加转发调度程序
<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>
更多info
或者,您还可以通过将参数 faces-redirect=true 附加到结果中来启用页面重定向,如下所示:
<h:form>
<h:commandButton action="page1?faces-redirect=true" value="Page1" />
</h:form>
但正如BalusC 所说,它不是使用 POST 进行页面导航的好习惯。始终使用
进行 GET<h:link> or <h:button>
另见:
when-should-i-use-houtputlink-instead-of-hcommandlink
Post-Redirect-Get pattern
【讨论】:
以上是关于JSF - Spring 安全集成问题的主要内容,如果未能解决你的问题,请参考以下文章
我们可以集成 JSF 2.0 + Spring 4.2.X + Spring Security 4.2.X [重复]