001/*
002 * (C) Copyright 2010 Nuxeo SA (http://nuxeo.com/) and others.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 *
016 * Contributors:
017 *     Nuxeo - initial API and implementation
018 */
019
020package org.nuxeo.ecm.platform.ui.web.auth.cas2;
021
022import java.io.IOException;
023import java.security.Principal;
024
025import javax.faces.context.FacesContext;
026import javax.servlet.ServletException;
027import javax.servlet.http.Cookie;
028import javax.servlet.http.HttpServletRequest;
029import javax.servlet.http.HttpServletResponse;
030
031import org.nuxeo.ecm.core.api.NuxeoException;
032import org.nuxeo.ecm.core.api.NuxeoPrincipal;
033import org.nuxeo.ecm.platform.ui.web.auth.NXAuthConstants;
034import org.nuxeo.ecm.platform.ui.web.auth.service.PluggableAuthenticationService;
035import org.nuxeo.ecm.platform.ui.web.rest.api.URLPolicyService;
036import org.nuxeo.ecm.platform.url.api.DocumentView;
037import org.nuxeo.ecm.platform.web.common.exceptionhandling.DefaultNuxeoExceptionHandler;
038import org.nuxeo.ecm.platform.web.common.exceptionhandling.ExceptionHelper;
039import org.nuxeo.runtime.api.Framework;
040
041import static org.nuxeo.ecm.platform.ui.web.auth.NXAuthConstants.SSO_INITIAL_URL_REQUEST_KEY;
042
043public class SecurityExceptionHandler extends DefaultNuxeoExceptionHandler {
044
045    public static final String CAS_REDIRECTION_URL = "/cas2.jsp";
046
047    public static final String COOKIE_NAME_LOGOUT_URL = "cookie.name.logout.url";
048
049    Cas2Authenticator cas2Authenticator;
050
051    public SecurityExceptionHandler() {
052    }
053
054    @Override
055    public void handleException(HttpServletRequest request, HttpServletResponse response, Throwable t)
056            throws IOException, ServletException {
057
058        if (response.containsHeader("Cache-Control")) {
059            response.setHeader("Cache-Control", "no-cache");
060        }
061
062        Throwable unwrappedException = unwrapException(t);
063
064        if (!ExceptionHelper.isSecurityError(unwrappedException)
065                && !response.containsHeader(SSO_INITIAL_URL_REQUEST_KEY)) {
066            super.handleException(request, response, t);
067            return;
068        }
069
070        Principal principal = request.getUserPrincipal();
071        NuxeoPrincipal nuxeoPrincipal = null;
072        if (principal instanceof NuxeoPrincipal) {
073            nuxeoPrincipal = (NuxeoPrincipal) principal;
074            // redirect to login than to requested page
075            if (nuxeoPrincipal.isAnonymous()) {
076                response.resetBuffer();
077
078                String urlToReach = getURLToReach(request);
079                Cookie cookieUrlToReach = new Cookie(NXAuthConstants.SSO_INITIAL_URL_REQUEST_KEY, urlToReach);
080                cookieUrlToReach.setPath("/");
081                cookieUrlToReach.setMaxAge(60);
082                response.addCookie(cookieUrlToReach);
083
084                if (!response.isCommitted()) {
085                    request.getRequestDispatcher(CAS_REDIRECTION_URL).forward(request, response);
086                }
087                FacesContext.getCurrentInstance().responseComplete();
088                return;
089            }
090        }
091        // go back to default handler
092        super.handleException(request, response, t);
093    }
094
095    protected Cas2Authenticator getCasAuthenticator() {
096        if (cas2Authenticator != null) {
097            return cas2Authenticator;
098        }
099
100        PluggableAuthenticationService service = (PluggableAuthenticationService) Framework.getRuntime().getComponent(
101                PluggableAuthenticationService.NAME);
102        if (service == null) {
103            throw new NuxeoException("Can't initialize Nuxeo Pluggable Authentication Service");
104        }
105
106        cas2Authenticator = (Cas2Authenticator) service.getPlugin("CAS2_AUTH");
107
108        if (cas2Authenticator == null) {
109            throw new NuxeoException("Can't get CAS authenticator");
110        }
111        return cas2Authenticator;
112    }
113
114    protected String getURLToReach(HttpServletRequest request) {
115        DocumentView docView = (DocumentView) request.getAttribute(URLPolicyService.DOCUMENT_VIEW_REQUEST_KEY);
116
117        if (docView != null) {
118            String urlToReach = getURLPolicyService().getUrlFromDocumentView(docView, "");
119
120            if (urlToReach != null) {
121                return urlToReach;
122            }
123        }
124        return request.getRequestURL().toString() + "?" + request.getQueryString();
125    }
126
127    protected URLPolicyService getURLPolicyService() {
128        return Framework.getService(URLPolicyService.class);
129    }
130
131}