2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6 * ================================================================================
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 * ============LICENSE_END=========================================================
20 package org.openecomp.sdc.fe.servlets;
22 import java.io.IOException;
23 import java.util.Enumeration;
24 import java.util.List;
25 import javax.servlet.RequestDispatcher;
26 import javax.servlet.ServletException;
27 import javax.servlet.http.Cookie;
28 import javax.servlet.http.HttpServlet;
29 import javax.servlet.http.HttpServletRequest;
30 import javax.servlet.http.HttpServletResponse;
31 import javax.ws.rs.GET;
32 import javax.ws.rs.Path;
33 import javax.ws.rs.core.Context;
34 import org.onap.portalsdk.core.onboarding.exception.CipherUtilException;
35 import org.onap.portalsdk.core.onboarding.util.CipherUtil;
36 import org.onap.sdc.security.AuthenticationCookie;
37 import org.onap.sdc.security.RepresentationUtils;
38 import org.openecomp.sdc.common.impl.MutableHttpServletRequest;
39 import org.openecomp.sdc.common.log.wrappers.Logger;
40 import org.openecomp.sdc.common.util.ValidationUtils;
41 import org.openecomp.sdc.fe.Constants;
42 import org.openecomp.sdc.fe.config.Configuration;
43 import org.openecomp.sdc.fe.config.ConfigurationManager;
44 import org.openecomp.sdc.fe.config.FeEcompErrorManager;
47 * Root resource (exposed at "/" path)
50 public class PortalServlet extends HttpServlet {
52 public static final String MISSING_HEADERS_MSG = "Missing Headers In Request";
53 private static final long serialVersionUID = 1L;
54 private static final String AUTHORIZATION_ERROR_MSG = "Autherization error";
55 private static final String NEW_LINE = System.getProperty("line.separator");
56 private static Logger log = Logger.getLogger(PortalServlet.class.getName());
58 private static String getUserIdFromCookie(HttpServletRequest request) throws CipherUtilException {
60 Cookie[] cookies = request.getCookies();
61 Cookie userIdcookie = null;
62 if (cookies != null) {
63 for (Cookie cookie : cookies) {
64 if (cookie.getName().equals(Constants.ECOMP_PORTAL_COOKIE)) {
65 userIdcookie = cookie;
69 if (userIdcookie != null) {
70 userId = CipherUtil.decrypt(userIdcookie.getValue());
75 private static String getValueFromCookie(HttpServletRequest request, String cookieName) {
77 Cookie[] cookies = request.getCookies();
78 Cookie valueFromCookie = null;
79 if (cookies != null) {
80 for (Cookie cookie : cookies) {
81 if (cookie.getName().endsWith(cookieName)) {
82 valueFromCookie = cookie;
86 if (valueFromCookie != null) {
87 value = valueFromCookie.getValue();
93 * Entry point from ECOMP portal
98 public void doGet(@Context final HttpServletRequest request, @Context final HttpServletResponse response) {
100 addRequestHeadersUsingWebseal(request, response);
101 } catch (Exception e) {
102 FeEcompErrorManager.getInstance().logFePortalServletError("Portal Servlet");
103 log.error("Error during getting portal page", e);
108 * Building new HTTP request and setting headers for the request The request will dispatch to index.html
112 * @throws ServletException
113 * @throws IOException
115 private void addRequestHeadersUsingWebseal(final HttpServletRequest request, final HttpServletResponse response)
116 throws ServletException, IOException, CipherUtilException {
117 response.setContentType("text/html");
118 // Create new request object to dispatch
119 MutableHttpServletRequest mutableRequest = new MutableHttpServletRequest(request);
120 // Get configuration object (reads data from configuration.yaml)
121 Configuration configuration = getConfiguration(request);
122 // Check if we got header from webseal
123 String userId = request.getHeader(Constants.WEBSEAL_USER_ID_HEADER);
124 if (null == userId) {
125 // Authentication via ecomp portal
127 String userIdFromCookie = getUserIdFromCookie(request);
128 if (("").equals(userIdFromCookie)) {
129 // This is probably a webseal request, so missing header in request should be printed.
130 response.sendError(HttpServletResponse.SC_USE_PROXY, MISSING_HEADERS_MSG);
132 userId = userIdFromCookie;
133 } catch (Exception e) {
134 response.sendError(HttpServletResponse.SC_USE_PROXY, AUTHORIZATION_ERROR_MSG);
135 log.error("Error during adding request header", e);
138 // Replace webseal header with open source header
139 mutableRequest.putHeader(Constants.USER_ID, userId);
140 // Getting identification headers from configuration.yaml
142 // (identificationHeaderFields) and setting them to new request
145 List<List<String>> identificationHeaderFields = configuration.getIdentificationHeaderFields();
146 for (List<String> possibleHeadersToRecieve : identificationHeaderFields) {
147 String allowedHeaderToPass = possibleHeadersToRecieve.get(0);
148 setNewHeader(possibleHeadersToRecieve, allowedHeaderToPass, request, mutableRequest);
150 // Getting optional headers from configuration.yaml
152 // (optionalHeaderFields) and setting them to new request mutableRequest
153 List<List<String>> optionalHeaderFields = configuration.getOptionalHeaderFields();
154 for (List<String> possibleHeadersToRecieve : optionalHeaderFields) {
155 String allowedHeaderToPass = possibleHeadersToRecieve.get(0);
156 setNewHeader(possibleHeadersToRecieve, allowedHeaderToPass, request, mutableRequest);
158 // Print headers from original request for debug purposes
159 printHeaders(request);
160 // In case using webseal, validate all mandatory headers (identificationHeaderFields) are included in the new request (mutableRequest).
162 // Via ecomp portal do not need to check the headers.
163 boolean allHeadersExist = true;
164 if (null != request.getHeader(Constants.WEBSEAL_USER_ID_HEADER)) {
165 allHeadersExist = checkHeaders(mutableRequest);
167 if (allHeadersExist) {
168 addCookies(response, mutableRequest, getMandatoryHeaders(request));
169 addCookies(response, mutableRequest, getOptionalHeaders(request));
170 getValueFromCookie(request, Constants.HTTP_CSP_FIRSTNAME);
171 getValueFromCookie(request, Constants.HTTP_CSP_LASTNAME);
173 //addAuthCookie(response, userId, firstNameFromCookie, lastNameFromCookie);
174 RequestDispatcher rd = request.getRequestDispatcher("index.html");
175 rd.forward(mutableRequest, response);
177 response.sendError(HttpServletResponse.SC_USE_PROXY, MISSING_HEADERS_MSG);
181 boolean addAuthCookie(HttpServletResponse response, String userId, String firstName, String lastName) throws IOException {
182 boolean isBuildCookieCompleted = false;
183 Cookie authCookie = null;
184 Configuration.CookieConfig confCookie = ConfigurationManager.getConfigurationManager().getConfiguration().getAuthCookie();
185 //create authentication and send it to encryption
186 String encryptedCookie = "";
188 AuthenticationCookie authenticationCookie = new AuthenticationCookie(userId, firstName, lastName);
189 String cookieAsJson = RepresentationUtils.toRepresentation(authenticationCookie);
190 encryptedCookie = CipherUtil.encryptPKC(cookieAsJson, confCookie.getSecurityKey());
191 isBuildCookieCompleted = true;
192 } catch (Exception e) {
193 log.error(" Cookie Encryption failed ", e);
195 authCookie = new Cookie(confCookie.getCookieName(), encryptedCookie);
196 authCookie.setPath(confCookie.getPath());
197 authCookie.setDomain(confCookie.getDomain());
198 authCookie.setHttpOnly(true);
199 // add generated cookie to response
200 if (isBuildCookieCompleted) {
201 response.addCookie(authCookie);
204 response.sendError(HttpServletResponse.SC_UNAUTHORIZED, AUTHORIZATION_ERROR_MSG);
209 * Print all request headers to the log
213 private void printHeaders(HttpServletRequest request) {
214 if (log.isDebugEnabled()) {
215 StringBuilder builder = new StringBuilder();
216 String sessionId = "";
217 if (request.getSession() != null) {
218 String id = request.getSession().getId();
223 builder.append("Receiving request with headers:" + NEW_LINE);
224 log.debug("{}", request.getHeaderNames());
225 @SuppressWarnings("unchecked") Enumeration<String> headerNames = request.getHeaderNames();
226 if (headerNames != null) {
227 while (headerNames.hasMoreElements()) {
228 String headerName = headerNames.nextElement();
229 String headerValue = request.getHeader(headerName);
230 builder.append("session " + sessionId + " header: name = " + headerName + ", value = " + headerValue + NEW_LINE);
233 log.debug(builder.toString());
238 * Add cookies (that where set in the new request headers) in the response Using DefaultHTTPUtilities Object to prevent CRLF injection in HTTP
245 private void addCookies(final HttpServletResponse response, final HttpServletRequest request, final String[] headers)
246 throws CipherUtilException {
247 for (var i = 0; i < headers.length; i++) {
248 final var currHeader = ValidationUtils.sanitizeInputString(headers[i]);
249 final var headerValue = ValidationUtils.sanitizeInputString(request.getHeader(currHeader));
250 if (headerValue != null) {
251 final var cookie = new Cookie(currHeader, CipherUtil.encryptPKC(headerValue));
252 cookie.setSecure(true);
253 response.addCookie(cookie);
259 * Get mandatory headers (identificationHeaderFields) String array, and checks that each header exists in the new request
264 private boolean checkHeaders(HttpServletRequest request) {
265 String[] mandatoryHeaders = getMandatoryHeaders(request);
266 boolean allHeadersExist = true;
267 for (int i = 0; i < mandatoryHeaders.length; i++) {
268 String headerValue = request.getHeader(mandatoryHeaders[i]);
269 if (headerValue == null) {
270 allHeadersExist = false;
274 return allHeadersExist;
278 * Get mandatory headers (identificationHeaderFields) from configuration.yaml file and return String[]
283 private String[] getMandatoryHeaders(HttpServletRequest request) {
284 Configuration configuration = getConfiguration(request);
285 List<List<String>> identificationHeaderFields = configuration.getIdentificationHeaderFields();
286 String[] mandatoryHeaders = new String[identificationHeaderFields.size()];
287 for (int i = 0; i < identificationHeaderFields.size(); i++) {
288 mandatoryHeaders[i] = identificationHeaderFields.get(i).get(0);
290 return mandatoryHeaders;
294 * Get optional headers (optionalHeaderFields) from configuration.yaml file and return String[]
299 private String[] getOptionalHeaders(HttpServletRequest request) {
300 Configuration configuration = getConfiguration(request);
301 List<List<String>> optionalHeaderFields = configuration.getOptionalHeaderFields();
302 String[] optionalHeaders = new String[optionalHeaderFields.size()];
303 for (int i = 0; i < optionalHeaderFields.size(); i++) {
304 optionalHeaders[i] = optionalHeaderFields.get(i).get(0);
306 return optionalHeaders;
310 * Return Configuration object to read from configuration.yaml
313 * @return Configuration
315 private Configuration getConfiguration(HttpServletRequest request) {
316 ConfigurationManager configManager = (ConfigurationManager) request.getSession().getServletContext()
317 .getAttribute(org.openecomp.sdc.common.api.Constants.CONFIGURATION_MANAGER_ATTR);
318 return configManager.getConfiguration();
321 private boolean setNewHeader(List<String> possibleOldHeaders, String newHeaderToSet, HttpServletRequest oldRequest,
322 MutableHttpServletRequest newRequest) {
323 boolean newHeaderIsSet = false;
324 for (int i = 0; i < possibleOldHeaders.size() && !newHeaderIsSet; i++) {
325 String headerValue = oldRequest.getHeader(possibleOldHeaders.get(i));
326 if (headerValue != null) {
327 newRequest.putHeader(newHeaderToSet, headerValue);
328 newHeaderIsSet = true;
331 return newHeaderIsSet;