view flys-client/src/main/java/de/intevation/flys/client/server/filter/GGInAFilter.java @ 5818:a4ff4167be1e

Request feature info on all layers and show it as html if the server does not return valid gml. Non queryable layers produce an error message when the request fails. This is good enough
author Andre Heinecke <aheinecke@intevation.de>
date Wed, 24 Apr 2013 17:33:27 +0200
parents 8af500d62098
children
line wrap: on
line source
package de.intevation.flys.client.server.filter;

import de.intevation.flys.client.server.auth.Authentication;
import de.intevation.flys.client.server.auth.AuthenticationException;
import de.intevation.flys.client.server.auth.AuthenticationFactory;
import de.intevation.flys.client.server.auth.User;
import de.intevation.flys.client.server.features.Features;

import java.io.IOException;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Enumeration;

import javax.servlet.Filter;
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.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.log4j.Logger;


/** ServletFilter used for GGInA authentification and certain authorisation. */
public class GGInAFilter implements Filter {

    /** Private logger. */
    private static Logger logger = Logger.getLogger(GGInAFilter.class);

    private boolean deactivate = false;
    private String authmethod;
    private String redirecturl;
    private ServletContext sc;

    private static final String LOGIN_JSP     = "/login.jsp";
    private static final String LOGIN_SERVLET = "/flys/login";
    private static final String FLYS_CSS      = "/FLYS.css";


    /**
     * Initialize.
     *
     * Read FilterConfig parameter deactivate
     */
    @Override
    public void init(FilterConfig config)
    throws ServletException
    {
        String deactivate = config.getInitParameter("deactivate");
        this.sc = config.getServletContext();
        logger.debug("GGInAFilter context " + this.sc.getContextPath());
        this.authmethod = sc.getInitParameter("authentication");
        this.redirecturl = sc.getInitParameter("redirect-url");
        if (deactivate != null && deactivate.equalsIgnoreCase("true")) {
            this.deactivate = true;
        }

    }


    /**
     * Called when filter in chain invoked.
     * @param req request to servlet
     * @param resp response of servlet
     * @param chain the filter chain
     */
    @Override
    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain)
    throws IOException, ServletException
    {
        if (this.deactivate) {
            logger.debug("GGinAFilter is deactivated");
            chain.doFilter(req, resp);
            return;
        }

        HttpServletRequest sreq = (HttpServletRequest) req;

        String requesturi = sreq.getRequestURI();
        if (logger.isDebugEnabled()) {
            for (Enumeration e = req.getAttributeNames() ; e.hasMoreElements() ;) {
                logger.debug(e.nextElement());
            }
        }

        logger.debug("Request for: " + requesturi);

        // Allow access to localhost
        if (isLocalAddress(req)) {
            logger.debug("Request to localhost");
            chain.doFilter(req, resp);
            return;
        }

        // Allow access to login pages
        String path = this.sc.getContextPath();
        if (requesturi.equals(path + LOGIN_JSP)
                || requesturi.equals(path + LOGIN_SERVLET)
                || requesturi.equals(path + FLYS_CSS)) {
            logger.debug("Request for login " + requesturi);
            chain.doFilter(req, resp);
            return;
        }

        boolean redirect = false;

        HttpSession session = sreq.getSession();

        String uri = path + "/" + this.redirecturl;

        /* Redirect if uri is root or redirecturl */
        if (requesturi.equals(uri) || requesturi.equals(path + "/")) {
            redirect = true;
        }

        String queryString = sreq.getQueryString();

        if (queryString != null) {
            uri += "?" + queryString;
        }
        session.setAttribute("requesturi", uri);

        User user = (User)session.getAttribute("user");
        if (user == null) {
            logger.debug("No user in session: " + requesturi);
            this.handleResponse(resp, redirect);
            return;
        }
        if (user.hasExpired()) {
            // try to re-authenticate the user
            logger.debug("User ticket has expired: " + requesturi);
            String encoding = sreq.getCharacterEncoding();
            try {
                Authentication auth = this.auth(user, encoding);
                if (auth == null || !auth.isSuccess()) {
                    logger.debug("Re-athentication not successful");
                    this.handleResponse(resp, redirect);
                }
            }
            catch(AuthenticationException e) {
                logger.error("Failure during re-authentication", e);
                this.handleResponse(resp, redirect);
                return;
            }
        }

        chain.doFilter(req, resp);
        return;
    }

    private void redirect(ServletResponse resp) throws IOException {
        logger.debug("Redirect to login");
        ((HttpServletResponse) resp).sendRedirect(this.sc.getContextPath() +
            "/login.jsp");
    }

    private void sendNotAuthenticated(ServletResponse resp) throws IOException {
        logger.debug("Send not authenticated");
        ((HttpServletResponse)resp).sendError(HttpServletResponse.SC_FORBIDDEN, "User not authenticated");
    }

    private void handleResponse(ServletResponse resp, boolean redirect) throws IOException {
        if (redirect) {
            this.redirect(resp);
        }
        else {
            this.sendNotAuthenticated(resp);
        }
    }


    /**
     * Do nothing at destruction.
     */
    @Override
    public void destroy() {
    }

    private Authentication auth(User user, String encoding)
        throws AuthenticationException, IOException {
        Features features = (Features)sc.getAttribute(Features.CONTEXT_ATTRIBUTE);
        return AuthenticationFactory.getInstance(this.authmethod).auth(
                user.getName(), user.getPassword(), encoding, features);
    }

    /**
     * Returns true if the request is from our machine
     * @param req The ServletRequest
     * @return true if the request is from a loopback interface or from one of
     *  the interface addresses of the machine
     */
    private boolean isLocalAddress(ServletRequest req) {
        try {
            InetAddress addr = InetAddress.getByName(req.getRemoteAddr());
            return addr.isAnyLocalAddress() || addr.isLoopbackAddress();
        } catch (UnknownHostException e) {
            logger.error(e, e);
            return false;
        }
    }
}
// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :

http://dive4elements.wald.intevation.org