/* * (C) Copyright 2006-2007 Nuxeo SA (http://nuxeo.com/) and others. * * Licensed 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. * * Contributors: * Nuxeo - initial API and implementation * * $Id: JOOoConvertPluginImpl.java 18651 2007-05-13 20:28:53Z sfermigier $ */ package org.nuxeo.ecm.platform.ui.web.auth.proxy; import java.io.Serializable; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.nuxeo.ecm.core.api.DocumentModelList; import org.nuxeo.ecm.directory.DirectoryException; import org.nuxeo.ecm.directory.Session; import org.nuxeo.ecm.directory.api.DirectoryService; import org.nuxeo.ecm.platform.api.login.UserIdentificationInfo; import org.nuxeo.ecm.platform.ui.web.auth.LoginScreenHelper; import org.nuxeo.ecm.platform.ui.web.auth.NXAuthConstants; import org.nuxeo.ecm.platform.ui.web.auth.NuxeoAuthenticationFilter; import org.nuxeo.ecm.platform.ui.web.auth.interfaces.NuxeoAuthenticationPlugin; import org.nuxeo.ecm.platform.usermanager.UserManager; import org.nuxeo.runtime.api.Framework; public class ProxyAuthenticator implements NuxeoAuthenticationPlugin { private static final Log log = LogFactory.getLog(ProxyAuthenticator.class); private static final String HEADER_NAME_KEY = "ssoHeaderName"; private static final String HEADER_NOREDIRECT_KEY = "ssoNeverRedirect"; public static final String USERNAME_REMOVE_EXPRESSION = "usernameUnwantedPartExpression"; protected String userIdHeaderName = "remote_user"; protected String regexp = null; protected boolean noRedirect; public static final String HTTP_CREDENTIAL_DIRECTORY_FIELD_PROPERTY_NAME = "org.nuxeo.ecm.platform.login.mod_sso.credentialDirectoryField"; private Pattern usernamePartRemovalPattern; @Override public List<String> getUnAuthenticatedURLPrefix() { return null; } @Override public Boolean handleLoginPrompt(HttpServletRequest httpRequest, HttpServletResponse httpResponse, String baseURL) { return false; } @Override public UserIdentificationInfo handleRetrieveIdentity(HttpServletRequest httpRequest, HttpServletResponse httpResponse) { String userName = httpRequest.getHeader(userIdHeaderName); if (userName == null) { return null; } if (regexp != null && usernamePartRemovalPattern != null) { String tmpUsername = userName; Matcher matcher = usernamePartRemovalPattern.matcher(userName); // Remove all instance of regexp from username string userName = matcher.replaceAll(""); log.debug(String.format("userName changed from '%s' to '%s'", tmpUsername, userName)); } String credentialFieldName = Framework.getRuntime().getProperty(HTTP_CREDENTIAL_DIRECTORY_FIELD_PROPERTY_NAME); if (credentialFieldName != null) { // use custom directory field to find the user with the ID given in // the HTTP header String directoryName = Framework.getService(UserManager.class).getUserDirectoryName(); try (Session userDir = Framework.getService(DirectoryService.class).open(directoryName)) { Map<String, Serializable> queryFilters = new HashMap<String, Serializable>(); queryFilters.put(credentialFieldName, userName); DocumentModelList result = userDir.query(queryFilters); if (result.isEmpty()) { log.error(String.format("could not find any user with %s='%s' in directory %s", credentialFieldName, userName, directoryName)); return null; } if (result.size() > 1) { log.error(String.format("found more than one entry for %s='%s' in directory %s", credentialFieldName, userName, directoryName)); return null; } // use the ID of the found user entry as new identification for // the principal userName = result.get(0).getId(); } catch (DirectoryException e) { log.error(String.format("could not retrieve user entry with %s='%s': %s", credentialFieldName, userName, e.getMessage()), e); return null; } } if (!noRedirect) { handleRedirectToValidStartPage(httpRequest, httpResponse); } return new UserIdentificationInfo(userName, userName); } /** * Handle redirection so that context is rebuilt correctly see NXP-2060 + NXP-2064 */ protected void handleRedirectToValidStartPage(HttpServletRequest httpRequest, HttpServletResponse httpResponse) { boolean isStartPageValid = false; if (httpRequest.getMethod().equals("GET") || httpRequest.getMethod().equals("POST")) { // try to keep valid start page NuxeoAuthenticationFilter filter = new NuxeoAuthenticationFilter(); isStartPageValid = filter.saveRequestedURLBeforeRedirect(httpRequest, httpResponse); } HttpSession session; if (httpResponse.isCommitted()) { session = httpRequest.getSession(false); } else { session = httpRequest.getSession(true); } if (session != null && !isStartPageValid) { session.setAttribute(NXAuthConstants.START_PAGE_SAVE_KEY, LoginScreenHelper.getStartupPagePath() + "?loginRedirection=true"); } } @Override public void initPlugin(Map<String, String> parameters) { if (parameters.containsKey(HEADER_NAME_KEY)) { userIdHeaderName = parameters.get(HEADER_NAME_KEY); } if (parameters.containsKey(HEADER_NOREDIRECT_KEY)) { noRedirect = Boolean.parseBoolean(parameters.get(HEADER_NOREDIRECT_KEY)); } if (parameters.containsKey(USERNAME_REMOVE_EXPRESSION)) { regexp = parameters.get(USERNAME_REMOVE_EXPRESSION); log.debug(String.format("Will remove all instances of '%s' from userName string.", regexp)); usernamePartRemovalPattern = Pattern.compile(regexp); } } @Override public Boolean needLoginPrompt(HttpServletRequest httpRequest) { return false; } }