/* * (C) Copyright 2010 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 */ package org.nuxeo.ecm.platform.shibboleth.auth; import java.io.IOException; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.lang3.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.nuxeo.ecm.core.api.DocumentModel; 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.shibboleth.service.ShibbolethAuthenticationService; import org.nuxeo.ecm.platform.ui.web.auth.interfaces.NuxeoAuthenticationPlugin; import org.nuxeo.ecm.platform.ui.web.auth.interfaces.NuxeoAuthenticationPluginLogoutExtension; import org.nuxeo.ecm.platform.usermanager.UserManager; import org.nuxeo.runtime.api.Framework; import org.nuxeo.usermapper.extension.UserMapper; import org.nuxeo.usermapper.service.UserMapperService; public class ShibbolethAuthenticationPlugin implements NuxeoAuthenticationPlugin, NuxeoAuthenticationPluginLogoutExtension { private static final Log log = LogFactory.getLog(ShibbolethAuthenticationPlugin.class); public static final String EXTERNAL_MAPPER_PARAM = "mapper"; public static final String DEFAULT_EXTERNAL_MAPPER = "shibboleth"; protected UserMapper externalMapper = null; protected ShibbolethAuthenticationService getService() { return Framework.getService(ShibbolethAuthenticationService.class); } @Override public List<String> getUnAuthenticatedURLPrefix() { return null; } @Override public Boolean handleLoginPrompt(HttpServletRequest httpRequest, HttpServletResponse httpResponse, String baseURL) { if (getService() == null) { return false; } String loginURL = getService().getLoginURL(httpRequest); if (loginURL == null) { log.error("Unable to handle Shibboleth login, no loginURL registered"); return false; } try { httpResponse.sendRedirect(loginURL); } catch (IOException e) { String errorMessage = String.format("Unable to handle Shibboleth login on %s", loginURL); log.error(errorMessage, e); return false; } return true; } @Override public Boolean handleLogout(HttpServletRequest httpRequest, HttpServletResponse httpResponse) { if (getService() == null) { return false; } String logoutURL = getService().getLogoutURL(httpRequest); if (logoutURL == null) { return false; } try { httpResponse.sendRedirect(logoutURL); } catch (IOException e) { log.error("Unable to handle Shibboleth logout", e); return false; } return true; } @Override public UserIdentificationInfo handleRetrieveIdentity(HttpServletRequest httpRequest, HttpServletResponse httpResponse) { if (getService() == null) { return null; } String userId = getService().getUserID(httpRequest); if (userId == null || StringUtils.EMPTY.equals(userId)) { return null; } else { UserMapperService ums = Framework.getService(UserMapperService.class); if (ums != null) { if (ums.getAvailableMappings().contains(DEFAULT_EXTERNAL_MAPPER)) { externalMapper = ums.getMapper(DEFAULT_EXTERNAL_MAPPER); } } } UserManager userManager = Framework.getService(UserManager.class); Map<String, Object> fieldMap = getService().getUserMetadata(userManager.getUserIdField(), httpRequest); if (externalMapper != null) { Map<String, Object> nativeObject = new HashMap<String, Object>(); nativeObject.putAll(fieldMap); nativeObject.put("userId", userId); externalMapper.getOrCreateAndUpdateNuxeoPrincipal(nativeObject); } else { try (Session userDir = Framework.getService(DirectoryService.class).open(userManager.getUserDirectoryName())) { DocumentModel entry = userDir.getEntry(userId); if (entry == null) { userDir.createEntry(fieldMap); } else { entry.setProperties(userManager.getUserSchemaName(), fieldMap); userDir.updateEntry(entry); } } catch (DirectoryException e) { log.error("Failed to get or create user entry", e); } } return new UserIdentificationInfo(userId, userId); } @Override public Boolean needLoginPrompt(HttpServletRequest httpRequest) { return true; } @Override public void initPlugin(Map<String, String> parameters) { } }