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.servlet.ServletException;
026import javax.servlet.http.Cookie;
027import javax.servlet.http.HttpServletRequest;
028import javax.servlet.http.HttpServletResponse;
029
030import org.nuxeo.ecm.core.api.NuxeoException;
031import org.nuxeo.ecm.core.api.NuxeoPrincipal;
032import org.nuxeo.ecm.platform.ui.web.auth.NXAuthConstants;
033import org.nuxeo.ecm.platform.ui.web.auth.service.PluggableAuthenticationService;
034import org.nuxeo.ecm.platform.ui.web.rest.api.URLPolicyService;
035import org.nuxeo.ecm.platform.url.api.DocumentView;
036import org.nuxeo.ecm.platform.web.common.exceptionhandling.DefaultNuxeoExceptionHandler;
037import org.nuxeo.ecm.platform.web.common.exceptionhandling.ExceptionHelper;
038import org.nuxeo.runtime.api.Framework;
039
040import static org.nuxeo.ecm.platform.ui.web.auth.NXAuthConstants.SSO_INITIAL_URL_REQUEST_KEY;
041
042public class SecurityExceptionHandler extends DefaultNuxeoExceptionHandler {
043
044    public static final String CAS_REDIRECTION_URL = "/cas2.jsp";
045
046    public static final String COOKIE_NAME_LOGOUT_URL = "cookie.name.logout.url";
047
048    Cas2Authenticator cas2Authenticator;
049
050    public SecurityExceptionHandler() {
051    }
052
053    @Override
054    public void handleException(HttpServletRequest request, HttpServletResponse response, Throwable t)
055            throws IOException, ServletException {
056
057        if (response.containsHeader("Cache-Control")) {
058            response.setHeader("Cache-Control", "no-cache");
059        }
060
061        Throwable unwrappedException = unwrapException(t);
062
063        if (!ExceptionHelper.isSecurityError(unwrappedException)
064                && !response.containsHeader(SSO_INITIAL_URL_REQUEST_KEY)) {
065            super.handleException(request, response, t);
066            return;
067        }
068
069        Principal principal = request.getUserPrincipal();
070        NuxeoPrincipal nuxeoPrincipal = null;
071        if (principal instanceof NuxeoPrincipal) {
072            nuxeoPrincipal = (NuxeoPrincipal) principal;
073            // redirect to login than to requested page
074            if (nuxeoPrincipal.isAnonymous()) {
075                response.resetBuffer();
076
077                String urlToReach = getURLToReach(request);
078                Cookie cookieUrlToReach = new Cookie(NXAuthConstants.SSO_INITIAL_URL_REQUEST_KEY, urlToReach);
079                cookieUrlToReach.setPath("/");
080                cookieUrlToReach.setMaxAge(60);
081                response.addCookie(cookieUrlToReach);
082
083                if (!response.isCommitted()) {
084                    request.getRequestDispatcher(CAS_REDIRECTION_URL).forward(request, response);
085                }
086                parameters.getListener().responseComplete();
087                return;
088            }
089        }
090        // go back to default handler
091        super.handleException(request, response, t);
092    }
093
094    protected Cas2Authenticator getCasAuthenticator() {
095        if (cas2Authenticator != null) {
096            return cas2Authenticator;
097        }
098
099        PluggableAuthenticationService service = (PluggableAuthenticationService) Framework.getRuntime().getComponent(
100                PluggableAuthenticationService.NAME);
101        if (service == null) {
102            throw new NuxeoException("Can't initialize Nuxeo Pluggable Authentication Service");
103        }
104
105        cas2Authenticator = (Cas2Authenticator) service.getPlugin("CAS2_AUTH");
106
107        if (cas2Authenticator == null) {
108            throw new NuxeoException("Can't get CAS authenticator");
109        }
110        return cas2Authenticator;
111    }
112
113    protected String getURLToReach(HttpServletRequest request) {
114        DocumentView docView = (DocumentView) request.getAttribute(URLPolicyService.DOCUMENT_VIEW_REQUEST_KEY);
115
116        if (docView != null) {
117            String urlToReach = getURLPolicyService().getUrlFromDocumentView(docView, "");
118
119            if (urlToReach != null) {
120                return urlToReach;
121            }
122        }
123        return request.getRequestURL().toString() + "?" + request.getQueryString();
124    }
125
126    protected URLPolicyService getURLPolicyService() {
127        return Framework.getService(URLPolicyService.class);
128    }
129
130}