Index: lams_central/src/java/org/lamsfoundation/lams/web/LoginRequestServlet.java =================================================================== RCS file: /usr/local/cvsroot/lams_central/src/java/org/lamsfoundation/lams/web/LoginRequestServlet.java,v diff -u -r1.13 -r1.14 --- lams_central/src/java/org/lamsfoundation/lams/web/LoginRequestServlet.java 18 Feb 2010 05:42:17 -0000 1.13 +++ lams_central/src/java/org/lamsfoundation/lams/web/LoginRequestServlet.java 26 Oct 2011 17:47:37 -0000 1.14 @@ -33,12 +33,14 @@ import javax.naming.NamingException; import javax.security.auth.login.FailedLoginException; import javax.servlet.ServletException; +import javax.servlet.http.Cookie; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import javax.sql.DataSource; +import org.apache.catalina.authenticator.Constants; import org.apache.log4j.Logger; import org.lamsfoundation.lams.integration.ExtCourseClassMap; import org.lamsfoundation.lams.integration.ExtServerOrgMap; @@ -68,175 +70,196 @@ @SuppressWarnings("serial") public class LoginRequestServlet extends HttpServlet { - private static Logger log = Logger.getLogger(LoginRequestServlet.class); + private static Logger log = Logger.getLogger(LoginRequestServlet.class); - private static IntegrationService integrationService = null; + private static IntegrationService integrationService = null; - private static final String JNDI_DATASOURCE = "java:/jdbc/lams-ds"; + private static final String JNDI_DATASOURCE = "java:/jdbc/lams-ds"; - private static final String PASSWORD_QUERY = "select password from lams_user where login=?"; + private static final String PASSWORD_QUERY = "select password from lams_user where login=?"; - /** - * The doGet method of the servlet.
- * - * This method is called when a form has its tag value method equals to get. - * - * @param request - * the request send by the client to the server - * @param response - * the response send by the server to the client - * @throws ServletException - * if an error occurred - * @throws IOException - * if an error occurred + /** + * The doGet method of the servlet.
+ * + * This method is called when a form has its tag value method equals to get. + * + * @param request + * the request send by the client to the server + * @param response + * the response send by the server to the client + * @throws ServletException + * if an error occurred + * @throws IOException + * if an error occurred + */ + @Override + public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + // create http session required by the valve + // since valve can't create session + /* + * HttpSession hses = request.getSession(); if(hses!=null) hses.invalidate(); HttpSession sharedsession = + * SessionManager.getSession(); if(sharedsession!=null) sharedsession.invalidate(); */ - public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { - // create http session required by the valve - // since valve can't create session - /* - * HttpSession hses = request.getSession(); if(hses!=null) hses.invalidate(); HttpSession sharedsession = - * SessionManager.getSession(); if(sharedsession!=null) sharedsession.invalidate(); - */ - HttpSession hses = request.getSession(true); + HttpSession hses = request.getSession(true); - String extUsername = request.getParameter(LoginRequestDispatcher.PARAM_USER_ID); - String serverId = request.getParameter(LoginRequestDispatcher.PARAM_SERVER_ID); - String extCourseId = request.getParameter(LoginRequestDispatcher.PARAM_COURSE_ID); - String timestamp = request.getParameter(LoginRequestDispatcher.PARAM_TIMESTAMP); - String hash = request.getParameter(LoginRequestDispatcher.PARAM_HASH); - String method = request.getParameter(LoginRequestDispatcher.PARAM_METHOD); - String countryIsoCode = request.getParameter(LoginRequestDispatcher.PARAM_COUNTRY); - String langIsoCode = request.getParameter(LoginRequestDispatcher.PARAM_LANGUAGE); - String courseName = request.getParameter(CentralConstants.PARAM_COURSE_NAME); + String extUsername = request.getParameter(LoginRequestDispatcher.PARAM_USER_ID); + String serverId = request.getParameter(LoginRequestDispatcher.PARAM_SERVER_ID); + String extCourseId = request.getParameter(LoginRequestDispatcher.PARAM_COURSE_ID); + String timestamp = request.getParameter(LoginRequestDispatcher.PARAM_TIMESTAMP); + String hash = request.getParameter(LoginRequestDispatcher.PARAM_HASH); + String method = request.getParameter(LoginRequestDispatcher.PARAM_METHOD); + String countryIsoCode = request.getParameter(LoginRequestDispatcher.PARAM_COUNTRY); + String langIsoCode = request.getParameter(LoginRequestDispatcher.PARAM_LANGUAGE); + String courseName = request.getParameter(CentralConstants.PARAM_COURSE_NAME); - // implicit login params - String firstName = request.getParameter(LoginRequestDispatcher.PARAM_FIRST_NAME); - String lastName = request.getParameter(LoginRequestDispatcher.PARAM_LAST_NAME); - String email = request.getParameter(LoginRequestDispatcher.PARAM_EMAIL); + // implicit login params + String firstName = request.getParameter(LoginRequestDispatcher.PARAM_FIRST_NAME); + String lastName = request.getParameter(LoginRequestDispatcher.PARAM_LAST_NAME); + String email = request.getParameter(LoginRequestDispatcher.PARAM_EMAIL); - if (extUsername == null || method == null || serverId == null || timestamp == null || hash == null - || extCourseId == null) { - response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Login Failed - login parameters missing"); - return; - } + if ((extUsername == null) || (method == null) || (serverId == null) || (timestamp == null) || (hash == null) + || (extCourseId == null)) { + response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Login Failed - login parameters missing"); + return; + } - // LDEV-2196 preserve character encoding if necessary - if (request.getCharacterEncoding() == null) { - log.debug("request.getCharacterEncoding is empty, parsing username and courseName as 8859_1 to UTF-8..."); - extUsername = new String(extUsername.getBytes("8859_1"), "UTF-8"); - if (courseName != null) { - courseName = new String(courseName.getBytes("8859_1"), "UTF-8"); - } - } + // LDEV-2196 preserve character encoding if necessary + if (request.getCharacterEncoding() == null) { + LoginRequestServlet.log + .debug("request.getCharacterEncoding is empty, parsing username and courseName as 8859_1 to UTF-8..."); + extUsername = new String(extUsername.getBytes("8859_1"), "UTF-8"); + if (courseName != null) { + courseName = new String(courseName.getBytes("8859_1"), "UTF-8"); + } + } - ExtServerOrgMap serverMap = getService().getExtServerOrgMap(serverId); + ExtServerOrgMap serverMap = getService().getExtServerOrgMap(serverId); - try { - ExtUserUseridMap userMap = null; + try { + ExtUserUseridMap userMap = null; - if (firstName == null && lastName == null) { - userMap = getService().getExtUserUseridMap(serverMap, extUsername); - } else { - userMap = getService().getImplicitExtUserUseridMap(serverMap, extUsername, firstName, lastName, - langIsoCode, countryIsoCode, email); - } + if ((firstName == null) && (lastName == null)) { + userMap = getService().getExtUserUseridMap(serverMap, extUsername); + } else { + userMap = getService().getImplicitExtUserUseridMap(serverMap, extUsername, firstName, lastName, + langIsoCode, countryIsoCode, email); + } - Authenticator.authenticate(serverMap, timestamp, extUsername, method, hash); - ExtCourseClassMap orgMap = getService().getExtCourseClassMap(serverMap, userMap, extCourseId, - countryIsoCode, langIsoCode, courseName, method); - User user = userMap.getUser(); - String login = user.getLogin(); - // was using hses.inNew() API to check if the external user has logged in yet, - // but it seems not working. The "extUser" attribute works as a flag to indicate - // if the user has logged in - String loginRequestUsername = (String) hses.getAttribute("extUser"); - if (loginRequestUsername != null && loginRequestUsername.equals(login)) { - String url = LoginRequestDispatcher.getRequestURL(request); - response.sendRedirect(response.encodeRedirectURL(url)); - return; - } else if (loginRequestUsername != null && !loginRequestUsername.equals(login)) { - hses.invalidate(); - hses = request.getSession(true); - } else if (request.getRemoteUser() != null && loginRequestUsername == null) { - hses.invalidate(); - hses = request.getSession(true); - } - Organisation org = orgMap.getOrganisation(); - IUserManagementService userManagementService = integrationService.getService(); - UserOrganisation uo = userManagementService.getUserOrganisation(user.getUserId(), org.getOrganisationId()); - // make sure external user has minimal set of roles, i.e. learner - Integer[] roleIds = new Integer[] { Role.ROLE_LEARNER }; - // we have to assign all the roles to the external user here, because once the user logged in, the roles - // are cached in JBoss, all the calls of request.isUserInRole() will be based on the cached roles - Map properties = new HashMap(); - properties.put("userOrganisation.userOrganisationId", uo.getUserOrganisationId()); - for (Integer roleId : roleIds) { - properties.put("role.roleId", roleId); - List list = userManagementService.findByProperties(UserOrganisationRole.class, properties); - if (list == null || list.size() == 0) { - UserOrganisationRole uor = new UserOrganisationRole(uo, (Role) userManagementService.findById( - Role.class, roleId)); - userManagementService.save(uor); - } - } - log.debug("Session Id - " + hses.getId()); - // connect to DB and get password here - String pass = getUserPassword(userMap.getUser().getLogin()); - // should post the parameters back so it's little more secure, - // but forward doesn't work, use this until a better method is found - hses.setAttribute("extUser", login); - hses.setAttribute(AttributeNames.USER, user.getUserDTO()); - response.sendRedirect("j_security_check?j_username=" + login + "&j_password=" + pass); - } catch (AuthenticationException e) { - log.error("Authentication error: ", e); - response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Login Failed - authentication error"); - } catch (UserInfoFetchException e) { - log.error("User fetch info error: ", e); - response.sendError(HttpServletResponse.SC_BAD_GATEWAY, - "Login Failed - failed to fetch user info from the third party server"); - } catch (FailedLoginException e) { - log.error("Login error: ", e); - response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Login Failed - user was not found"); - } catch (NamingException e) { - log.error("Naming error: ", e); - response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage()); - } catch (SQLException e) { - log.error("Database error: ", e); - response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage()); + Authenticator.authenticate(serverMap, timestamp, extUsername, method, hash); + ExtCourseClassMap orgMap = getService().getExtCourseClassMap(serverMap, userMap, extCourseId, + countryIsoCode, langIsoCode, courseName, method); + User user = userMap.getUser(); + String login = user.getLogin(); + // was using hses.inNew() API to check if the external user has logged in yet, + // but it seems not working. The "extUser" attribute works as a flag to indicate + // if the user has logged in + String loginRequestUsername = (String) hses.getAttribute("extUser"); + if ((loginRequestUsername != null) && loginRequestUsername.equals(login)) { + String url = LoginRequestDispatcher.getRequestURL(request); + response.sendRedirect(response.encodeRedirectURL(url)); + return; + } else if (loginRequestUsername == null ? request.getRemoteUser() != null : !loginRequestUsername + .equals(login)) { + hses = recreateSession(request, response); + } + Organisation org = orgMap.getOrganisation(); + IUserManagementService userManagementService = LoginRequestServlet.integrationService.getService(); + UserOrganisation uo = userManagementService.getUserOrganisation(user.getUserId(), org.getOrganisationId()); + // make sure external user has minimal set of roles, i.e. learner + Integer[] roleIds = new Integer[] { Role.ROLE_LEARNER }; + // we have to assign all the roles to the external user here, because once the user logged in, the roles + // are cached in JBoss, all the calls of request.isUserInRole() will be based on the cached roles + Map properties = new HashMap(); + properties.put("userOrganisation.userOrganisationId", uo.getUserOrganisationId()); + for (Integer roleId : roleIds) { + properties.put("role.roleId", roleId); + List list = userManagementService.findByProperties(UserOrganisationRole.class, properties); + if ((list == null) || (list.size() == 0)) { + UserOrganisationRole uor = new UserOrganisationRole(uo, (Role) userManagementService.findById( + Role.class, roleId)); + userManagementService.save(uor); } + } + LoginRequestServlet.log.debug("Session Id - " + hses.getId()); + // connect to DB and get password here + String pass = getUserPassword(userMap.getUser().getLogin()); + // should post the parameters back so it's little more secure, + // but forward doesn't work, use this until a better method is found + hses.setAttribute("extUser", login); + hses.setAttribute(AttributeNames.USER, user.getUserDTO()); + response.sendRedirect("j_security_check?j_username=" + login + "&j_password=" + pass); + } catch (AuthenticationException e) { + LoginRequestServlet.log.error("Authentication error: ", e); + response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Login Failed - authentication error"); + } catch (UserInfoFetchException e) { + LoginRequestServlet.log.error("User fetch info error: ", e); + response.sendError(HttpServletResponse.SC_BAD_GATEWAY, + "Login Failed - failed to fetch user info from the third party server"); + } catch (FailedLoginException e) { + LoginRequestServlet.log.error("Login error: ", e); + response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Login Failed - user was not found"); + } catch (NamingException e) { + LoginRequestServlet.log.error("Naming error: ", e); + response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage()); + } catch (SQLException e) { + LoginRequestServlet.log.error("Database error: ", e); + response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage()); } + } - // using JDBC connection to prevent the caching of passwords by hibernate - private String getUserPassword(String username) throws FailedLoginException, NamingException, SQLException { - InitialContext ctx = new InitialContext(); + // using JDBC connection to prevent the caching of passwords by hibernate + private String getUserPassword(String username) throws FailedLoginException, NamingException, SQLException { + InitialContext ctx = new InitialContext(); - DataSource ds = (DataSource) ctx.lookup(JNDI_DATASOURCE); - Connection conn = null; - String password = null; - try { - conn = ds.getConnection(); - PreparedStatement ps = conn.prepareStatement(PASSWORD_QUERY); - ps.setString(1, username); - ResultSet rs = ps.executeQuery(); + DataSource ds = (DataSource) ctx.lookup(LoginRequestServlet.JNDI_DATASOURCE); + Connection conn = null; + String password = null; + try { + conn = ds.getConnection(); + PreparedStatement ps = conn.prepareStatement(LoginRequestServlet.PASSWORD_QUERY); + ps.setString(1, username); + ResultSet rs = ps.executeQuery(); - // check if there is any result - if (rs.next() == false) - throw new FailedLoginException("invalid username"); + // check if there is any result + if (rs.next() == false) { + throw new FailedLoginException("invalid username"); + } - password = rs.getString(1); - rs.close(); - } finally { - if (conn != null && !conn.isClosed()) - conn.close(); - } - return password; + password = rs.getString(1); + rs.close(); + } finally { + if ((conn != null) && !conn.isClosed()) { + conn.close(); + } } + return password; + } - private IntegrationService getService() { - if (integrationService == null) { - integrationService = (IntegrationService) WebApplicationContextUtils.getRequiredWebApplicationContext( - getServletContext()).getBean("integrationService"); + private HttpSession recreateSession(HttpServletRequest request, HttpServletResponse response) { + HttpSession hses = request.getSession(false); + hses.invalidate(); + hses = request.getSession(true); + + Cookie cookies[] = request.getCookies(); + if (cookies != null) { + for (int i = 0; i < cookies.length; i++) { + if (Constants.SINGLE_SIGN_ON_COOKIE.equals(cookies[i].getName())) { + Cookie cookie = new Cookie(cookies[i].getName(), ""); + cookie.setPath("/"); + cookie.setMaxAge(0); + response.addCookie(cookie); + break; } - return integrationService; + } } + return hses; + } + + private IntegrationService getService() { + if (LoginRequestServlet.integrationService == null) { + LoginRequestServlet.integrationService = (IntegrationService) WebApplicationContextUtils + .getRequiredWebApplicationContext(getServletContext()).getBean("integrationService"); + } + return LoginRequestServlet.integrationService; + } } Index: lams_common/src/java/org/lamsfoundation/lams/integration/security/SingleSignOn.java =================================================================== RCS file: /usr/local/cvsroot/lams_common/src/java/org/lamsfoundation/lams/integration/security/SingleSignOn.java,v diff -u -r1.3 -r1.4 --- lams_common/src/java/org/lamsfoundation/lams/integration/security/SingleSignOn.java 24 Jan 2008 05:57:21 -0000 1.3 +++ lams_common/src/java/org/lamsfoundation/lams/integration/security/SingleSignOn.java 26 Oct 2011 17:47:34 -0000 1.4 @@ -34,6 +34,7 @@ import org.apache.catalina.connector.Request; import org.apache.catalina.connector.Response; import org.apache.log4j.Logger; +import org.lamsfoundation.lams.web.session.SystemSessionFilter; /** *

@@ -110,12 +111,15 @@ request.setAuthType(entry.getAuthType()); request.setUserPrincipal(entry.getPrincipal()); } - } else { -// if (log.isDebugEnabled()) -// log.debug(" No cached principal found, erasing SSO cookie"); - cookie.setMaxAge(0); - response.addCookie(cookie); - } + } else { + // if (log.isDebugEnabled()) + // log.debug(" No cached principal found, erasing SSO cookie"); + deregister(cookie.getValue()); + cookie = new Cookie(cookie.getName(), ""); + cookie.setPath("/"); + cookie.setMaxAge(0); + response.addCookie(cookie); + } // Invoke the next Valve in our pipeline getNext().invoke(request, response);