我在使用JSF的Spring Security中出现以下问题:
我已经定制了会话管理过滤器,以便在请求的页面受到保护时(即,仅允许经过身份验证的用户)将用户重定向到invalidSessionUrl。我在Spring Security提供的会话管理过滤器中输入的自定义代码是:
if (invalidSessionUrl != null) {
String pagSolicitada = UtilSpringSecurity.extraerPagina(request);
if ( UtilSpringSecurity.paginaAutenticada(pagSolicitada ) ) {
request.getSession();
redirectStrategy.sendRedirect(request, response, invalidSessionUrl);
return;
}
//the requested page doesn't require the user to be authenticated
//so i just skip this filter and continue with the filter chain
chain.doFilter(request, response);
return;
}
方法“UtilSpringSecurity.extraerPagina(request)”以这种方式返回请求的页面:
public static String extraerPagina (HttpServletRequest request) {
String uri = request.getRequestURI().toLowerCase();
String cPath = request.getContextPath().toLowerCase();
// uri = cPath + pagina
int longCPath = cPath.length();
String pagina = uri.substring(longCPath);
return pagina;
}
如果param是一个需要用户进行身份验证的页面,那么方法“UtilSpringSecurity.paginaAutenticada(pagSolicitada)”将返回true(我使用IF进行检查,考虑到我的xml安全配置文件的intercept-url元素它具有属性access="isAuthenticated()"
):
public static boolean paginaAutenticada (String pagina) {
if (pagina.startsWith("/faces/paginas/administracion/") || pagina.startsWith("/faces/paginas/barco/") ) {
return true;
}
return false;
}
此解决方案有效,但只有一个问题:
如果我让浏览器在页面中保持空闲状态直到会话超时到期,然后我请求同一页面,那么我会得到一个“viewExpiredException”。这是因为过滤器运行良好,它绕过重定向到invalidSessionUrl,但是当会话过期时,我尝试重新渲染同一页面时得到该异常。
如果我在会话时间到期时请求任何其他不安全的页面,它运行良好,它正确地重定向到页面,我没有得到viewExpiredException。
任何人都知道如何解决这个问题?
提前谢谢。
答案 0 :(得分:3)
Spring安全性应该允许您匿名访问未经身份验证的用户的页面集。下面是我的XML配置摘录,以了解我是如何实现这一目标的。
<http auto-config="true" access-denied-page="/unauthorized.xhtml" >
<intercept-url pattern="/admin/**" access="ROLE_ADMIN" />
<intercept-url pattern="/app/**" access="ROLE_USER,ROLE_ADMIN" />
<intercept-url pattern="/*.xhtml" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<form-login login-page="/login.xhtml" login-processing-url="/j_spring_security_check"
authentication-success-handler-ref="authenticationSuccessBean"
authentication-failure-handler-ref="authenticationFailureBean" />
<session-management invalid-session-url="/login.xhtml" >
</session-management>
</http>
我基本上使用intercept-url
标记来声明某些相对上下文中的页面只能由以下角色访问。您可以看到匿名用户可以使用Web应用程序默认上下文中的所有页面。如果用户未经授权查看该页面,则会将其重定向到access-denied-page
。
唯一的问题是您的User bean必须实现UserDetails
接口并且具有返回实现GrantedAuthority
接口的角色bean的属性。 Spring会查找UserDetails
来拥有GrantedAuthority
属性来确定角色是什么。如果此用户不存在,未经身份验证或未知,则默认为匿名角色。
答案 1 :(得分:0)
最后我解决了。这是一个JSF问题,与Spring Security无关。
我用这种方式覆盖了jsf的restoreView方法:
@Override
public UIViewRoot restoreView(FacesContext facesContext, String viewId) {
UIViewRoot root = wrapped.restoreView(facesContext, viewId);
if(root == null) {
root = createView(facesContext, viewId);
}
return root;
}
现在的问题是,如果页面有参数,我在最近创建的视图发布时丢失了它们,但这是另一个与JSF再次交易的不同问题(PRG模式)。