我们的应用程序正在使用 Wicket。我们使用 Wicket 自己的表单来处理身份验证,主要好处是网站的外观保持一致。
我们认为我们无法进行容器身份验证,因为我们的应用程序允许用户在中途切换身份验证机制,而 Jetty 本身无论如何都会产生相当多的摩擦,只是让简单的身份验证在容器级别工作。
所以我们最终通过过滤器实现了身份验证(那里有很多很好的例子。)
现在我发现通过这样做,Wicket 身份验证被稍微破坏了。发生的事情是:
- 匿名用户将访问该站点。
- 安全筛选器确定用户未通过身份验证并重定向到登录。
- Wicket 呈现登录页面。
- 用户登录。
- Wicket 将帖子处理到登录表单并将用户重定向回来。
- 安全过滤器确定用户未通过身份验证并重定向...
我查看了 AuthenticatedWebSession 的子类,希望找到某种方法可以获取 HttpSession 并设置一个会话属性,然后可以从过滤器中检查该属性。但是,我一生都无法找到一种方法来做到这一点。
我采取的做法是制作另一个过滤器,编码如下:
public class StealWicketUserFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
// Nothing to initialise.
}
@Override
public void doFilter(ServletRequest servletRequest,
ServletResponse servletResponse,
FilterChain filterChain) throws IOException, ServletException
{
filterChain.doFilter(servletRequest, servletResponse);
HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
if ("POST".equals(httpServletRequest.getMethod()) &&
"/sign_in".equals(httpServletRequest.getRequestURI())) {
HttpSession session = httpServletRequest.getSession();
ServerUser currentUser = (ServerUser)
session.getAttribute("wicket:webUIServlet:currentUser");
if (currentUser != null) {
session.setAttribute(CombinedSecurityFilter.CURRENT_USER_ATTRIBUTE,
currentUser);
}
}
else if ("/sign_out".equals(httpServletRequest.getRequestURI())) {
HttpSession session = httpServletRequest.getSession();
session.removeAttribute(CombinedSecurityFilter.CURRENT_USER_ATTRIBUTE);
}
}
@Override
public void destroy() {
// Nothing to destroy.
}
}
这当然有效(并且将继续有效,直到 Wicket 更改它们存储会话属性的前缀。)
我想我想知道这是否是一个坏主意以及是否有“适当的 Wicket 方式”来做这种事情。
至于我们不单独使用 Wicket 身份验证的原因 - 原因是我们希望支持 SPNEGO 身份验证和可能的其他外部身份验证类型。