0cda5f8a275fbe75adc1310e66883e1397103cc4
[sdc.git] /
1 /*-
2  * ============LICENSE_START=======================================================
3  * SDC
4  * ================================================================================
5  * Copyright (C) 2021 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
10  * 
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  * 
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=========================================================
19  */
20
21 package org.openecomp.server.filters;
22
23 import com.fasterxml.jackson.databind.ObjectMapper;
24 import java.io.FileInputStream;
25 import java.io.InputStream;
26 import java.util.Arrays;
27 import java.util.List;
28 import java.util.Map;
29 import java.util.Objects;
30 import javax.servlet.Filter;
31 import javax.servlet.FilterChain;
32 import javax.servlet.FilterConfig;
33 import javax.servlet.ServletException;
34 import javax.servlet.ServletRequest;
35 import javax.servlet.ServletResponse;
36 import org.onap.sdc.tosca.services.YamlUtil;
37 import org.openecomp.sdc.be.config.Configuration.BasicAuthConfig;
38 import org.openecomp.sdc.logging.api.Logger;
39 import org.openecomp.sdc.logging.api.LoggerFactory;
40
41 import javax.servlet.http.HttpServletRequest;
42 import javax.servlet.http.HttpServletRequestWrapper;
43 import javax.servlet.http.HttpServletResponse;
44 import java.io.IOException;
45 import java.util.Base64;
46 import org.openecomp.sdcrests.item.rest.services.catalog.notification.EntryNotConfiguredException;
47
48 public class BasicAuthenticationFilter implements Filter {
49
50   private static final Logger log = LoggerFactory.getLogger(BasicAuthenticationFilter.class);
51   private static final String CONFIG_FILE_PROPERTY = "configuration.yaml";
52   private static final String CONFIG_SECTION = "basicAuth";
53
54   @Override
55   public void destroy() {
56     // TODO Auto-generated method stub
57
58   }
59
60   @Override
61   public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2)
62       throws IOException, ServletException {
63       String file = Objects.requireNonNull(System.getProperty(CONFIG_FILE_PROPERTY),
64         "Config file location must be specified via system property " + CONFIG_FILE_PROPERTY);
65       Object config = getAuthenticationConfiguration(file);
66       ObjectMapper mapper = new ObjectMapper();
67       BasicAuthConfig basicAuthConfig = mapper.convertValue(config, BasicAuthConfig.class);
68       HttpServletRequest httpRequest = (HttpServletRequest) arg0;
69       HttpServletRequestWrapper servletRequest = new HttpServletRequestWrapper(httpRequest);
70
71       // BasicAuth is disabled
72       if (!basicAuthConfig.isEnabled()) {
73          arg2.doFilter(servletRequest, arg1);
74          return;
75       }
76
77       List<String> excludedUrls = Arrays.asList(basicAuthConfig.getExcludedUrls().split(","));
78       if (excludedUrls.contains(httpRequest.getServletPath() + httpRequest.getPathInfo())) {
79         // this url is included in the excludeUrls list, no need for authentication
80         arg2.doFilter(servletRequest, arg1);
81         return;
82       }
83
84
85       // Get the basicAuth info from the header
86       String authorizationHeader = httpRequest.getHeader("Authorization");
87       if (authorizationHeader == null || authorizationHeader.isEmpty()) {
88         ((HttpServletResponse) arg1).setStatus(HttpServletResponse.SC_UNAUTHORIZED);
89         return;
90       }
91
92       String base64Credentials =
93           httpRequest.getHeader("Authorization").replace("Basic", "").trim();
94       if (verifyCredentials(basicAuthConfig, base64Credentials)) {
95           arg2.doFilter(servletRequest, arg1);
96       } else {
97           ((HttpServletResponse) arg1).setStatus(HttpServletResponse.SC_UNAUTHORIZED);
98       }
99   }
100
101   @Override
102   public void init(FilterConfig config) throws ServletException {
103   }
104
105   private static Object getAuthenticationConfiguration(String file) throws IOException {
106     InputStream fileInput = new FileInputStream(file);
107     YamlUtil yamlUtil = new YamlUtil();
108
109     Map<?, ?> configuration = Objects.requireNonNull(yamlUtil.yamlToMap(fileInput), "Configuration cannot be empty");
110     Object authenticationConfig = configuration.get(CONFIG_SECTION);
111     if (authenticationConfig == null) {
112       throw new EntryNotConfiguredException(CONFIG_SECTION + " section");
113     }
114     return authenticationConfig;
115   }
116
117   private boolean verifyCredentials (BasicAuthConfig basicAuthConfig, String credential) {
118     String decodedCredentials = new String(Base64.getDecoder().decode(credential));
119     int p = decodedCredentials.indexOf(':');
120     if (p != -1) {
121       String userName = decodedCredentials.substring(0, p).trim();
122       String password = decodedCredentials.substring(p + 1).trim();
123       if (!userName.equals(basicAuthConfig.getUserName()) || !password.equals(basicAuthConfig.getUserPass())) {
124         log.error("Authentication failed. Invalid user name or password");
125         return false;
126       }
127       return true;
128     } else {
129       log.error("Failed to decode credentials");
130       return false;
131     }
132   }
133 }