001/* 002 * (C) Copyright 2010-2018 Nuxeo (http://nuxeo.com/) and others. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 * 016 * Contributors: 017 * Nuxeo - initial API and implementation 018 */ 019 020package org.nuxeo.ecm.platform.shibboleth.service; 021 022import static org.apache.commons.lang3.StringUtils.isNotEmpty; 023import static org.nuxeo.ecm.platform.ui.web.auth.NXAuthConstants.REDIRECT_URL; 024 025import java.io.UnsupportedEncodingException; 026import java.util.HashMap; 027import java.util.Map; 028 029import javax.servlet.http.HttpServletRequest; 030 031import org.nuxeo.common.utils.URIUtils; 032import org.nuxeo.ecm.platform.web.common.vh.VirtualHostHelper; 033import org.nuxeo.runtime.model.ComponentInstance; 034import org.nuxeo.runtime.model.DefaultComponent; 035 036import com.google.common.collect.BiMap; 037import com.google.common.collect.HashBiMap; 038 039public class ShibbolethAuthenticationServiceImpl extends DefaultComponent implements ShibbolethAuthenticationService { 040 041 public static final String CONFIG_EP = "config"; 042 043 protected ShibbolethAuthenticationConfig config; 044 045 @Override 046 public void registerContribution(Object contribution, String extensionPoint, ComponentInstance contributor) { 047 if (CONFIG_EP.equals(extensionPoint)) { 048 config = (ShibbolethAuthenticationConfig) contribution; 049 } 050 } 051 052 public ShibbolethAuthenticationConfig getConfig() { 053 return config; 054 } 055 056 @Override 057 public String getLoginURL(String redirectURL) { 058 if (config == null || config.getLoginURL() == null) { 059 return null; 060 } 061 062 Map<String, String> urlParameters = new HashMap<>(1); 063 urlParameters.put(config.getLoginRedirectURLParameter(), redirectURL); 064 return URIUtils.addParametersToURIQuery(config.getLoginURL(), urlParameters); 065 } 066 067 @Override 068 public String getLogoutURL(String redirectURL) { 069 if (config == null || config.getLogoutURL() == null) { 070 return null; 071 } 072 073 Map<String, String> urlParameters = new HashMap<>(1); 074 urlParameters.put(config.getLogoutRedirectURLParameter(), redirectURL); 075 return URIUtils.addParametersToURIQuery(config.getLogoutURL(), urlParameters); 076 } 077 078 @Override 079 public String getLoginURL(HttpServletRequest request) { 080 String redirectUrl = VirtualHostHelper.getRedirectUrl(request); 081 request.getSession().setAttribute(REDIRECT_URL, redirectUrl); 082 return getLoginURL(redirectUrl); 083 } 084 085 @Override 086 public String getLogoutURL(HttpServletRequest request) { 087 return getLogoutURL((String) request.getSession().getAttribute(REDIRECT_URL)); 088 } 089 090 @Override 091 public String getUserID(HttpServletRequest httpRequest) { 092 String idpUrl = httpRequest.getHeader(config.getIdpHeader()); 093 String uidHeader = config.getUidHeaders().get(idpUrl); 094 if (uidHeader == null || readHeader(httpRequest, uidHeader) == null 095 || readHeader(httpRequest, uidHeader).isEmpty()) { 096 uidHeader = config.getDefaultUidHeader(); 097 } 098 return readHeader(httpRequest, uidHeader); 099 } 100 101 @Override 102 public Map<String, Object> getUserMetadata(String userIdField, HttpServletRequest httpRequest) { 103 Map<String, Object> fieldMap = new HashMap<>(config.fieldMapping.size()); 104 for (String key : config.getFieldMapping().keySet()) { 105 fieldMap.put(config.getFieldMapping().get(key), readHeader(httpRequest, key)); 106 } 107 // Force userIdField to shibb userId value in case of the IdP do 108 // not use the same mapping as the default's one. 109 fieldMap.put(userIdField, getUserID(httpRequest)); 110 return fieldMap; 111 } 112 113 @Override 114 public BiMap<String, String> getUserMetadata() { 115 BiMap<String, String> biMap = HashBiMap.create(); 116 biMap.putAll(config.getFieldMapping()); 117 return biMap; 118 } 119 120 protected String readHeader(HttpServletRequest request, String key) { 121 String value = request.getHeader(key); 122 if (isNotEmpty(value) && isNotEmpty(config.getHeaderEncoding())) { 123 try { 124 value = new String(value.getBytes("ISO-8859-1"), config.getHeaderEncoding()); 125 } catch (UnsupportedEncodingException ignored) { 126 // Nothing 127 } 128 } 129 return value; 130 } 131}