Merge pull request #66 from mbien/spring_renovations
Spring Renovations
diff --git a/app/pom.xml b/app/pom.xml
index 81e5c8f..9a067cf 100644
--- a/app/pom.xml
+++ b/app/pom.xml
@@ -56,8 +56,8 @@
<maven-antrun.version>1.0b3</maven-antrun.version>
<rome.version>1.13.1</rome.version>
<slf4j.version>1.7.26</slf4j.version>
- <spring.version>4.1.4.RELEASE</spring.version>
- <spring.security.version>3.2.5.RELEASE</spring.security.version>
+ <spring.version>5.2.7.RELEASE</spring.version>
+ <spring.security.version>5.3.3.RELEASE</spring.security.version>
<struts.version>2.5.22</struts.version>
<velocity.version>1.7</velocity.version>
<webjars.version>1.5</webjars.version>
@@ -215,6 +215,16 @@
<groupId>org.apache.struts</groupId>
<artifactId>struts2-spring-plugin</artifactId>
<version>${struts.version}</version>
+ <exclusions>
+ <exclusion>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-beans</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-core</artifactId>
+ </exclusion>
+ </exclusions>
</dependency>
<dependency>
diff --git a/app/src/main/java/org/apache/roller/weblogger/pojos/User.java b/app/src/main/java/org/apache/roller/weblogger/pojos/User.java
index bde443f..881f8ee 100644
--- a/app/src/main/java/org/apache/roller/weblogger/pojos/User.java
+++ b/app/src/main/java/org/apache/roller/weblogger/pojos/User.java
@@ -25,10 +25,10 @@
import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;
import org.apache.roller.weblogger.WebloggerException;
-import org.apache.roller.weblogger.config.WebloggerConfig;
import org.apache.roller.util.UUIDGenerator;
import org.apache.roller.weblogger.business.WebloggerFactory;
-import org.apache.roller.weblogger.util.Utilities;
+import org.apache.roller.weblogger.ui.core.RollerContext;
+import org.springframework.security.crypto.password.PasswordEncoder;
/**
@@ -115,15 +115,9 @@
*
* @param newPassword The new password to be set.
*/
- public void resetPassword(String newPassword) throws WebloggerException {
-
- String encrypt = WebloggerConfig.getProperty("passwds.encryption.enabled");
- String algorithm = WebloggerConfig.getProperty("passwds.encryption.algorithm");
- if (Boolean.valueOf(encrypt)) {
- setPassword(Utilities.encodePassword(newPassword, algorithm));
- } else {
- setPassword(newPassword);
- }
+ public void resetPassword(String newPassword) {
+ PasswordEncoder encoder = RollerContext.getPasswordEncoder();
+ setPassword(encoder.encode(newPassword));
}
/**
diff --git a/app/src/main/java/org/apache/roller/weblogger/ui/core/RollerContext.java b/app/src/main/java/org/apache/roller/weblogger/ui/core/RollerContext.java
index 3946e75..fb5ec25 100644
--- a/app/src/main/java/org/apache/roller/weblogger/ui/core/RollerContext.java
+++ b/app/src/main/java/org/apache/roller/weblogger/ui/core/RollerContext.java
@@ -20,6 +20,8 @@
import java.io.File;
import java.io.InputStream;
+import java.util.HashMap;
+import java.util.Map;
import java.util.Properties;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
@@ -30,9 +32,6 @@
import org.springframework.security.authentication.ProviderManager;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.core.userdetails.UserCache;
-import org.springframework.security.authentication.encoding.Md5PasswordEncoder;
-import org.springframework.security.authentication.encoding.PasswordEncoder;
-import org.springframework.security.authentication.encoding.ShaPasswordEncoder;
import org.springframework.security.authentication.RememberMeAuthenticationProvider;
import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint;
import org.apache.commons.logging.Log;
@@ -50,6 +49,10 @@
import org.apache.velocity.runtime.RuntimeSingleton;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.context.ApplicationContext;
+import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
+import org.springframework.security.crypto.password.DelegatingPasswordEncoder;
+import org.springframework.security.crypto.password.PasswordEncoder;
+import org.springframework.security.crypto.password.Pbkdf2PasswordEncoder;
import org.springframework.web.context.ContextLoaderListener;
import org.springframework.web.context.support.WebApplicationContextUtils;
@@ -63,6 +66,7 @@
private static Log log = LogFactory.getLog(RollerContext.class);
private static ServletContext servletContext = null;
+ private static DelegatingPasswordEncoder encoder;
public RollerContext() {
@@ -89,6 +93,9 @@
return servletContext;
}
+ public static PasswordEncoder getPasswordEncoder() {
+ return encoder;
+ }
/**
* Responds to app-init event and triggers startup procedures.
@@ -251,27 +258,14 @@
}
}
- String encryptPasswords = WebloggerConfig.getProperty("passwds.encryption.enabled");
- boolean doEncrypt = Boolean.valueOf(encryptPasswords);
+ encoder = createPasswordEncoder();
String daoBeanName = "org.springframework.security.authentication.dao.DaoAuthenticationProvider#0";
// for LDAP-only authentication, no daoBeanName (i.e., UserDetailsService) may be provided in security.xml.
- if (doEncrypt && ctx.containsBean(daoBeanName)) {
+ if (ctx.containsBean(daoBeanName)) {
DaoAuthenticationProvider provider = (DaoAuthenticationProvider) ctx.getBean(daoBeanName);
- String algorithm = WebloggerConfig.getProperty("passwds.encryption.algorithm");
- PasswordEncoder encoder = null;
- if (algorithm.equalsIgnoreCase("SHA")) {
- encoder = new ShaPasswordEncoder();
- } else if (algorithm.equalsIgnoreCase("MD5")) {
- encoder = new Md5PasswordEncoder();
- } else {
- log.error("Encryption algorithm '" + algorithm + "' not supported, disabling encryption.");
- }
- if (encoder != null) {
- provider.setPasswordEncoder(encoder);
- log.info("Password Encryption Algorithm set to '" + algorithm + "'");
- }
+ provider.setPasswordEncoder(encoder);
}
if (WebloggerConfig.getBooleanProperty("securelogin.enabled")) {
@@ -281,6 +275,58 @@
}
}
+ @SuppressWarnings("deprecation")
+ private DelegatingPasswordEncoder createPasswordEncoder() {
+
+ Map<String, PasswordEncoder> encoders = new HashMap<>();
+
+ // outdated digest encoder used for lazy upgrades from pws encoded by old roller versions.
+ String migrateFrom = WebloggerConfig.getProperty("passwds.encryption.lazyUpgradeFrom");
+
+ if(migrateFrom == null || migrateFrom.isEmpty()) {
+ log.debug("lazy pw upgrade disabled");
+ } else if (migrateFrom.equals("plaintext")) {
+ encoders.put(null, org.springframework.security.crypto.password.NoOpPasswordEncoder.getInstance());
+ } else if (migrateFrom.equals("MD5")) {
+ encoders.put(null, new org.springframework.security.crypto.password.MessageDigestPasswordEncoder("MD5"));
+ } else if (migrateFrom.equals("SHA")) {
+ encoders.put(null, new org.springframework.security.crypto.password.MessageDigestPasswordEncoder("SHA-1"));
+ } else {
+ throw new RuntimeException("passwds.encryption.lazyUpgradeFrom="+migrateFrom+" is no valid encoding to upgrade from.");
+ }
+
+ // supported encoders
+ encoders.put("bcrypt", new BCryptPasswordEncoder());
+ encoders.put("pbkdf2", new Pbkdf2PasswordEncoder());
+ // requires bouncy castle impl
+// encoders.put("scrypt", new SCryptPasswordEncoder());
+// encoders.put("argon2", new Argon2PasswordEncoder());
+
+ // just for testing
+ encoders.put("noop", org.springframework.security.crypto.password.NoOpPasswordEncoder.getInstance());
+
+ String algorithm = WebloggerConfig.getProperty("passwds.encryption.algorithm");
+
+ if (WebloggerConfig.getBooleanProperty("passwds.encryption.enabled")) {
+
+ if ("SHA".equals(algorithm) || "MD5".equals(algorithm)) {
+ throw new RuntimeException("passwds.encryption.algorithm="+algorithm+" is outdated,"
+ + " please set passwds.encryption.algorithm to 'bcrypt' for automatic lazy upgrade.");
+ }
+
+ if (!encoders.containsKey(algorithm)) {
+ throw new RuntimeException("passwds.encryption.algorithm="+algorithm+" is not supported.");
+ }
+ } else {
+ log.warn("New passwords are stored in plain text!");
+ algorithm = "noop";
+ }
+
+ log.info("Password Encryption Algorithm set to '" + algorithm + "'");
+
+ return new DelegatingPasswordEncoder(algorithm, encoders);
+ }
+
/**
* Flush user from any caches maintained by security system.
diff --git a/app/src/main/java/org/apache/roller/weblogger/ui/core/filters/SpringFirewallExceptionFilter.java b/app/src/main/java/org/apache/roller/weblogger/ui/core/filters/SpringFirewallExceptionFilter.java
new file mode 100644
index 0000000..2ff028c
--- /dev/null
+++ b/app/src/main/java/org/apache/roller/weblogger/ui/core/filters/SpringFirewallExceptionFilter.java
@@ -0,0 +1,71 @@
+/*
+ * 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.filters;
+
+import java.io.IOException;
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.springframework.security.web.firewall.RequestRejectedException;
+
+/**
+ * <p>The spring default firewall ({@link org.springframework.security.web.firewall.StrictHttpFirewall})
+ * is throwing exceptions if it decides to block a request. For example double slashes (//) in the request are
+ * interpreted as non-normalized URL and rejected by throwing RequestRejectedExceptions.
+ * Those exceptions are caught by the server and cause 500 errors which isn't very nice behavior.</p>
+ *
+ * <p>The most straightforward way to handle this seems to be a servlet filter.</p>
+ *
+ * @see org.springframework.security.web.firewall.StrictHttpFirewall
+ */
+public class SpringFirewallExceptionFilter implements Filter {
+
+ private final static Log log = LogFactory.getLog(SpringFirewallExceptionFilter.class);
+
+ @Override
+ public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
+ try {
+ chain.doFilter(request, response);
+ } catch (RequestRejectedException ex) {
+
+ HttpServletRequest req = (HttpServletRequest) request;
+ HttpServletResponse resp = (HttpServletResponse) response;
+
+ // url seems to be dangerous -> log & 404
+ log.warn("request rejected: " + req.getRequestURL() + " cause: " + ex.getMessage());
+ resp.sendError(HttpServletResponse.SC_NOT_FOUND);
+
+ }
+ }
+
+ @Override
+ public void destroy() {}
+
+ @Override
+ public void init(FilterConfig filterConfig) throws ServletException {}
+
+
+}
diff --git a/app/src/main/java/org/apache/roller/weblogger/ui/core/security/RollerRememberMeAuthenticationProvider.java b/app/src/main/java/org/apache/roller/weblogger/ui/core/security/RollerRememberMeAuthenticationProvider.java
index 7c8b60c..78d50f6 100644
--- a/app/src/main/java/org/apache/roller/weblogger/ui/core/security/RollerRememberMeAuthenticationProvider.java
+++ b/app/src/main/java/org/apache/roller/weblogger/ui/core/security/RollerRememberMeAuthenticationProvider.java
@@ -25,20 +25,20 @@
public class RollerRememberMeAuthenticationProvider extends RememberMeAuthenticationProvider {
- private static final Log log = LogFactory.getLog(RollerRememberMeServices.class);
+ private static final Log log = LogFactory.getLog(RollerRememberMeAuthenticationProvider.class);
public RollerRememberMeAuthenticationProvider() {
+
+ super(WebloggerConfig.getProperty("rememberme.key", "springRocks"));
+
log.debug("initializing: RollerRememberMeAuthenticationProvider");
- String key = WebloggerConfig.getProperty("rememberme.key", "springRocks");
-
- if ("springRocks".equals(key)) {
+ if (WebloggerConfig.getBooleanProperty("rememberme.enabled") && "springRocks".equals(getKey())) {
throw new RuntimeException(
"If remember-me is to be enabled, rememberme.key must be specified in the roller " +
"properties file. Make sure it is a secret and make sure it is NOT springRocks");
}
- setKey(key);
log.debug("initialized: RollerRememberMeAuthenticationProvider with key: " + getKey());
}
diff --git a/app/src/main/java/org/apache/roller/weblogger/ui/core/security/RollerRememberMeServices.java b/app/src/main/java/org/apache/roller/weblogger/ui/core/security/RollerRememberMeServices.java
index ca765af..af1afc2 100644
--- a/app/src/main/java/org/apache/roller/weblogger/ui/core/security/RollerRememberMeServices.java
+++ b/app/src/main/java/org/apache/roller/weblogger/ui/core/security/RollerRememberMeServices.java
@@ -22,6 +22,7 @@
import org.apache.commons.logging.LogFactory;
import org.apache.roller.weblogger.config.AuthMethod;
import org.apache.roller.weblogger.config.WebloggerConfig;
+import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.codec.Hex;
import org.springframework.security.web.authentication.rememberme.TokenBasedRememberMeServices;
@@ -33,17 +34,17 @@
private static final Log log = LogFactory.getLog(RollerRememberMeServices.class);
- public RollerRememberMeServices() {
+ public RollerRememberMeServices(UserDetailsService userDetailsService) {
+
+ super(WebloggerConfig.getProperty("rememberme.key", "springRocks"), userDetailsService);
+
log.debug("initializing: RollerRememberMeServices");
- String key = WebloggerConfig.getProperty("rememberme.key", "springRocks");
-
- if ("springRocks".equals(key)) {
+ if (WebloggerConfig.getBooleanProperty("rememberme.enabled") && "springRocks".equals(getKey())) {
throw new RuntimeException(
"If remember-me is to be enabled, rememberme.key must be specified in the roller " +
"properties file. Make sure it is a secret and make sure it is NOT springRocks");
}
- setKey(key);
log.debug("initialized: RollerRememberMeServices with key");
}
diff --git a/app/src/main/java/org/apache/roller/weblogger/ui/struts2/admin/UserEdit.java b/app/src/main/java/org/apache/roller/weblogger/ui/struts2/admin/UserEdit.java
index 73107b9..15ae410 100644
--- a/app/src/main/java/org/apache/roller/weblogger/ui/struts2/admin/UserEdit.java
+++ b/app/src/main/java/org/apache/roller/weblogger/ui/struts2/admin/UserEdit.java
@@ -39,7 +39,6 @@
import org.apache.roller.weblogger.pojos.WeblogPermission;
import org.apache.roller.weblogger.ui.struts2.core.Register;
import org.apache.roller.weblogger.ui.struts2.util.UIAction;
-import org.apache.struts2.convention.annotation.AllowedMethods;
import org.apache.struts2.interceptor.validation.SkipValidation;
@@ -159,21 +158,13 @@
// User.password does not allow null, so generate one
if (authMethod.equals(AuthMethod.OPENID) ||
(authMethod.equals(AuthMethod.DB_OPENID) && !StringUtils.isEmpty(bean.getOpenIdUrl()))) {
- try {
- String randomString = RandomStringUtils.randomAlphanumeric(255);
- user.resetPassword(randomString);
- } catch (WebloggerException e) {
- addMessage("yourProfile.passwordResetError");
- }
+ String randomString = RandomStringUtils.randomAlphanumeric(255);
+ user.resetPassword(randomString);
}
// reset password if set
if (!StringUtils.isEmpty(getBean().getPassword())) {
- try {
- user.resetPassword(getBean().getPassword());
- } catch (WebloggerException e) {
- addMessage("yourProfile.passwordResetError");
- }
+ user.resetPassword(getBean().getPassword());
}
try {
diff --git a/app/src/main/java/org/apache/roller/weblogger/ui/struts2/core/Install.java b/app/src/main/java/org/apache/roller/weblogger/ui/struts2/core/Install.java
index 7ad0522..3552395 100644
--- a/app/src/main/java/org/apache/roller/weblogger/ui/struts2/core/Install.java
+++ b/app/src/main/java/org/apache/roller/weblogger/ui/struts2/core/Install.java
@@ -31,8 +31,7 @@
import org.apache.roller.weblogger.business.startup.WebloggerStartup;
import org.apache.roller.weblogger.config.WebloggerConfig;
import org.apache.roller.weblogger.ui.struts2.util.UIAction;
-import org.apache.struts2.convention.annotation.AllowedMethods;
-import org.springframework.beans.factory.access.BootstrapException;
+import org.springframework.beans.FatalBeanException;
/**
@@ -173,8 +172,8 @@
log.info("EXITING - Bootstrap successful, forwarding to Roller");
return SUCCESS;
- } catch (BootstrapException ex) {
- log.error("BootstrapException", ex);
+ } catch (FatalBeanException ex) {
+ log.error("FatalBeanException", ex);
rootCauseException = ex;
} catch (WebloggerException ex) {
log.error("WebloggerException", ex);
diff --git a/app/src/main/java/org/apache/roller/weblogger/ui/struts2/core/Profile.java b/app/src/main/java/org/apache/roller/weblogger/ui/struts2/core/Profile.java
index 8f6e60f..198ce2b 100644
--- a/app/src/main/java/org/apache/roller/weblogger/ui/struts2/core/Profile.java
+++ b/app/src/main/java/org/apache/roller/weblogger/ui/struts2/core/Profile.java
@@ -28,7 +28,6 @@
import org.apache.roller.weblogger.config.WebloggerConfig;
import org.apache.roller.weblogger.pojos.User;
import org.apache.roller.weblogger.ui.struts2.util.UIAction;
-import org.apache.struts2.convention.annotation.AllowedMethods;
import org.apache.struts2.interceptor.validation.SkipValidation;
@@ -105,21 +104,13 @@
if (authMethod.equals(AuthMethod.OPENID) ||
(authMethod.equals(AuthMethod.DB_OPENID) && !StringUtils.isEmpty(bean.getOpenIdUrl()))) {
String randomString = RandomStringUtils.randomAlphanumeric(255);
- try {
- existingUser.resetPassword(randomString);
- } catch (WebloggerException e) {
- addMessage("yourProfile.passwordResetError");
- }
+ existingUser.resetPassword(randomString);
}
// If user set both password and passwordConfirm then reset password
if (!StringUtils.isEmpty(getBean().getPasswordText()) &&
!StringUtils.isEmpty(getBean().getPasswordConfirm())) {
- try {
- existingUser.resetPassword(getBean().getPasswordText());
- } catch (WebloggerException e) {
- addMessage("yourProfile.passwordResetError");
- }
+ existingUser.resetPassword(getBean().getPasswordText());
}
try {
diff --git a/app/src/main/java/org/apache/roller/weblogger/webservices/atomprotocol/RollerAtomHandler.java b/app/src/main/java/org/apache/roller/weblogger/webservices/atomprotocol/RollerAtomHandler.java
index f397461..f6a427e 100644
--- a/app/src/main/java/org/apache/roller/weblogger/webservices/atomprotocol/RollerAtomHandler.java
+++ b/app/src/main/java/org/apache/roller/weblogger/webservices/atomprotocol/RollerAtomHandler.java
@@ -29,7 +29,6 @@
import org.apache.roller.weblogger.pojos.User;
import org.apache.roller.weblogger.pojos.WeblogEntry;
import org.apache.roller.weblogger.pojos.Weblog;
-import org.apache.roller.weblogger.util.Utilities;
import org.apache.roller.weblogger.util.WSSEUtilities;
import com.rometools.propono.atom.common.AtomService;
import com.rometools.propono.atom.server.AtomException;
@@ -48,6 +47,7 @@
import org.apache.roller.weblogger.config.WebloggerConfig;
import org.apache.roller.weblogger.config.WebloggerRuntimeConfig;
import org.apache.roller.weblogger.pojos.WeblogPermission;
+import org.apache.roller.weblogger.ui.core.RollerContext;
/**
@@ -448,7 +448,6 @@
public String authenticateBASIC(HttpServletRequest request) {
boolean valid = false;
String userID = null;
- String password = null;
try {
String authHeader = request.getHeader("Authorization");
if (authHeader != null) {
@@ -462,17 +461,9 @@
if (p != -1) {
userID = userPass.substring(0, p);
User inUser = roller.getUserManager().getUserByUserName(userID);
- boolean enabled = inUser.getEnabled();
- if (enabled) {
- // are passwords encrypted?
- String encrypted =
- WebloggerConfig.getProperty("passwds.encryption.enabled");
- password = userPass.substring(p+1);
- if ("true".equalsIgnoreCase(encrypted)) {
- password = Utilities.encodePassword(password,
- WebloggerConfig.getProperty("passwds.encryption.algorithm"));
- }
- valid = inUser.getPassword().equals(password);
+ if (inUser.getEnabled()) {
+ String password = userPass.substring(p+1);
+ valid = RollerContext.getPasswordEncoder().matches(password, user.getPassword());
}
}
}
diff --git a/app/src/main/java/org/apache/roller/weblogger/webservices/xmlrpc/BaseAPIHandler.java b/app/src/main/java/org/apache/roller/weblogger/webservices/xmlrpc/BaseAPIHandler.java
index d509fed..6426924 100644
--- a/app/src/main/java/org/apache/roller/weblogger/webservices/xmlrpc/BaseAPIHandler.java
+++ b/app/src/main/java/org/apache/roller/weblogger/webservices/xmlrpc/BaseAPIHandler.java
@@ -25,15 +25,14 @@
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.xmlrpc.XmlRpcException;
-import org.apache.roller.weblogger.config.WebloggerConfig;
import org.apache.roller.weblogger.config.WebloggerRuntimeConfig;
import org.apache.roller.weblogger.business.WebloggerFactory;
import org.apache.roller.weblogger.business.UserManager;
import org.apache.roller.weblogger.business.WeblogManager;
import org.apache.roller.weblogger.pojos.User;
import org.apache.roller.weblogger.pojos.Weblog;
+import org.apache.roller.weblogger.ui.core.RollerContext;
import org.apache.roller.weblogger.util.cache.CacheManager;
-import org.apache.roller.weblogger.util.Utilities;
import org.apache.xmlrpc.common.XmlRpcNotAuthorizedException;
/**
@@ -104,9 +103,9 @@
//------------------------------------------------------------------------
/**
* Returns website, but only if user authenticates and is authorized to edit.
- * @param blogid Blogid sent in request (used as website's hanldle)
+ * @param blogid Blogid sent in request (used as website's handle)
* @param username Username sent in request
- * @param password Password sent in requeset
+ * @param password Password sent in request
*/
protected Weblog validate(String blogid, String username, String password)
throws Exception {
@@ -116,12 +115,10 @@
boolean apiEnabled = false;
boolean weblogFound = false;
Weblog website = null;
- User user = null;
try {
UserManager userMgr = WebloggerFactory.getWeblogger().getUserManager();
WeblogManager weblogMgr = WebloggerFactory.getWeblogger().getWeblogManager();
- user = userMgr.getUserByUserName(username);
- userEnabled = user.getEnabled();
+ User user = userMgr.getUserByUserName(username);
website = weblogMgr.getWeblogByHandle(blogid);
if (website != null) {
@@ -132,15 +129,8 @@
}
if (user != null) {
- // are passwords encrypted
- String encrypted =
- WebloggerConfig.getProperty("passwds.encryption.enabled");
- //System.out.print("password was [" + password + "] ");
- if ("true".equalsIgnoreCase(encrypted)) {
- password = Utilities.encodePassword(password,
- WebloggerConfig.getProperty("passwds.encryption.algorithm"));
- }
- authenticated = password.equals(user.getPassword());
+ userEnabled = user.getEnabled();
+ authenticated = RollerContext.getPasswordEncoder().matches(password, user.getPassword());
}
} catch (Exception e) {
mLogger.error("ERROR internal error validating user", e);
@@ -168,31 +158,21 @@
/**
* Returns true if username/password are valid and user is not disabled.
* @param username Username sent in request
- * @param password Password sent in requeset
+ * @param password Password sent in request
*/
protected boolean validateUser(String username, String password)
throws Exception {
boolean authenticated = false;
boolean enabled = false;
boolean apiEnabled = false;
- User user = null;
try {
UserManager userMgr = WebloggerFactory.getWeblogger().getUserManager();
- user = userMgr.getUserByUserName(username);
+ User user = userMgr.getUserByUserName(username);
- enabled = user.getEnabled();
- if (enabled) {
- // are passwords encrypted?
- String encrypted =
- WebloggerConfig.getProperty("passwds.encryption.enabled");
- //System.out.print("password was [" + password + "] ");
- if ("true".equalsIgnoreCase(encrypted)) {
- password = Utilities.encodePassword(password,
- WebloggerConfig.getProperty("passwds.encryption.algorithm"));
- }
- //System.out.println("is now [" + password + "]");
- authenticated = user.getPassword().equals(password);
+ if (user != null) {
+ enabled = user.getEnabled();
+ authenticated = RollerContext.getPasswordEncoder().matches(password, user.getPassword());
apiEnabled = WebloggerRuntimeConfig.getBooleanProperty("webservices.enableXmlRpc");
}
@@ -200,14 +180,14 @@
mLogger.error("ERROR internal error validating user", e);
}
- if ( !enabled ) {
- throw new XmlRpcNotAuthorizedException(USER_DISABLED_MSG);
- }
-
if ( !authenticated ) {
throw new XmlRpcNotAuthorizedException(AUTHORIZATION_EXCEPTION_MSG);
}
+ if ( !enabled ) {
+ throw new XmlRpcNotAuthorizedException(USER_DISABLED_MSG);
+ }
+
if ( !apiEnabled ) {
throw new XmlRpcNotAuthorizedException(BLOGGERAPI_DISABLED_MSG);
}
diff --git a/app/src/main/resources/org/apache/roller/weblogger/config/roller.properties b/app/src/main/resources/org/apache/roller/weblogger/config/roller.properties
index ffbd275..5308ae7 100644
--- a/app/src/main/resources/org/apache/roller/weblogger/config/roller.properties
+++ b/app/src/main/resources/org/apache/roller/weblogger/config/roller.properties
@@ -348,7 +348,11 @@
# Password security settings
passwds.encryption.enabled=true
-passwds.encryption.algorithm=SHA
+passwds.encryption.algorithm=bcrypt
+
+# Allows lazy upgrade from legacy encodings. Can be plaintext, SHA or MD5 or left empty.
+# Should be set to the value of 'passwds.encryption.algorithm' used on old Roller installations.
+passwds.encryption.lazyUpgradeFrom=SHA
# Role name to global permission action mappings
role.names=editor,admin
@@ -607,7 +611,7 @@
# Some folks consider remember-me type functionality to be a security risk
# If you enable remember me you MUST define a unique secret key that is not 'springRocks'
rememberme.enabled=false
-rememberme.key=
+rememberme.key=springRocks
# You might want to disable GZIP if your app server already supports it
compression.gzipResponse.enabled=true
diff --git a/app/src/main/webapp/WEB-INF/security.xml b/app/src/main/webapp/WEB-INF/security.xml
index d3e8fa3..08e7c62 100644
--- a/app/src/main/webapp/WEB-INF/security.xml
+++ b/app/src/main/webapp/WEB-INF/security.xml
@@ -20,15 +20,15 @@
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
- http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
+ http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
http://www.springframework.org/schema/security
- http://www.springframework.org/schema/security/spring-security-3.2.xsd">
+ http://www.springframework.org/schema/security/spring-security-5.3.xsd">
<http pattern="/images/**" security="none"/>
<http pattern="/scripts/**" security="none"/>
<http pattern="/styles/**" security="none"/>
- <http auto-config="false" access-decision-manager-ref="accessDecisionManager">
+ <http auto-config="false" access-decision-manager-ref="accessDecisionManager" use-expressions="false">
<intercept-url pattern="/roller-ui/login-redirect**" access="admin,editor"/>
<intercept-url pattern="/roller-ui/profile**" access="admin,editor"/>
<intercept-url pattern="/roller-ui/createWeblog**" access="admin,editor"/>
@@ -38,6 +38,8 @@
<intercept-url pattern="/rewrite-status*" access="admin"/>
<form-login login-page="/roller-ui/login.rol"
+ username-parameter="j_username"
+ password-parameter="j_password"
authentication-failure-url="/roller-ui/login.rol?error=true"
login-processing-url="/roller_j_security_check"/>
@@ -45,15 +47,19 @@
key="715F2448-3176-11DD-ABC6-9CD955D89593"/>
<custom-filter ref="openidAuthenticationProcessingFilter" position="OPENID_FILTER"/>
+
+ <!-- roller already uses its own salt based CSRF protection-->
+ <csrf disabled="true"/>
+
+ <!-- some roller UI (i.e. media file editor) uses iframes -->
+ <headers>
+ <frame-options policy="SAMEORIGIN"/>
+ </headers>
</http>
<beans:bean id="accessDecisionManager" class="org.springframework.security.access.vote.AffirmativeBased">
+ <beans:constructor-arg ref="roleVoter"/>
<beans:property name="allowIfAllAbstainDecisions" value="false"/>
- <beans:property name="decisionVoters">
- <beans:list>
- <beans:ref bean="roleVoter"/>
- </beans:list>
- </beans:property>
</beans:bean>
<beans:bean id="roleVoter" class="org.springframework.security.access.vote.RoleVoter">
@@ -78,13 +84,11 @@
<beans:bean id="rollerRememberMeServices"
class="org.apache.roller.weblogger.ui.core.security.RollerRememberMeServices">
- <beans:property name="key" value="ignored"/>
- <beans:property name="userDetailsService" ref="rollerUserService"/>
+ <beans:constructor-arg name="userDetailsService" ref="rollerUserService"/>
</beans:bean>
<beans:bean id="rememberMeAuthenticationProvider"
class="org.apache.roller.weblogger.ui.core.security.RollerRememberMeAuthenticationProvider">
- <beans:property name="key" value="ignored"/>
</beans:bean>
<beans:bean id = "openIDAuthProvider" class="org.springframework.security.openid.OpenIDAuthenticationProvider">
diff --git a/app/src/main/webapp/WEB-INF/web.xml b/app/src/main/webapp/WEB-INF/web.xml
index 3ccd730..27229df 100644
--- a/app/src/main/webapp/WEB-INF/web.xml
+++ b/app/src/main/webapp/WEB-INF/web.xml
@@ -31,6 +31,11 @@
</filter>
<filter>
+ <filter-name>SpringFirewallExceptionFilter</filter-name>
+ <filter-class>org.apache.roller.weblogger.ui.core.filters.SpringFirewallExceptionFilter</filter-class>
+ </filter>
+
+ <filter>
<filter-name>PersistenceSessionFilter</filter-name>
<filter-class>org.apache.roller.weblogger.ui.core.filters.PersistenceSessionFilter</filter-class>
</filter>
@@ -98,6 +103,14 @@
<url-pattern>/roller-ui/rendering/trackback/*</url-pattern>
<dispatcher>FORWARD</dispatcher>
</filter-mapping>
+
+ <!-- keep right above spring firewall filter, see source for details -->
+ <filter-mapping>
+ <filter-name>SpringFirewallExceptionFilter</filter-name>
+ <url-pattern>/*</url-pattern>
+ <dispatcher>REQUEST</dispatcher>
+ <dispatcher>FORWARD</dispatcher>
+ </filter-mapping>
<!-- Spring Security filters - controls secure access to different parts of Roller -->
<filter-mapping>