Author: jamesyong
Date: Sat Dec 23 10:39:44 2017 New Revision: 1819133 URL: http://svn.apache.org/viewvc?rev=1819133&view=rev Log: Implemented: Tomcat SSO (OFBIZ-10047) This allow developers the option to use Tomcat SSO, instead of externalLoginKey, for SSO. Thanks: Jacques and Michael for the reviews Added: ofbiz/ofbiz-framework/trunk/framework/catalina/src/main/java/org/apache/ofbiz/catalina/container/HashedCredentialHandler.java (with props) ofbiz/ofbiz-framework/trunk/framework/catalina/src/main/java/org/apache/ofbiz/catalina/container/OFBizRealm.java (with props) ofbiz/ofbiz-framework/trunk/framework/catalina/src/main/java/org/apache/ofbiz/catalina/container/SimpleCredentialHandler.java (with props) Modified: ofbiz/ofbiz-framework/trunk/framework/catalina/src/main/java/org/apache/ofbiz/catalina/container/CatalinaContainer.java ofbiz/ofbiz-framework/trunk/framework/common/servicedef/services.xml ofbiz/ofbiz-framework/trunk/framework/common/src/main/java/org/apache/ofbiz/common/login/LoginServices.java ofbiz/ofbiz-framework/trunk/framework/security/config/security.properties ofbiz/ofbiz-framework/trunk/framework/webapp/src/main/java/org/apache/ofbiz/webapp/control/LoginWorker.java Modified: ofbiz/ofbiz-framework/trunk/framework/catalina/src/main/java/org/apache/ofbiz/catalina/container/CatalinaContainer.java URL: http://svn.apache.org/viewvc/ofbiz/ofbiz-framework/trunk/framework/catalina/src/main/java/org/apache/ofbiz/catalina/container/CatalinaContainer.java?rev=1819133&r1=1819132&r2=1819133&view=diff ============================================================================== --- ofbiz/ofbiz-framework/trunk/framework/catalina/src/main/java/org/apache/ofbiz/catalina/container/CatalinaContainer.java (original) +++ ofbiz/ofbiz-framework/trunk/framework/catalina/src/main/java/org/apache/ofbiz/catalina/container/CatalinaContainer.java Sat Dec 23 10:39:44 2017 @@ -42,6 +42,7 @@ import org.apache.catalina.Globals; import org.apache.catalina.Host; import org.apache.catalina.LifecycleException; import org.apache.catalina.Valve; +import org.apache.catalina.authenticator.SingleSignOn; import org.apache.catalina.connector.Connector; import org.apache.catalina.core.StandardContext; import org.apache.catalina.core.StandardEngine; @@ -75,6 +76,7 @@ import org.apache.ofbiz.base.start.Start import org.apache.ofbiz.base.util.Debug; import org.apache.ofbiz.base.util.UtilValidate; import org.apache.ofbiz.base.util.UtilXml; +import org.apache.ofbiz.entity.util.EntityUtilProperties; import org.apache.tomcat.JarScanner; import org.apache.tomcat.util.IntrospectionUtils; import org.apache.tomcat.util.descriptor.web.FilterDef; @@ -108,6 +110,19 @@ public class CatalinaContainer implement Engine engine = prepareTomcatEngine(tomcat, engineConfig); Host host = prepareHost(tomcat, null); + // add realm and valve for Tomcat SSO + if (EntityUtilProperties.propertyValueEquals("security", "security.login.tomcat.sso", "true")){ + boolean useEncryption = EntityUtilProperties.propertyValueEquals("security", "password.encrypt", "true"); + OFBizRealm ofBizRealm = new OFBizRealm(); + if (useEncryption){ + ofBizRealm.setCredentialHandler(new HashedCredentialHandler()); + } else { + ofBizRealm.setCredentialHandler(new SimpleCredentialHandler()); + } + host.setRealm(ofBizRealm); + ((StandardHost)host).addValve(new SingleSignOn()); + } + // clustering, valves and connectors setup Property clusterProps = prepareTomcatClustering(host, engineConfig); prepareTomcatEngineValves(engineConfig).forEach(valve -> ((StandardEngine)engine).addValve(valve)); Added: ofbiz/ofbiz-framework/trunk/framework/catalina/src/main/java/org/apache/ofbiz/catalina/container/HashedCredentialHandler.java URL: http://svn.apache.org/viewvc/ofbiz/ofbiz-framework/trunk/framework/catalina/src/main/java/org/apache/ofbiz/catalina/container/HashedCredentialHandler.java?rev=1819133&view=auto ============================================================================== --- ofbiz/ofbiz-framework/trunk/framework/catalina/src/main/java/org/apache/ofbiz/catalina/container/HashedCredentialHandler.java (added) +++ ofbiz/ofbiz-framework/trunk/framework/catalina/src/main/java/org/apache/ofbiz/catalina/container/HashedCredentialHandler.java Sat Dec 23 10:39:44 2017 @@ -0,0 +1,35 @@ +/******************************************************************************* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. 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. + *******************************************************************************/ +package org.apache.ofbiz.catalina.container; + +import org.apache.catalina.CredentialHandler; +import org.apache.ofbiz.base.crypto.HashCrypt; +import org.apache.ofbiz.common.login.LoginServices; + +public class HashedCredentialHandler implements CredentialHandler { + @Override + public boolean matches(String inputCredentials, String storedCredentials) { + return LoginServices.checkPassword(storedCredentials, true, inputCredentials); + } + + @Override + public String mutate(String inputCredentials) { + return HashCrypt.cryptUTF8(LoginServices.getHashType(), null, inputCredentials); + } +} Propchange: ofbiz/ofbiz-framework/trunk/framework/catalina/src/main/java/org/apache/ofbiz/catalina/container/HashedCredentialHandler.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: ofbiz/ofbiz-framework/trunk/framework/catalina/src/main/java/org/apache/ofbiz/catalina/container/HashedCredentialHandler.java ------------------------------------------------------------------------------ svn:keywords = Date Rev Author URL Id Propchange: ofbiz/ofbiz-framework/trunk/framework/catalina/src/main/java/org/apache/ofbiz/catalina/container/HashedCredentialHandler.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: ofbiz/ofbiz-framework/trunk/framework/catalina/src/main/java/org/apache/ofbiz/catalina/container/OFBizRealm.java URL: http://svn.apache.org/viewvc/ofbiz/ofbiz-framework/trunk/framework/catalina/src/main/java/org/apache/ofbiz/catalina/container/OFBizRealm.java?rev=1819133&view=auto ============================================================================== --- ofbiz/ofbiz-framework/trunk/framework/catalina/src/main/java/org/apache/ofbiz/catalina/container/OFBizRealm.java (added) +++ ofbiz/ofbiz-framework/trunk/framework/catalina/src/main/java/org/apache/ofbiz/catalina/container/OFBizRealm.java Sat Dec 23 10:39:44 2017 @@ -0,0 +1,65 @@ +/******************************************************************************* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. 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. + *******************************************************************************/ +package org.apache.ofbiz.catalina.container; + +import java.security.Principal; +import java.util.ArrayList; +import java.util.List; + +import org.apache.catalina.realm.GenericPrincipal; +import org.apache.catalina.realm.RealmBase; +import org.apache.ofbiz.base.util.Debug; +import org.apache.ofbiz.entity.Delegator; +import org.apache.ofbiz.entity.DelegatorFactory; +import org.apache.ofbiz.entity.GenericEntityException; +import org.apache.ofbiz.entity.GenericValue; +import org.apache.ofbiz.entity.util.EntityQuery; + +public class OFBizRealm extends RealmBase +{ + public static final String module = OFBizRealm.class.getName(); + + @Override + protected String getName() { + return "OFBizRealm"; + } + + @Override + protected String getPassword(String username) { + Delegator delegator = DelegatorFactory.getDelegator(null); + try { + GenericValue userLogin = EntityQuery.use(delegator).from("UserLogin").where("userLoginId", username).queryOne(); + if (userLogin!=null){ + return userLogin.getString("currentPassword"); + } + } catch (GenericEntityException e) { + Debug.logError(e, module); + } + return null; + } + + @Override + protected Principal getPrincipal(String username) { + List<String> roles = new ArrayList<>(); + return new GenericPrincipal(username, + getPassword(username), + roles); + } + +} \ No newline at end of file Propchange: ofbiz/ofbiz-framework/trunk/framework/catalina/src/main/java/org/apache/ofbiz/catalina/container/OFBizRealm.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: ofbiz/ofbiz-framework/trunk/framework/catalina/src/main/java/org/apache/ofbiz/catalina/container/OFBizRealm.java ------------------------------------------------------------------------------ svn:keywords = Date Rev Author URL Id Propchange: ofbiz/ofbiz-framework/trunk/framework/catalina/src/main/java/org/apache/ofbiz/catalina/container/OFBizRealm.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: ofbiz/ofbiz-framework/trunk/framework/catalina/src/main/java/org/apache/ofbiz/catalina/container/SimpleCredentialHandler.java URL: http://svn.apache.org/viewvc/ofbiz/ofbiz-framework/trunk/framework/catalina/src/main/java/org/apache/ofbiz/catalina/container/SimpleCredentialHandler.java?rev=1819133&view=auto ============================================================================== --- ofbiz/ofbiz-framework/trunk/framework/catalina/src/main/java/org/apache/ofbiz/catalina/container/SimpleCredentialHandler.java (added) +++ ofbiz/ofbiz-framework/trunk/framework/catalina/src/main/java/org/apache/ofbiz/catalina/container/SimpleCredentialHandler.java Sat Dec 23 10:39:44 2017 @@ -0,0 +1,37 @@ +/******************************************************************************* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. 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. + *******************************************************************************/ +package org.apache.ofbiz.catalina.container; + +import org.apache.catalina.CredentialHandler; +import org.apache.ofbiz.common.login.LoginServices; + + +public class SimpleCredentialHandler implements CredentialHandler { + @Override + public boolean matches(String inputCredentials, String storedCredentials) { + return LoginServices.checkPassword(storedCredentials, false, inputCredentials); + } + + @Override + public String mutate(String inputCredentials) { + // when password.encrypt=false, password is stored as clear text in the database. + // no need to encrypt this input password. + return null; + } +} Propchange: ofbiz/ofbiz-framework/trunk/framework/catalina/src/main/java/org/apache/ofbiz/catalina/container/SimpleCredentialHandler.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: ofbiz/ofbiz-framework/trunk/framework/catalina/src/main/java/org/apache/ofbiz/catalina/container/SimpleCredentialHandler.java ------------------------------------------------------------------------------ svn:keywords = Date Rev Author URL Id Propchange: ofbiz/ofbiz-framework/trunk/framework/catalina/src/main/java/org/apache/ofbiz/catalina/container/SimpleCredentialHandler.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Modified: ofbiz/ofbiz-framework/trunk/framework/common/servicedef/services.xml URL: http://svn.apache.org/viewvc/ofbiz/ofbiz-framework/trunk/framework/common/servicedef/services.xml?rev=1819133&r1=1819132&r2=1819133&view=diff ============================================================================== --- ofbiz/ofbiz-framework/trunk/framework/common/servicedef/services.xml (original) +++ ofbiz/ofbiz-framework/trunk/framework/common/servicedef/services.xml Sat Dec 23 10:39:44 2017 @@ -379,6 +379,7 @@ under the License. <service name="userLogin" engine="java" location="org.apache.ofbiz.common.login.LoginServices" invoke="userLogin"> <description>Used to Automatically Authenticate a username/password; create a UserLogin object</description> <implements service="authenticationInterface"/> + <attribute name="request" mode="IN" type="javax.servlet.http.HttpServletRequest" optional="true"/> </service> <service name="createUserLogin" engine="java" auth="false" location="org.apache.ofbiz.common.login.LoginServices" invoke="createUserLogin"> Modified: ofbiz/ofbiz-framework/trunk/framework/common/src/main/java/org/apache/ofbiz/common/login/LoginServices.java URL: http://svn.apache.org/viewvc/ofbiz/ofbiz-framework/trunk/framework/common/src/main/java/org/apache/ofbiz/common/login/LoginServices.java?rev=1819133&r1=1819132&r2=1819133&view=diff ============================================================================== --- ofbiz/ofbiz-framework/trunk/framework/common/src/main/java/org/apache/ofbiz/common/login/LoginServices.java (original) +++ ofbiz/ofbiz-framework/trunk/framework/common/src/main/java/org/apache/ofbiz/common/login/LoginServices.java Sat Dec 23 10:39:44 2017 @@ -28,6 +28,8 @@ import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; import javax.transaction.Transaction; import org.apache.ofbiz.base.crypto.HashCrypt; @@ -58,6 +60,8 @@ import org.apache.ofbiz.service.ModelSer import org.apache.ofbiz.service.ServiceUtil; import org.apache.ofbiz.webapp.control.LoginWorker; +import org.apache.tomcat.util.res.StringManager; + /** * <b>Title:</b> Login Services */ @@ -209,10 +213,18 @@ public class LoginServices { authFatalError = true; } + + // check whether to sign in with Tomcat SSO + boolean useTomcatSSO = EntityUtilProperties.propertyValueEquals("security", "security.login.tomcat.sso", "true"); + HttpServletRequest request = (javax.servlet.http.HttpServletRequest) context.get("request"); + // when request is not supplied, we will treat that SSO is not required as + // in the usage of userLogin service in ICalWorker.java and XmlRpcEventHandler.java. + useTomcatSSO = useTomcatSSO && (request!=null); + // if the password.accept.encrypted.and.plain property in security is set to true allow plain or encrypted passwords // if this is a system account don't bother checking the passwords // if externalAuth passed; this is run as well - if ((!authFatalError && externalAuth) || checkPassword(userLogin.getString("currentPassword"), useEncryption, password)) { + if ((!authFatalError && externalAuth) || (useTomcatSSO ? TomcatSSOLogin(request, username, password) : checkPassword(userLogin.getString("currentPassword"), useEncryption, password) )) { Debug.logVerbose("[LoginServices.userLogin] : Password Matched", module); // update the hasLoggedOut flag @@ -1016,7 +1028,7 @@ public class LoginServices { return hashType; } - private static boolean checkPassword(String oldPassword, boolean useEncryption, String currentPassword) { + public static boolean checkPassword(String oldPassword, boolean useEncryption, String currentPassword) { boolean passwordMatches = false; if (oldPassword != null) { if (useEncryption) { @@ -1030,4 +1042,20 @@ public class LoginServices { } return passwordMatches; } + + private static boolean TomcatSSOLogin(HttpServletRequest request, String userName, String currentPassword) { + try { + request.login(userName, currentPassword); + } catch (ServletException e) { + + StringManager sm = StringManager.getManager("org.apache.catalina.connector"); + if (sm.getString("coyoteRequest.alreadyAuthenticated").equals(e.getMessage())){ + return true; + } else { + Debug.logError(e, module); + return false; + } + } + return true; + } } Modified: ofbiz/ofbiz-framework/trunk/framework/security/config/security.properties URL: http://svn.apache.org/viewvc/ofbiz/ofbiz-framework/trunk/framework/security/config/security.properties?rev=1819133&r1=1819132&r2=1819133&view=diff ============================================================================== --- ofbiz/ofbiz-framework/trunk/framework/security/config/security.properties (original) +++ ofbiz/ofbiz-framework/trunk/framework/security/config/security.properties Sat Dec 23 10:39:44 2017 @@ -116,6 +116,9 @@ security.login.cert.allow=true # -- pattern for the userlogin id in CN section of certificate security.login.cert.pattern=^(\\w*\\s?\\w*)\\W*.*$ +# -- use Tomcat SingleSignOn valve +security.login.tomcat.sso=false + # -- Hours after which EmailAdressVerification should expire email_verification.expire.hours=48 Modified: ofbiz/ofbiz-framework/trunk/framework/webapp/src/main/java/org/apache/ofbiz/webapp/control/LoginWorker.java URL: http://svn.apache.org/viewvc/ofbiz/ofbiz-framework/trunk/framework/webapp/src/main/java/org/apache/ofbiz/webapp/control/LoginWorker.java?rev=1819133&r1=1819132&r2=1819133&view=diff ============================================================================== --- ofbiz/ofbiz-framework/trunk/framework/webapp/src/main/java/org/apache/ofbiz/webapp/control/LoginWorker.java (original) +++ ofbiz/ofbiz-framework/trunk/framework/webapp/src/main/java/org/apache/ofbiz/webapp/control/LoginWorker.java Sat Dec 23 10:39:44 2017 @@ -34,6 +34,7 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.servlet.ServletContext; +import javax.servlet.ServletException; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @@ -330,7 +331,7 @@ public class LoginWorker { String username = request.getParameter("USERNAME"); String password = request.getParameter("PASSWORD"); String forgotPwdFlag = request.getParameter("forgotPwdFlag"); - + // password decryption EntityCrypto entityDeCrypto = null; try { @@ -435,7 +436,7 @@ public class LoginWorker { try { // get the visit id to pass to the userLogin for history String visitId = VisitHandler.getVisitId(session); - result = dispatcher.runSync("userLogin", UtilMisc.toMap("login.username", username, "login.password", password, "visitId", visitId, "locale", UtilHttp.getLocale(request))); + result = dispatcher.runSync("userLogin", UtilMisc.toMap("login.username", username, "login.password", password, "visitId", visitId, "locale", UtilHttp.getLocale(request), "request", request)); } catch (GenericServiceException e) { Debug.logError(e, "Error calling userLogin service", module); Map<String, String> messageMap = UtilMisc.toMap("errorMessage", e.getMessage()); @@ -665,6 +666,15 @@ public class LoginWorker { session.invalidate(); session = request.getSession(true); + if (EntityUtilProperties.propertyValueEquals("security", "security.login.tomcat.sso", "true")){ + try { + // log out from Tomcat SSO + request.logout(); + } catch (ServletException e) { + Debug.logError(e, module); + } + } + // setup some things that should always be there UtilHttp.setInitialRequestInfo(request); @@ -872,6 +882,20 @@ public class LoginWorker { } } } + Boolean useTomcatSSO = EntityUtilProperties.propertyValueEquals("security", "security.login.tomcat.sso", "true"); + if (useTomcatSSO) { + + // make sure the user isn't already logged in + if (!LoginWorker.isUserLoggedIn(request)) { + String remoteUserId = request.getRemoteUser(); + if (UtilValidate.isNotEmpty(remoteUserId)) { + return LoginWorker.loginUserWithUserLoginId(request, response, remoteUserId); + } else { + // user is/has logged out at this point + return "success"; + } + } + } return "success"; } |
Free forum by Nabble | Edit this page |