001/*
002 * (C) Copyright 2010-2016 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 */
019package org.nuxeo.ecm.platform.ui.web.auth.cas2;
020
021import static org.nuxeo.ecm.platform.ui.web.auth.NXAuthConstants.SSO_INITIAL_URL_REQUEST_KEY;
022
023import java.io.IOException;
024import java.security.Principal;
025
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
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 = ExceptionHelper.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 = getPrincipal(request);
069        if (principal instanceof NuxeoPrincipal) {
070            NuxeoPrincipal nuxeoPrincipal = (NuxeoPrincipal) principal;
071            // redirect to login than to requested page
072            if (nuxeoPrincipal.isAnonymous()) {
073                response.resetBuffer();
074
075                String urlToReach = getURLToReach(request);
076                Cookie cookieUrlToReach = new Cookie(NXAuthConstants.SSO_INITIAL_URL_REQUEST_KEY, urlToReach);
077                cookieUrlToReach.setPath("/");
078                cookieUrlToReach.setMaxAge(60);
079                response.addCookie(cookieUrlToReach);
080
081                if (!response.isCommitted()) {
082                    request.getRequestDispatcher(CAS_REDIRECTION_URL).forward(request, response);
083                }
084                parameters.getListener().responseComplete();
085                return;
086            }
087        }
088        // go back to default handler
089        super.handleException(request, response, t);
090    }
091
092    protected Cas2Authenticator getCasAuthenticator() {
093        if (cas2Authenticator != null) {
094            return cas2Authenticator;
095        }
096
097        PluggableAuthenticationService service = (PluggableAuthenticationService) Framework.getRuntime().getComponent(
098                PluggableAuthenticationService.NAME);
099        if (service == null) {
100            throw new NuxeoException("Can't initialize Nuxeo Pluggable Authentication Service");
101        }
102
103        cas2Authenticator = (Cas2Authenticator) service.getPlugin("CAS2_AUTH");
104
105        if (cas2Authenticator == null) {
106            throw new NuxeoException("Can't get CAS authenticator");
107        }
108        return cas2Authenticator;
109    }
110
111    protected String getURLToReach(HttpServletRequest request) {
112        DocumentView docView = (DocumentView) request.getAttribute(URLPolicyService.DOCUMENT_VIEW_REQUEST_KEY);
113
114        if (docView != null) {
115            String urlToReach = getURLPolicyService().getUrlFromDocumentView(docView, "");
116
117            if (urlToReach != null) {
118                return urlToReach;
119            }
120        }
121        return request.getRequestURL().toString() + "?" + request.getQueryString();
122    }
123
124    protected URLPolicyService getURLPolicyService() {
125        return Framework.getService(URLPolicyService.class);
126    }
127
128}