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 {
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);
174 //addAuthCookie(response, userId, firstNameFromCookie, lastNameFromCookie);
175 RequestDispatcher rd = request.getRequestDispatcher("index.html");
176 rd.forward(mutableRequest, response);
178 response.sendError(HttpServletResponse.SC_USE_PROXY, MISSING_HEADERS_MSG);
182 boolean addAuthCookie(HttpServletResponse response, String userId, String firstName, String lastName) throws IOException {
183 boolean isBuildCookieCompleted = true;
184 Cookie authCookie = null;
185 Configuration.CookieConfig confCookie = ConfigurationManager.getConfigurationManager().getConfiguration().getAuthCookie();
186 //create authentication and send it to encryption
187 String encryptedCookie = "";
189 AuthenticationCookie authenticationCookie = new AuthenticationCookie(userId, firstName, lastName);
190 String cookieAsJson = RepresentationUtils.toRepresentation(authenticationCookie);
191 encryptedCookie = org.onap.sdc.security.CipherUtil.encryptPKC(cookieAsJson, confCookie.getSecurityKey());
192 } catch (Exception e) {
193 isBuildCookieCompleted = false;
194 log.error(" Cookie Encryption failed ", e);
196 authCookie = new Cookie(confCookie.getCookieName(), encryptedCookie);
197 authCookie.setPath(confCookie.getPath());
198 authCookie.setDomain(confCookie.getDomain());
199 authCookie.setHttpOnly(true);
200 // add generated cookie to response
201 if (isBuildCookieCompleted) {
202 response.addCookie(authCookie);
205 response.sendError(HttpServletResponse.SC_UNAUTHORIZED, AUTHORIZATION_ERROR_MSG);
210 * Print all request headers to the log
214 private void printHeaders(HttpServletRequest request) {
215 if (log.isDebugEnabled()) {
216 StringBuilder builder = new StringBuilder();
217 String sessionId = "";
218 if (request.getSession() != null) {
219 String id = request.getSession().getId();
224 builder.append("Receiving request with headers:" + NEW_LINE);
225 log.debug("{}", request.getHeaderNames());
226 @SuppressWarnings("unchecked") Enumeration<String> headerNames = request.getHeaderNames();
227 if (headerNames != null) {
228 while (headerNames.hasMoreElements()) {
229 String headerName = headerNames.nextElement();
230 String headerValue = request.getHeader(headerName);
231 builder.append("session " + sessionId + " header: name = " + headerName + ", value = " + headerValue + NEW_LINE);
234 log.debug(builder.toString());
239 * Add cookies (that where set in the new request headers) in the response Using DefaultHTTPUtilities Object to prevent CRLF injection in HTTP
246 private void addCookies(final HttpServletResponse response, final HttpServletRequest request, final String[] headers) {
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, 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;