Our application is using Wicket. We’re using Wicket’s own forms to handle authentication, the main benefits being that the look of the site is kept consistent.
We thought we couldn’t do container authentication because our application allows the user to switch authentication mechanisms mid-stream, and Jetty itself was creating quite a bit of friction anyway, just getting simple authentication to work at the container level.
So we ended up implementing authentication via a filter (there are a number of good examples out there.)
Now I have discovered that by doing this, Wicket authentication is slightly broken. What happened was:
- Anonymous user would visit the site.
- Security filter determines that the user isn’t authenticated and redirects to sign-in.
- Wicket renders the sign-in page.
- User signs in.
- Wicket processes the post to the sign-in form and redirects user back.
- Security filter determines that the user isn’t authenticated and redirects…
I looked inside my subclass of AuthenticatedWebSession, hoping to find some way I could get a hold of the HttpSession and set a session attribute which could then be checked from the filter. However I couldn’t for the life of me find a way to do it.
What I resorted to doing was making yet another filter, coded like this:
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.
}
}
This of course works (and will continue to work until Wicket change the prefix they store session attributes under.)
I guess what I want to know is whether this is a bad idea and whether there is a “proper Wicket way” to do this sort of thing.
As for the reason we don’t use Wicket’s authentication alone – the reason is that we wanted to support SPNEGO authentication and potentially other external authentication types.
You can get hold of your
HttpSession,albeit throughRequestand notSession.What you need is:
However I’m pretty sure Wicket authentication isn’t broken in such an obvious manner so I’d probably try to find out what is causing this glitch instead.