I have an embedded jetty server that is iterating through a list of webapps (the list varies between deployments) from many different locations. I'm trying to make the transition from basic authentication to form authentication.
What I'd like to do is something like:
// create constraint
Constraint usersOnly = new Constraint(Constraint.__FORM_AUTH, "user");
usersOnly.setAuthenticate(true);
ConstraintMapping requireAuthentication = new ConstraintMapping();
requireAuthentication.setConstraint(usersOnly);
requireAuthentication.setPathSpec("/*");
// create login service
LoginService loginService = new HashLoginService("realm");
loginService.setConfig("users.txt");
// create form authentication
FormAuthenticator formAuthenticator = new FormAuthenticator("/login", "/login", true);
// create /login route
ServletHolder loginServlet = new ServletHolder(new DefaultServlet() {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.getWriter().append("<html>\n<head>\n<title>Login</title>\n</head>\n<body>\n"
+ "<form method='POST' action='/j_security_check'>\n"
+ "<input type='text' name='j_username'/>\n"
+ "<input type='password' name='j_password'/>\n"
+ "<input type='submit' value='Login'/>\n</form>\n</body>\n</html>\n");
}
});
ConstraintSecurityHandler securityHandler = new ConstraintSecurityHandler();
securityHandler.addMapping(requireAuthentication);
securityHandler.setLoginService(loginService);
securityHandler.setAuthenticator(formAuthenticator);
// assign security to each webapp
for (WebAppContext webapp : webapps) {
webapp.setSecurityHandler(securityHandler);
webapp.addServlet(loginServlet, "/login");
}
This works as desired if there's only one webapp in webapps, but if there are multiple, you get prompted to sign in every time you follow a link from one webapp to another, and every time you reauthenticate, you get redirected to the base webapp at route "/" and are only authenticated for that one.
I want to get my contexts to share sessions.
According to this question, having a common SessionManager for each WebAppContext instance should solve the problem, but the asker only had one WebAppContext instance. If I try to assign the same SessionManager instance to each WebAppContext, I get NPEs.
I've also seen some resources point to setting the path of each context's SessionCookieConfig to a common context path and the useRequestedId to true for each WebAppContext's SessionManager, but this solution is for org.mortbay.jetty and is outdated.
If you have any insight or experience setting up SSO for an embedded jetty server with multiple WebAppContexts, or if you can think of a better way to serve up multiple distinct webapps with one common server, please point me in the right direction.
How can I allow a user to authenticate into all of the webapps handled by one server by filling out a single form?
Let me know if I'm not being clear or if you have any questions.