001/*
002 * (C) Copyright 2010 Nuxeo SAS (http://nuxeo.com/) and contributors.
003 *
004 * All rights reserved. This program and the accompanying materials
005 * are made available under the terms of the GNU Lesser General Public License
006 * (LGPL) version 2.1 which accompanies this distribution, and is available at
007 * http://www.gnu.org/licenses/lgpl.html
008 *
009 * This library is distributed in the hope that it will be useful,
010 * but WITHOUT ANY WARRANTY; without even the implied warranty of
011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012 * Lesser General Public License for more details.
013 *
014 * Contributors:
015 *     Nuxeo - initial API and implementation
016 */
017
018package org.nuxeo.ecm.platform.ui.web.auth.cas2;
019
020import java.io.IOException;
021import java.security.Principal;
022
023import javax.faces.context.FacesContext;
024import javax.servlet.ServletException;
025import javax.servlet.http.Cookie;
026import javax.servlet.http.HttpServletRequest;
027import javax.servlet.http.HttpServletResponse;
028
029import org.nuxeo.ecm.core.api.NuxeoException;
030import org.nuxeo.ecm.core.api.NuxeoPrincipal;
031import org.nuxeo.ecm.platform.ui.web.auth.NXAuthConstants;
032import org.nuxeo.ecm.platform.ui.web.auth.service.PluggableAuthenticationService;
033import org.nuxeo.ecm.platform.ui.web.rest.api.URLPolicyService;
034import org.nuxeo.ecm.platform.url.api.DocumentView;
035import org.nuxeo.ecm.platform.web.common.exceptionhandling.DefaultNuxeoExceptionHandler;
036import org.nuxeo.ecm.platform.web.common.exceptionhandling.ExceptionHelper;
037import org.nuxeo.runtime.api.Framework;
038
039import static org.nuxeo.ecm.platform.ui.web.auth.NXAuthConstants.SSO_INITIAL_URL_REQUEST_KEY;
040
041public class SecurityExceptionHandler extends DefaultNuxeoExceptionHandler {
042
043    public static final String CAS_REDIRECTION_URL = "/cas2.jsp";
044
045    public static final String COOKIE_NAME_LOGOUT_URL = "cookie.name.logout.url";
046
047    Cas2Authenticator cas2Authenticator;
048
049    public SecurityExceptionHandler() {
050    }
051
052    @Override
053    public void handleException(HttpServletRequest request, HttpServletResponse response, Throwable t)
054            throws IOException, ServletException {
055
056        if (response.containsHeader("Cache-Control")) {
057            response.setHeader("Cache-Control", "no-cache");
058        }
059
060        Throwable unwrappedException = unwrapException(t);
061
062        if (!ExceptionHelper.isSecurityError(unwrappedException)
063                && !response.containsHeader(SSO_INITIAL_URL_REQUEST_KEY)) {
064            super.handleException(request, response, t);
065            return;
066        }
067
068        Principal principal = request.getUserPrincipal();
069        NuxeoPrincipal nuxeoPrincipal = null;
070        if (principal instanceof NuxeoPrincipal) {
071            nuxeoPrincipal = (NuxeoPrincipal) principal;
072            // redirect to login than to requested page
073            if (nuxeoPrincipal.isAnonymous()) {
074                response.resetBuffer();
075
076                String urlToReach = getURLToReach(request);
077                Cookie cookieUrlToReach = new Cookie(NXAuthConstants.SSO_INITIAL_URL_REQUEST_KEY, urlToReach);
078                cookieUrlToReach.setPath("/");
079                cookieUrlToReach.setMaxAge(60);
080                response.addCookie(cookieUrlToReach);
081
082                if (!response.isCommitted()) {
083                    request.getRequestDispatcher(CAS_REDIRECTION_URL).forward(request, response);
084                }
085                FacesContext.getCurrentInstance().responseComplete();
086                return;
087            }
088        }
089        // go back to default handler
090        super.handleException(request, response, t);
091    }
092
093    protected Cas2Authenticator getCasAuthenticator() {
094        if (cas2Authenticator != null) {
095            return cas2Authenticator;
096        }
097
098        PluggableAuthenticationService service = (PluggableAuthenticationService) Framework.getRuntime().getComponent(
099                PluggableAuthenticationService.NAME);
100        if (service == null) {
101            throw new NuxeoException("Can't initialize Nuxeo Pluggable Authentication Service");
102        }
103
104        cas2Authenticator = (Cas2Authenticator) service.getPlugin("CAS2_AUTH");
105
106        if (cas2Authenticator == null) {
107            throw new NuxeoException("Can't get CAS authenticator");
108        }
109        return cas2Authenticator;
110    }
111
112    protected String getURLToReach(HttpServletRequest request) {
113        DocumentView docView = (DocumentView) request.getAttribute(URLPolicyService.DOCUMENT_VIEW_REQUEST_KEY);
114
115        if (docView != null) {
116            String urlToReach = getURLPolicyService().getUrlFromDocumentView(docView, "");
117
118            if (urlToReach != null) {
119                return urlToReach;
120            }
121        }
122        return request.getRequestURL().toString() + "?" + request.getQueryString();
123    }
124
125    protected URLPolicyService getURLPolicyService() {
126        return Framework.getService(URLPolicyService.class);
127    }
128
129}