/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.apache.atlas.web.filters;

import org.apache.atlas.ApplicationProperties;
import org.apache.atlas.AtlasConfiguration;
import org.apache.atlas.security.SecurityProperties;
import org.apache.atlas.utils.AuthenticationUtil;
import org.apache.atlas.web.security.AtlasAuthenticationProvider;
import org.apache.atlas.web.util.Servlets;
import org.apache.commons.collections.iterators.IteratorEnumeration;
import org.apache.commons.configuration.Configuration;
import org.apache.commons.configuration.ConfigurationConverter;
import org.apache.commons.lang.StringUtils;
import org.apache.hadoop.security.SecurityUtil;
import org.apache.hadoop.security.authentication.client.AuthenticatedURL;
import org.apache.hadoop.security.authentication.client.AuthenticationException;
import org.apache.hadoop.security.authentication.client.KerberosAuthenticator;
import org.apache.hadoop.security.authentication.server.AuthenticationFilter;
import org.apache.hadoop.security.authentication.server.AuthenticationHandler;
import org.apache.hadoop.security.authentication.server.AuthenticationToken;
import org.apache.hadoop.security.authentication.server.KerberosAuthenticationHandler;
import org.apache.hadoop.security.authentication.util.Signer;
import org.apache.hadoop.security.authentication.util.SignerException;
import org.apache.hadoop.security.authentication.util.SignerSecretProvider;
import org.apache.hadoop.security.authorize.ProxyUsers;
import org.apache.log4j.NDC;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.authentication.AbstractAuthenticationToken;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.web.authentication.WebAuthenticationDetails;
import org.springframework.stereotype.Component;
import org.apache.hadoop.security.UserGroupInformation;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpServletResponse;
import javax.ws.rs.core.Response;
import java.io.IOException;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.security.Principal;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.hadoop.security.authorize.AuthorizationException;
import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler;

import static org.apache.atlas.web.filters.RestUtil.constructForwardableURL;


/**
 * This enforces authentication as part of the filter before processing the request.
 * todo: Subclass of {@link AuthenticationFilter}.
 */

@Component
public class AtlasAuthenticationFilter extends AuthenticationFilter {
    private static final Logger LOG = LoggerFactory.getLogger(AtlasAuthenticationFilter.class);

    private   static final String         CONFIG_KERBEROS_TOKEN_VALIDITY = "atlas.authentication.method.kerberos.token.validity";
    private   static final String         CONFIG_PROXY_USERS    = "atlas.proxyusers";
    private   static final String         PREFIX                = "atlas.authentication.method";
    private   static final String[]       DEFAULT_PROXY_USERS   = new String[] { "knox" };
    private   static final String         CONF_PROXYUSER_PREFIX = "atlas.proxyuser";
    protected static final ServletContext nullContext           = new NullServletContext();
    private   static final String         ORIGINAL_URL_QUERY_PARAM = "originalUrl";

    private Signer               signer;
    private SignerSecretProvider secretProvider;
    private final boolean        isKerberos = AuthenticationUtil.isKerberosAuthenticationEnabled();
    private boolean              isInitializedByTomcat;
    private Set<Pattern>         browserUserAgents;
    private boolean              supportKeyTabBrowserLogin = false;
    private Configuration        configuration;
    private Properties           headerProperties;
    private Set<String>          atlasProxyUsers = new HashSet<>();
    private HttpServlet          optionsServlet;
    private boolean              supportTrustedProxy = false;
    private int                  sessionTimeout;

    private SecurityContextLogoutHandler logoutHandler;

    public AtlasAuthenticationFilter() {
        LOG.info("==> AtlasAuthenticationFilter()");

        try {
            init(null);
        } catch (ServletException e) {
            LOG.error("Error while initializing AtlasAuthenticationFilter", e);
        }

        LOG.info("<== AtlasAuthenticationFilter()");
    }

    /**
     * Initialize the filter.
     *
     * @param filterConfig filter configuration.
     * @throws ServletException thrown if the filter could not be initialized.
     */
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        LOG.info("==> AtlasAuthenticationFilter.init");

        final FilterConfig        globalConf = filterConfig;
        final Map<String, String> params     = new HashMap<>();
        try {
            configuration = ApplicationProperties.get();
        } catch (Exception e) {
            throw new ServletException(e);
        }

        if (configuration != null) {
            headerProperties = ConfigurationConverter.getProperties(configuration.subset("atlas.headers"));
        }

        String tokenValidityStr = null;

        if(configuration != null) {
            tokenValidityStr = configuration.getString(CONFIG_KERBEROS_TOKEN_VALIDITY);
        }

        if (StringUtils.isNotBlank(tokenValidityStr)) {
            try {
                Long tokenValidity = Long.parseLong(tokenValidityStr);

                if (tokenValidity > 0) {
                    params.put(AuthenticationFilter.AUTH_TOKEN_VALIDITY, tokenValidity.toString());
                } else {
                    throw new ServletException(tokenValidity + ": invalid value for property '" + CONFIG_KERBEROS_TOKEN_VALIDITY + "'. Must be a positive integer");
                }
            } catch (NumberFormatException e) {
                throw new ServletException(tokenValidityStr + ": invalid value for property '" + CONFIG_KERBEROS_TOKEN_VALIDITY + "'. Must be a positive integer", e);
            }
        }

        FilterConfig filterConfig1 = new FilterConfig() {
            @Override
            public ServletContext getServletContext() {
                if (globalConf != null) {
                    return globalConf.getServletContext();
                } else {
                    return nullContext;
                }
            }

            @SuppressWarnings("unchecked")
            @Override
            public Enumeration<String> getInitParameterNames() {
                return new IteratorEnumeration(params.keySet().iterator());
            }

            @Override
            public String getInitParameter(String param) {
                return params.get(param);
            }

            @Override
            public String getFilterName() {
                return "AtlasAuthenticationFilter";
            }
        };

        super.init(filterConfig1);

        ProxyUsers.refreshSuperUserGroupsConfiguration(getProxyuserConfiguration(), CONF_PROXYUSER_PREFIX);

        optionsServlet = new HttpServlet() {
        };
        optionsServlet.init();
        logoutHandler = new SecurityContextLogoutHandler();
        LOG.info("<== AtlasAuthenticationFilter.init(filterConfig={})", filterConfig);

    }


    @Override
    public void initializeSecretProvider(FilterConfig filterConfig) throws ServletException {
        LOG.info("==> AtlasAuthenticationFilter.initializeSecretProvider");

        secretProvider = (SignerSecretProvider) filterConfig.getServletContext().getAttribute(AuthenticationFilter.SIGNER_SECRET_PROVIDER_ATTRIBUTE);

        if (secretProvider == null) {
            // As tomcat cannot specify the provider object in the configuration.
            // It'll go into this path
            String configPrefix = filterConfig.getInitParameter(CONFIG_PREFIX);

            configPrefix = (configPrefix != null) ? configPrefix + "." : "";

            try {
                secretProvider = AuthenticationFilter.constructSecretProvider(filterConfig.getServletContext(), super.getConfiguration(configPrefix, filterConfig), false);

                this.isInitializedByTomcat = true;
            } catch (Exception ex) {
                throw new ServletException(ex);
            }
        }

        signer = new Signer(secretProvider);

        LOG.info("<== AtlasAuthenticationFilter.initializeSecretProvider(filterConfig={})", filterConfig);
    }

    @Override
    protected Properties getConfiguration(String configPrefix, FilterConfig filterConfig) throws ServletException {
        LOG.info("==> AtlasAuthenticationFilter.getConfiguration()");

        try {
            configuration = ApplicationProperties.get();
        } catch (Exception e) {
            throw new ServletException(e);
        }

        Properties ret = new Properties();

        String kerberosAuthEnabled = configuration != null ? configuration.getString("atlas.authentication.method.kerberos") : null;

        final String authMethod;

        if (kerberosAuthEnabled == null || kerberosAuthEnabled.equalsIgnoreCase("false")) {
            LOG.info("No authentication method configured.  Defaulting to simple authentication");

            authMethod = "simple";
        } else if (kerberosAuthEnabled.equalsIgnoreCase("true")) {
            authMethod = "kerberos";

            if (configuration.getString("atlas.authentication.method.kerberos.name.rules") != null) {
                ret.put("kerberos.name.rules", configuration.getString("atlas.authentication.method.kerberos.name.rules"));
            }

            if (configuration.getString("atlas.authentication.method.kerberos.keytab") != null) {
                ret.put("kerberos.keytab", configuration.getString("atlas.authentication.method.kerberos.keytab"));
            }

            if (configuration.getString("atlas.authentication.method.kerberos.principal") != null) {
                ret.put("kerberos.principal", configuration.getString("atlas.authentication.method.kerberos.principal"));
            }
        } else {
            authMethod = "";
        }

        ret.put(AuthenticationFilter.AUTH_TYPE, authMethod);
        ret.put(AuthenticationFilter.COOKIE_PATH, "/");

        // add any config passed in as init parameters
        Enumeration<String> enumeration = filterConfig.getInitParameterNames();
        while (enumeration.hasMoreElements()) {
            String name = enumeration.nextElement();

            ret.put(name, filterConfig.getInitParameter(name));
        }

        //Resolve _HOST into bind address
        String bindAddress = configuration.getString(SecurityProperties.BIND_ADDRESS);
        if (bindAddress == null) {
            LOG.info("No host name configured. Defaulting to local host name.");

            try {
                bindAddress = InetAddress.getLocalHost().getHostName();
            } catch (UnknownHostException e) {
                throw new ServletException("Unable to obtain host name", e);
            }
        }

        String principal = ret.getProperty(KerberosAuthenticationHandler.PRINCIPAL);
        if (principal != null) {
            try {
                principal = SecurityUtil.getServerPrincipal(principal, bindAddress);
            } catch (IOException ex) {
                throw new RuntimeException("Could not resolve Kerberos principal name: " + ex.toString(), ex);
            }

            ret.put(KerberosAuthenticationHandler.PRINCIPAL, principal);
        }


        LOG.debug(" AuthenticationFilterConfig: {}", ret);

        sessionTimeout = AtlasConfiguration.SESSION_TIMEOUT_SECS.getInt();
        if(sessionTimeout < 30){
            LOG.warn("AtlasAuthenticationFilter:: sessionTimeout is set low");
        }
        supportKeyTabBrowserLogin = configuration.getBoolean("atlas.authentication.method.kerberos.support.keytab.browser.login", false);
        supportTrustedProxy = configuration.getBoolean("atlas.authentication.method.trustedproxy", true);
        String agents = configuration.getString(AtlasCSRFPreventionFilter.BROWSER_USER_AGENT_PARAM, AtlasCSRFPreventionFilter.BROWSER_USER_AGENTS_DEFAULT);

        if (agents == null) {
            agents = AtlasCSRFPreventionFilter.BROWSER_USER_AGENTS_DEFAULT;
        }

        String[] proxyUsers = configuration.getStringArray(CONFIG_PROXY_USERS);

        if (proxyUsers == null || proxyUsers.length == 0) {
            proxyUsers = DEFAULT_PROXY_USERS;
        }

        atlasProxyUsers = new HashSet<>(Arrays.asList(proxyUsers));

        parseBrowserUserAgents(agents);

        LOG.info("<== AtlasAuthenticationFilter.getConfiguration(configPrefix={}, filterConfig={}): {}", configPrefix, filterConfig, ret);

        return ret;
    }

    @Override
    public void doFilter(final ServletRequest request, final ServletResponse response, final FilterChain filterChain) throws IOException, ServletException {
        final HttpServletRequest httpRequest = (HttpServletRequest) request;

        try {
            Authentication              existingAuth    = SecurityContextHolder.getContext().getAuthentication();
            HttpServletResponse         httpResponse    = (HttpServletResponse) response;
            AtlasResponseRequestWrapper responseWrapper = new AtlasResponseRequestWrapper(httpResponse);
            String action = httpRequest.getParameter("action");
            String doAsUser = request.getParameter("doAs");

            HeadersUtil.setHeaderMapAttributes(responseWrapper, HeadersUtil.X_FRAME_OPTIONS_KEY);
            HeadersUtil.setHeaderMapAttributes(responseWrapper, HeadersUtil.X_CONTENT_TYPE_OPTIONS_KEY);
            HeadersUtil.setHeaderMapAttributes(responseWrapper, HeadersUtil.X_XSS_PROTECTION_KEY);
            HeadersUtil.setHeaderMapAttributes(responseWrapper, HeadersUtil.STRICT_TRANSPORT_SEC_KEY);

            if (headerProperties != null) {
                for (String headerKey : headerProperties.stringPropertyNames()) {
                    responseWrapper.setHeader(headerKey, headerProperties.getProperty(headerKey));
                }
            }

            if (supportTrustedProxy && StringUtils.isNotEmpty(doAsUser) && StringUtils.equals(action, RestUtil.TIMEOUT_ACTION)) {
                if (existingAuth != null) {
                    logoutHandler.logout(httpRequest, httpResponse, existingAuth);
                }
                redirectTimeoutReqeust(httpRequest, httpResponse);
                return;
            }

            if (existingAuth == null) {
                String authHeader = httpRequest.getHeader("Authorization");

                if (authHeader != null && authHeader.startsWith("Basic")) {
                    filterChain.doFilter(request, response);
                } else if (isKerberos) {
                    doKerberosAuth(request, response, filterChain);
                } else {
                    filterChain.doFilter(request, response);
                }
            } else {
                filterChain.doFilter(request, response);
            }
        } catch (NullPointerException e) {
            LOG.error("Exception in AtlasAuthenticationFilter ", e);
            //PseudoAuthenticationHandler.getUserName() from hadoop-auth throws NPE if user name is not specified
            ((HttpServletResponse) response).sendError(Response.Status.BAD_REQUEST.getStatusCode(),
                    "Authentication is enabled and user is not specified. Specify user.name parameter");
        }
    }

    private void redirectTimeoutReqeust(HttpServletRequest httpRequest, HttpServletResponse httpResponse) throws IOException{
        String logoutUrl = httpRequest.getRequestURL().toString();

        logoutUrl =  StringUtils.replace(logoutUrl, httpRequest.getRequestURI(), RestUtil.LOGOUT_URL);
        if (LOG.isDebugEnabled()) {
            LOG.debug("logoutUrl value is " + logoutUrl);
        }
        String xForwardedURL = constructForwardableURL(httpRequest);


        if (LOG.isDebugEnabled()) {
            LOG.debug("xForwardedURL = " + xForwardedURL);
        }
        String redirectUrl = RestUtil.constructRedirectURL(httpRequest, logoutUrl, xForwardedURL, ORIGINAL_URL_QUERY_PARAM);

        if (LOG.isDebugEnabled()) {
            LOG.debug("Redirect URL = " + redirectUrl);
            LOG.debug("session id = " + httpRequest.getRequestedSessionId());
        }

        httpResponse.sendRedirect(redirectUrl);
    }


    /**
     * This method is copied from hadoop auth lib, code added for error handling and fallback to other auth methods
     *
     * If the request has a valid authentication token it allows the request to continue to the target resource,
     * otherwise it triggers an authentication sequence using the configured {@link AuthenticationHandler}.
     *
     * @param request     the request object.
     * @param response    the response object.
     * @param filterChain the filter chain object.
     *
     * @throws IOException      thrown if an IO error occurred.
     * @throws ServletException thrown if a processing error occurred.
     */
    private void doKerberosAuth(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException {
        KerberosFilterChainWrapper filterChainWrapper   = new KerberosFilterChainWrapper(request, response, filterChain);
        boolean                    unauthorizedResponse = true;
        int                        errCode              = HttpServletResponse.SC_UNAUTHORIZED;
        AuthenticationException    authenticationEx     = null;
        HttpServletRequest         httpRequest          = (HttpServletRequest) request;
        HttpServletResponse        httpResponse         = (HttpServletResponse) response;
        boolean                    isHttps              = "https".equals(httpRequest.getScheme());
        AuthenticationHandler      authHandler          = getAuthenticationHandler();
        String doAsUser = supportTrustedProxy ? Servlets.getDoAsUser(httpRequest) : null;

        try {
            boolean             newToken = false;
            AuthenticationToken token;

            try {
                token = getToken(httpRequest);
            } catch (AuthenticationException ex) {
                LOG.warn("AuthenticationToken ignored: {}", ex);
                // will be sent back in a 401 unless filter authenticates
                authenticationEx = ex;
                token            = null;
            }

            if (authHandler.managementOperation(token, httpRequest, httpResponse)) {
                if (token == null) {
                    if (LOG.isDebugEnabled()) {
                        LOG.debug("Request [{}] triggering authentication", getRequestURL(httpRequest));
                    }

                    token = authHandler.authenticate(httpRequest, httpResponse);

                    if (token != null && token.getExpires() != 0 && token != AuthenticationToken.ANONYMOUS) {
                        token.setExpires(System.currentTimeMillis() + getValidity() * 1000);
                    }

                    newToken = true;
                }

                if (token != null) {
                    if (LOG.isDebugEnabled()) {
                        LOG.debug("Request [{}] user [{}] authenticated", getRequestURL(httpRequest), token.getUserName());
                    }

                    unauthorizedResponse = false;

                    final AuthenticationToken authToken = token;

                    httpRequest = new HttpServletRequestWrapper(httpRequest) {
                        @Override
                        public String getAuthType() {
                            return authToken.getType();
                        }

                        @Override
                        public String getRemoteUser() {
                            return authToken.getUserName();
                        }

                        @Override
                        public Principal getUserPrincipal() {
                            return (authToken != AuthenticationToken.ANONYMOUS) ? authToken : null;
                        }
                    };

                    // Create the proxy user if doAsUser exists

                    if (supportTrustedProxy && doAsUser != null && !doAsUser.equals(httpRequest.getRemoteUser())) {
                        LOG.debug("doAsUser is {}", doAsUser);

                        UserGroupInformation requestUgi = (token != null) ? UserGroupInformation.createRemoteUser(token.getUserName()) : null;

                        if (requestUgi != null) {
                            requestUgi = UserGroupInformation.createProxyUser(doAsUser, requestUgi);

                            try {
                                ProxyUsers.authorize(requestUgi, request.getRemoteAddr());
                                request.setAttribute("proxyUser", doAsUser);
                            } catch (AuthorizationException ex) {
                                LOG.warn("Proxy user AuthorizationException", ex);

                                httpResponse.setStatus(HttpServletResponse.SC_FORBIDDEN);
                                filterChain.doFilter(request, response);

                                return;

                            }
                        }
                    } else if(StringUtils.isNotBlank(httpRequest.getRemoteUser()) && atlasProxyUsers.contains(httpRequest.getRemoteUser())){
                        LOG.info("Ignoring kerberos login from proxy user "+ httpRequest.getRemoteUser());

                        httpResponse.setHeader(KerberosAuthenticator.WWW_AUTHENTICATE, "");
                        httpResponse.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
                        filterChain.doFilter(request, response);

                        return;
                    }

                    if (newToken && !token.isExpired() && token != AuthenticationToken.ANONYMOUS) {
                        String signedToken = signer.sign(token.toString());

                        createAtlasAuthCookie(httpResponse, signedToken, getCookieDomain(), getCookiePath(), token.getExpires(), isHttps);
                    }

                    filterChainWrapper.doFilter(httpRequest, httpResponse);
                }
            } else {
                unauthorizedResponse = false;
            }
        } catch (AuthenticationException ex) {
            LOG.warn("Authentication exception: {}", ex.getMessage(), ex);

            // exception from the filter itself is fatal
            errCode          = HttpServletResponse.SC_FORBIDDEN;
            authenticationEx = ex;
        }

        if (unauthorizedResponse) {
            if (!httpResponse.isCommitted()) {
                createAtlasAuthCookie(httpResponse, "", getCookieDomain(), getCookiePath(), 0, isHttps);

                // If response code is 401. Then WWW-Authenticate Header should be
                // present.. reset to 403 if not found..
                if (errCode == HttpServletResponse.SC_UNAUTHORIZED && !httpResponse.containsHeader(KerberosAuthenticator.WWW_AUTHENTICATE)) {
                    errCode = HttpServletResponse.SC_FORBIDDEN;
                }

                boolean isKerberosOnBrowser = supportKeyTabBrowserLogin || doAsUser != null;

                if (authenticationEx == null) { // added this code for atlas error handling and fallback
                    if (!isKerberosOnBrowser && isBrowser(httpRequest.getHeader("User-Agent"))) {
                        filterChain.doFilter(request, response);
                    } else {
                        boolean            chk         = true;
                        Collection<String> headerNames = httpResponse.getHeaderNames();

                        for (String headerName : headerNames) {
                            String value = httpResponse.getHeader(headerName);

                            if (headerName.equalsIgnoreCase("Set-Cookie") && value.startsWith("ATLASSESSIONID")) {
                                chk = false;
                                break;
                            }
                        }

                        String authHeader = httpRequest.getHeader("Authorization");

                        if (authHeader == null && chk) {
                            filterChain.doFilter(request, response);
                        } else if (authHeader != null && authHeader.startsWith("Basic")) {
                            filterChain.doFilter(request, response);
                        }
                    }
                } else {
                    httpResponse.sendError(errCode, authenticationEx.getMessage());
                }
            }
        }
    }


    @Override
    public void destroy() {

        if ((this.secretProvider != null) && (this.isInitializedByTomcat)) {
            this.secretProvider.destroy();
            this.secretProvider = null;
        }
        optionsServlet.destroy();
        super.destroy();
    }


    private static String readUserFromCookie(HttpServletResponse response1) {
        String  userName    = null;
        boolean isCookieSet = response1.containsHeader("Set-Cookie");

        if (isCookieSet) {
            Collection<String> authUserName = response1.getHeaders("Set-Cookie");

            if (authUserName != null) {
                for (String cookie : authUserName) {
                    if (!StringUtils.isEmpty(cookie)) {
                        if (cookie.toLowerCase().startsWith(AuthenticatedURL.AUTH_COOKIE.toLowerCase()) && cookie.contains("u=")) {
                            String[] split = cookie.split(";");

                            if (split != null) {
                                for (String s : split) {
                                    if (!StringUtils.isEmpty(s) && s.toLowerCase().startsWith(AuthenticatedURL.AUTH_COOKIE.toLowerCase())) {
                                        int ustr = s.indexOf("u=");

                                        if (ustr != -1) {
                                            int andStr = s.indexOf("&", ustr);

                                            if (andStr != -1) {
                                                try {
                                                    userName = s.substring(ustr + 2, andStr);
                                                    break;
                                                } catch (Exception e) {
                                                    userName = null;
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }

        return userName;
    }

    private void createAtlasAuthCookie(HttpServletResponse resp, String token, String domain, String path, long expires, boolean isSecure) {
        StringBuilder sb = (new StringBuilder(AuthenticatedURL.AUTH_COOKIE)).append("=");

        if (token != null && token.length() > 0) {
            sb.append("\"").append(token).append("\"");
        }

        sb.append("; Version=1");

        if (path != null) {
            sb.append("; Path=").append(path);
        }

        if (domain != null) {
            sb.append("; Domain=").append(domain);
        }

        if (expires >= 0L) {
            SimpleDateFormat df = new SimpleDateFormat("EEE, dd-MMM-yyyy HH:mm:ss zzz");
            df.setTimeZone(TimeZone.getTimeZone("GMT"));
            sb.append("; Expires=").append(df.format(new Date(expires)));
        }

        if (isSecure) {
            sb.append("; Secure");
        }

        sb.append("; HttpOnly");
        resp.addHeader("Set-Cookie", sb.toString());
    }

    @Override
    protected AuthenticationToken getToken(HttpServletRequest request)
            throws IOException, AuthenticationException {
        AuthenticationToken token = null;
        String tokenStr = null;
        Cookie[] cookies = request.getCookies();
        if (cookies != null) {
            for (Cookie cookie : cookies) {
                if (cookie.getName().equals(AuthenticatedURL.AUTH_COOKIE)) {
                    tokenStr = cookie.getValue();
                    try {
                        tokenStr = this.signer.verifyAndExtract(tokenStr);
                    } catch (SignerException ex) {
                        throw new AuthenticationException(ex);
                    }
                }
            }
        }

        if (tokenStr != null) {
            token = AuthenticationToken.parse(tokenStr);
            if (token != null) {
                AuthenticationHandler authHandler = getAuthenticationHandler();
                if (!token.getType().equals(authHandler.getType())) {
                    throw new AuthenticationException("Invalid AuthenticationToken type");
                }
                if (token.isExpired()) {
                    throw new AuthenticationException("AuthenticationToken expired");
                }
            }
        }
        return token;
    }

    void parseBrowserUserAgents(String userAgents) {
        String[] agentsArray = userAgents.split(",");
        browserUserAgents = new HashSet<>();
        for (String patternString : agentsArray) {
            browserUserAgents.add(Pattern.compile(patternString));
        }
    }

    boolean isBrowser(String userAgent) {
        if (userAgent != null) {
            for (Pattern pattern : browserUserAgents) {
                Matcher matcher = pattern.matcher(userAgent);

                if (matcher.matches()) {
                    return true;
                }
            }
        }

        return false;
    }


    private class KerberosFilterChainWrapper implements FilterChain {
        private final ServletRequest  request;
        private final ServletResponse response;
        private final FilterChain     filterChain;

        KerberosFilterChainWrapper(ServletRequest request, ServletResponse response, FilterChain filterChain) {
            this.request     = request;
            this.response    = response;
            this.filterChain = filterChain;
        }

        @Override
        public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse) throws IOException, ServletException {
            final HttpServletRequest  httpRequest  = (HttpServletRequest) servletRequest;
            final HttpServletResponse httpResponse = (HttpServletResponse) servletResponse;
            final Authentication      existingAuth = SecurityContextHolder.getContext().getAuthentication();
            String                    loggedInUser = readUserFromCookie(httpResponse);
            String                    userName     = loggedInUser;

            if (!StringUtils.isEmpty((String) httpRequest.getAttribute("proxyUser"))) {
                userName = (String) httpRequest.getAttribute("proxyUser");
            } else if (StringUtils.isEmpty(userName) && !StringUtils.isEmpty(httpRequest.getRemoteUser())) {
                userName = httpRequest.getRemoteUser();
            }

            if ((existingAuth == null || !existingAuth.isAuthenticated()) && !StringUtils.isEmpty(userName)) {
                final List<GrantedAuthority>   grantedAuths        = AtlasAuthenticationProvider.getAuthoritiesFromUGI(userName);
                final UserDetails              principal           = new User(userName, "", grantedAuths);
                final Authentication           finalAuthentication = new UsernamePasswordAuthenticationToken(principal, "", grantedAuths);
                final WebAuthenticationDetails webDetails          = new WebAuthenticationDetails(httpRequest);

                ((AbstractAuthenticationToken) finalAuthentication).setDetails(webDetails);

                SecurityContextHolder.getContext().setAuthentication(finalAuthentication);
                httpRequest.getSession().setMaxInactiveInterval(sessionTimeout);
                request.setAttribute("atlas.http.authentication.type", true);

                if (!StringUtils.equals(loggedInUser, userName)) {
                    LOG.info("Logged into Atlas as = {}, by proxyUser = {}", userName, loggedInUser);
                } else {
                    LOG.info("Logged into Atlas as = {}", userName);
                }
            }

            // OPTIONS method is sent from quick start jersey atlas client
            if (httpRequest.getMethod().equals("OPTIONS")) {
                optionsServlet.service(request, response);
            } else {
                try {
                    String requestUser = httpRequest.getRemoteUser();

                    NDC.push(requestUser + ":" + httpRequest.getMethod() + httpRequest.getRequestURI());

                    LOG.info("Request from authenticated user: {}, URL={}", requestUser, Servlets.getRequestURI(httpRequest));

                    filterChain.doFilter(servletRequest, servletResponse);
                } finally {
                    NDC.pop();
                }
            }
        }
    }

    private org.apache.hadoop.conf.Configuration getProxyuserConfiguration() {
        org.apache.hadoop.conf.Configuration ret  = new org.apache.hadoop.conf.Configuration(false);

        if(configuration!=null) {
            Properties props = ConfigurationConverter.getProperties(configuration.subset(CONF_PROXYUSER_PREFIX));

            for (String key : props.stringPropertyNames()) {
                ret.set(CONF_PROXYUSER_PREFIX + "." + key, props.getProperty(key));
            }
        }

        return ret;
    }
}
