From fff0cc0fecaa4dac8c3fb6d8204095ee3d9f9e7e Mon Sep 17 00:00:00 2001 From: "David M. Johnson" Date: Mon, 20 Jan 2025 11:08:49 -0500 Subject: [PATCH] Introduce Roller session listener. --- .../weblogger/ui/core/RollerSession.java | 156 +++++++++--------- .../ui/core/RollerSessionListener.java | 51 ++++++ app/src/main/webapp/WEB-INF/web.xml | 2 +- 3 files changed, 127 insertions(+), 82 deletions(-) create mode 100644 app/src/main/java/org/apache/roller/weblogger/ui/core/RollerSessionListener.java diff --git a/app/src/main/java/org/apache/roller/weblogger/ui/core/RollerSession.java b/app/src/main/java/org/apache/roller/weblogger/ui/core/RollerSession.java index a94797a81..26c9aca97 100644 --- a/app/src/main/java/org/apache/roller/weblogger/ui/core/RollerSession.java +++ b/app/src/main/java/org/apache/roller/weblogger/ui/core/RollerSession.java @@ -18,31 +18,28 @@ package org.apache.roller.weblogger.ui.core; -import java.io.Serializable; -import java.security.Principal; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpSession; -import javax.servlet.http.HttpSessionActivationListener; -import javax.servlet.http.HttpSessionEvent; -import javax.servlet.http.HttpSessionListener; - import com.opensymphony.xwork2.inject.Inject; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.roller.weblogger.WebloggerException; -import org.apache.roller.weblogger.config.WebloggerConfig; -import org.apache.roller.weblogger.business.WebloggerFactory; import org.apache.roller.weblogger.business.UserManager; +import org.apache.roller.weblogger.business.WebloggerFactory; +import org.apache.roller.weblogger.config.WebloggerConfig; import org.apache.roller.weblogger.pojos.User; import org.apache.roller.weblogger.ui.core.security.AutoProvision; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpSession; +import javax.servlet.http.HttpSessionActivationListener; +import javax.servlet.http.HttpSessionListener; +import java.io.Serializable; +import java.security.Principal; + /** * Roller session handles session startup and shutdown. */ -public class RollerSession - implements HttpSessionListener, HttpSessionActivationListener, Serializable { +public class RollerSession implements HttpSessionListener, HttpSessionActivationListener, Serializable { private static final long serialVersionUID = 5890132909166913727L; private static final Log log; @@ -58,7 +55,6 @@ public class RollerSession log = LogFactory.getLog(RollerSession.class); } - @Inject public RollerSession(SessionManager sessionManager) { this.sessionManager = sessionManager; @@ -68,66 +64,77 @@ public RollerSession(SessionManager sessionManager) { public RollerSession(SessionManager sessionManager, HttpServletRequest request) { this.sessionManager = sessionManager; + // No session exists yet, nothing to do HttpSession session = request.getSession(false); - if (session != null) { - RollerSession storedSession = (RollerSession)session.getAttribute(ROLLER_SESSION); - - if (storedSession == null) { - session.setAttribute(ROLLER_SESSION, this); - } else if (storedSession.getAuthenticatedUser() != null) { - if (sessionManager.get(storedSession.getAuthenticatedUser().getUserName()) == null) { - // override it with the new session - session.setAttribute(ROLLER_SESSION, this); - } + if (session == null) { + return; + } + + // Get or create roller session in HTTP session + RollerSession storedSession = (RollerSession)session.getAttribute(ROLLER_SESSION); + if (storedSession == null) { + session.setAttribute(ROLLER_SESSION, this); + } + // If stored session exists with authenticated user but not in cache, override it + else if (storedSession.getAuthenticatedUser() != null + && sessionManager.get(storedSession.getAuthenticatedUser().getUserName()) == null) { + session.setAttribute(ROLLER_SESSION, this); + } + + Principal principal = request.getUserPrincipal(); + + // Skip authentication if no principal, user already authenticated, or system not bootstrapped + if (getAuthenticatedUser() != null || principal == null || !WebloggerFactory.isBootstrapped()) { + return; + } + + try { + UserManager userManager = WebloggerFactory.getWeblogger().getUserManager(); + User user = authenticateUser(principal, userManager); + + // Try auto-provisioning if LDAP enabled and user not found + if (user == null && WebloggerConfig.getBooleanProperty("users.ldap.autoProvision.enabled")) { + user = attemptAutoProvision(request, principal, userManager); } - - Principal principal = request.getUserPrincipal(); - - // If we've got a principal but no user object, then attempt to get - // user object from user manager but *only* do this if we have been - // bootstrapped because under an SSO scenario we may have a - // principal even before we have been bootstrapped. - if (getAuthenticatedUser() == null && principal != null && WebloggerFactory.isBootstrapped()) { - try { - - UserManager umgr = WebloggerFactory.getWeblogger().getUserManager(); - User user = umgr.getUserByUserName(principal.getName()); - - // check for OpenID username (in the form of a URL) - if (user == null && principal.getName() != null && principal.getName().startsWith("http://")) { - String openidurl = principal.getName(); - if (openidurl.endsWith("/")) { - openidurl = openidurl.substring(0, openidurl.length() - 1); - } - user = umgr.getUserByOpenIdUrl(openidurl); - } - - // try one time to auto-provision, only happens if user==null - // which means installation has LDAP enabled in security.xml - if (user == null && WebloggerConfig.getBooleanProperty("users.ldap.autoProvision.enabled")) { - - // provisioning enabled, get provisioner and execute - AutoProvision provisioner = RollerContext.getAutoProvision(); - if(provisioner != null) { - boolean userProvisioned = provisioner.execute(request); - if (userProvisioned) { - // try lookup again real quick - user = umgr.getUserByUserName(principal.getName()); - } - } - } - // only set authenticated user if user is enabled - if (user != null && user.getEnabled()) { - setAuthenticatedUser(user); - } - - } catch (WebloggerException e) { - log.error("ERROR: getting user object",e); - } + + // Set authenticated user if found and enabled + if (user != null && user.getEnabled()) { + setAuthenticatedUser(user); } + } catch (WebloggerException e) { + log.error("Error authenticating user", e); } } + /** + * Attempts to authenticate user via username or OpenID URL + */ + private User authenticateUser(Principal principal, UserManager userManager) throws WebloggerException { + // Try regular username first + User user = userManager.getUserByUserName(principal.getName()); + + // If not found, try OpenID URL + if (user == null && principal.getName() != null && principal.getName().startsWith("http://")) { + String openidUrl = principal.getName(); + if (openidUrl.endsWith("/")) { + openidUrl = openidUrl.substring(0, openidUrl.length() - 1); + } + user = userManager.getUserByOpenIdUrl(openidUrl); + } + return user; + } + + /** + * Attempts to auto-provision user via LDAP if enabled + */ + private User attemptAutoProvision(HttpServletRequest request, Principal principal, + UserManager userManager) throws WebloggerException { + AutoProvision provisioner = RollerContext.getAutoProvision(); + if (provisioner != null && provisioner.execute(request)) { + return userManager.getUserByUserName(principal.getName()); + } + return null; + } /** * Authenticated user associated with this session. */ @@ -153,17 +160,4 @@ public void setAuthenticatedUser(User authenticatedUser) { this.userName = authenticatedUser.getUserName(); sessionManager.register(authenticatedUser.getUserName(), this); } - - private void clearSession(HttpSessionEvent se) { - HttpSession session = se.getSession(); - try { - session.removeAttribute(ROLLER_SESSION); - } catch (Exception e) { - if (log.isDebugEnabled()) { - // ignore purge exceptions - log.debug("EXCEPTION PURGING session attributes",e); - } - } - } - } diff --git a/app/src/main/java/org/apache/roller/weblogger/ui/core/RollerSessionListener.java b/app/src/main/java/org/apache/roller/weblogger/ui/core/RollerSessionListener.java new file mode 100644 index 000000000..f0e3ea754 --- /dev/null +++ b/app/src/main/java/org/apache/roller/weblogger/ui/core/RollerSessionListener.java @@ -0,0 +1,51 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. The ASF licenses this file to You + * under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. For additional information regarding + * copyright in this work, please see the NOTICE file in the top level + * directory of this distribution. + */ + +package org.apache.roller.weblogger.ui.core; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import javax.servlet.http.HttpSession; +import javax.servlet.http.HttpSessionActivationListener; +import javax.servlet.http.HttpSessionEvent; +import javax.servlet.http.HttpSessionListener; + + +public class RollerSessionListener implements HttpSessionListener, HttpSessionActivationListener { + private static final Log log = LogFactory.getLog(RollerSessionListener.class); + + @Override + public void sessionDestroyed(HttpSessionEvent se) { + clearSession(se); + } + + @Override + public void sessionWillPassivate(HttpSessionEvent se) { + clearSession(se); + } + + private void clearSession(HttpSessionEvent se) { + HttpSession session = se.getSession(); + try { + session.removeAttribute(RollerSession.ROLLER_SESSION); + } catch (Exception e) { + log.debug("Exception purging session attributes", e); + } + } +} \ No newline at end of file diff --git a/app/src/main/webapp/WEB-INF/web.xml b/app/src/main/webapp/WEB-INF/web.xml index 0418832da..e75cb6869 100644 --- a/app/src/main/webapp/WEB-INF/web.xml +++ b/app/src/main/webapp/WEB-INF/web.xml @@ -174,7 +174,7 @@ - org.apache.roller.weblogger.ui.core.RollerSession + org.apache.roller.weblogger.ui.core.RollerSessionListener