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.be.filters;
22 import com.google.gson.Gson;
23 import com.google.gson.GsonBuilder;
24 import java.io.IOException;
25 import java.nio.charset.StandardCharsets;
26 import java.util.Arrays;
27 import java.util.List;
28 import java.util.StringTokenizer;
29 import javax.annotation.Priority;
30 import javax.servlet.ServletContext;
31 import javax.servlet.http.HttpServletRequest;
32 import javax.ws.rs.container.ContainerRequestContext;
33 import javax.ws.rs.container.ContainerRequestFilter;
34 import javax.ws.rs.core.Context;
35 import javax.ws.rs.core.Response;
36 import javax.ws.rs.core.Response.ResponseBuilder;
37 import javax.ws.rs.core.Response.Status;
38 import org.apache.commons.codec.binary.Base64;
39 import org.glassfish.jersey.server.ContainerRequest;
40 import org.openecomp.sdc.be.config.Configuration;
41 import org.openecomp.sdc.be.config.ConfigurationManager;
42 import org.openecomp.sdc.be.dao.api.ActionStatus;
43 import org.openecomp.sdc.be.impl.ComponentsUtils;
44 import org.openecomp.sdc.be.impl.WebAppContextWrapper;
45 import org.openecomp.sdc.common.api.Constants;
46 import org.openecomp.sdc.common.log.enums.LogLevel;
47 import org.openecomp.sdc.common.log.enums.Severity;
48 import org.openecomp.sdc.common.log.wrappers.Logger;
49 import org.openecomp.sdc.common.log.wrappers.LoggerSdcAudit;
50 import org.openecomp.sdc.exception.ResponseFormat;
51 import org.springframework.web.context.WebApplicationContext;
54 public class BasicAuthenticationFilter implements ContainerRequestFilter {
56 private static final Logger log = Logger.getLogger(BasicAuthenticationFilter.class);
57 private static final String COMPONENT_UTILS_FAILED = "Authentication Filter Failed to get component utils.";
58 private static final ConfigurationManager configurationManager = ConfigurationManager.getConfigurationManager();
59 private static final Configuration.BasicAuthConfig basicAuthConf = configurationManager.getConfiguration().getBasicAuth();
60 private static LoggerSdcAudit audit = new LoggerSdcAudit(BasicAuthenticationFilter.class);
61 protected Gson gson = new GsonBuilder().setPrettyPrinting().create();
63 private HttpServletRequest sr;
64 private String realm = "ASDC";
67 public void filter(ContainerRequestContext requestContext) throws IOException {
68 audit.startLog(requestContext);
69 if (!basicAuthConf.isEnabled()) {
72 List<String> excludedUrls = Arrays.asList(basicAuthConf.getExcludedUrls().split(","));
73 if (excludedUrls.contains(((ContainerRequest) requestContext).getRequestUri().getPath())) {
76 String authHeader = requestContext.getHeaderString(Constants.AUTHORIZATION_HEADER);
77 if (authHeader != null) {
78 StringTokenizer st = new StringTokenizer(authHeader);
79 String failedToRetrieveAuthErrorMsg = "Authentication Filter Failed Couldn't retrieve authentication, no basic authentication.";
80 if (st.hasMoreTokens()) {
81 String basic = st.nextToken();
82 if ("Basic".equalsIgnoreCase(basic)) {
83 String credentials = new String(Base64.decodeBase64(st.nextToken()), StandardCharsets.UTF_8);
84 log.debug("Credentials: {}", credentials);
85 checkUserCredentials(requestContext, credentials);
87 log.error(failedToRetrieveAuthErrorMsg);
88 authInvalidHeaderError(requestContext);
91 log.error(failedToRetrieveAuthErrorMsg);
92 authInvalidHeaderError(requestContext);
95 log.error("Authentication Filter Failed no authorization header");
96 authRequiredError(requestContext);
100 private void checkUserCredentials(ContainerRequestContext requestContext, String credentials) {
101 int p = credentials.indexOf(':');
103 String userName = credentials.substring(0, p).trim();
104 String password = credentials.substring(p + 1).trim();
105 if (!userName.equals(basicAuthConf.getUserName()) || !password.equals(basicAuthConf.getUserPass())) {
106 log.error("Authentication Failed. Invalid userName or password");
107 authInvalidPasswordError(requestContext, userName);
109 authSuccessful(requestContext, userName);
111 log.error("Authentication Filter Failed Couldn't retrieve authentication, no basic authentication.");
112 authInvalidHeaderError(requestContext);
116 private void authSuccessful(ContainerRequestContext requestContext, String userName) {
117 ComponentsUtils componentUtils = getComponentsUtils();
118 if (componentUtils == null) {
119 abortWith(requestContext, COMPONENT_UTILS_FAILED, Response.status(Status.INTERNAL_SERVER_ERROR).build());
121 componentUtils.auditAuthEvent(requestContext.getUriInfo().getPath(), userName, AuthStatus.AUTH_SUCCESS.toString(), realm);
125 private void authInvalidPasswordError(ContainerRequestContext requestContext, String userName) {
126 ComponentsUtils componentUtils = getComponentsUtils();
127 if (componentUtils == null) {
128 abortWith(requestContext, COMPONENT_UTILS_FAILED, Response.status(Status.INTERNAL_SERVER_ERROR).build());
130 componentUtils.auditAuthEvent(requestContext.getUriInfo().getPath(), userName, AuthStatus.AUTH_FAILED_INVALID_PASSWORD.toString(), realm);
131 ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.AUTH_FAILED);
132 abortWith(requestContext, responseFormat.getFormattedMessage(), buildErrorResponse(responseFormat, false));
136 private void authInvalidHeaderError(ContainerRequestContext requestContext) {
137 ComponentsUtils componentUtils = getComponentsUtils();
138 if (componentUtils == null) {
139 abortWith(requestContext, COMPONENT_UTILS_FAILED, Response.status(Status.INTERNAL_SERVER_ERROR).build());
142 .auditAuthEvent(requestContext.getUriInfo().getPath(), "", AuthStatus.AUTH_FAILED_INVALID_AUTHENTICATION_HEADER.toString(), realm);
143 ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.AUTH_FAILED_INVALIDE_HEADER);
144 abortWith(requestContext, responseFormat.getFormattedMessage(), buildErrorResponse(responseFormat, false));
147 private void authRequiredError(ContainerRequestContext requestContext) {
148 ComponentsUtils componentUtils = getComponentsUtils();
149 if (componentUtils == null) {
150 abortWith(requestContext, COMPONENT_UTILS_FAILED, Response.status(Status.INTERNAL_SERVER_ERROR).build());
152 getComponentsUtils().auditAuthEvent(requestContext.getUriInfo().getPath(), "", AuthStatus.AUTH_REQUIRED.toString(), realm);
153 ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.AUTH_REQUIRED);
154 abortWith(requestContext, responseFormat.getFormattedMessage(), buildErrorResponse(responseFormat, true));
157 private ComponentsUtils getComponentsUtils() {
158 ServletContext context = sr.getSession().getServletContext();
159 WebAppContextWrapper webApplicationContextWrapper = (WebAppContextWrapper) context
160 .getAttribute(Constants.WEB_APPLICATION_CONTEXT_WRAPPER_ATTR);
161 WebApplicationContext webApplicationContext = webApplicationContextWrapper.getWebAppContext(context);
162 return webApplicationContext.getBean(ComponentsUtils.class);
165 protected Response buildErrorResponse(ResponseFormat requestErrorWrapper, boolean addWwwAuthenticationHeader) {
166 ResponseBuilder responseBuilder = Response.status(requestErrorWrapper.getStatus());
167 if (addWwwAuthenticationHeader) {
168 responseBuilder = responseBuilder.header("WWW-Authenticate", "Basic realm=\"" + realm + "\"");
170 return responseBuilder.entity(gson.toJson(requestErrorWrapper.getRequestError())).build();
173 private void abortWith(ContainerRequestContext requestContext, String message, Response response) {
174 audit.logEntry(sr.getRemoteAddr(), requestContext,
175 // response.getStatusInfo(),
176 LogLevel.ERROR, Severity.WARNING, message, null);
179 requestContext.abortWith(response);
182 public enum AuthStatus {
183 AUTH_REQUIRED, AUTH_FAILED_USER_NOT_FOUND, AUTH_FAILED_INVALID_PASSWORD, AUTH_FAILED_INVALID_AUTHENTICATION_HEADER, AUTH_SUCCESS