【发布时间】:2010-03-22 15:20:11
【问题描述】:
我正在尝试在 j_security_check 上执行过滤器以执行一些登录后操作,例如更改重定向 url 等。但问题是我的过滤器永远不会被执行。我可以申请的任何拼凑?任何帮助,将不胜感激。我真的厌倦了容器管理的安全性。
提前致谢。
【问题讨论】:
我正在尝试在 j_security_check 上执行过滤器以执行一些登录后操作,例如更改重定向 url 等。但问题是我的过滤器永远不会被执行。我可以申请的任何拼凑?任何帮助,将不胜感激。我真的厌倦了容器管理的安全性。
提前致谢。
【问题讨论】:
您不能以编程方式挂钩/j_security_check。这是一个安全限制。
您最好的选择是通过手动检查HttpSession 中的用户主体来确定首次登录,如果不存在则将其放在那里,然后执行您的操作。我在here 之前发布了类似的答案。这是过滤器代码的摘录,您只需将过滤器映射到所需的url-pattern 覆盖受保护的页面。
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) {
HttpServletRequest httpRequest = (HttpServletRequest) request;
UserPrincipal user = httpRequest.getUserPrincipal();
HttpSession session = httpRequest.getSession();
if (user != null && session.getAttribute("user") == null) {
session.setAttribute("user", user);
// First-time login. You can do your intercepting thing here.
}
chain.doFilter(request, response);
}
【讨论】:
response 转换回HttpServletResponse 并致电sendRedirect()。 Scriptlet 是不好的做法。
恕我直言,您不应该尝试拦截容器的身份验证系统;在您的情况下,可以在 web.xml 中以声明方式设置重定向 URL。
如果您想执行一些身份验证后操作,我建议设置一个虚拟的身份验证后 servlet/jsp 来执行您想要的操作,然后重定向到请求的资源。然后可以将该认证后 servlet 正确配置为登录后页面。
【讨论】:
一种便携式解决方案。
在模式 /* 上注册一个全局过滤器;
在 doFilter() 中尝试从会话中获取自定义对象(即用户工作区);
如果对象为空,则将新对象放入会话并执行登录后逻辑。
public void doFilter(
ServletRequest request,
ServletResponse response,
FilterChain chain
) throws IOException, ServletException
{
Principal principal = request.getUserPrincipal();
if(principal != null) {
UserWorkspace uwks = (UserWorkspace) getSession(request).getAttribute("com.foo.myproject.userworkspace");
if (uwks == null) {
uwks = new UserWorkspace(principal);
getSession(request).setAttribute("com.foo.myproject.userworkspace", uwks);
//
// post-login code here
//
}
}
chain.doFilter(request, response);
}
【讨论】: