001/*
002 * (C) Copyright 2006-2009 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 * $Id: ClearTrustAuthenticator.java 33212 2009-04-22 14:06:56Z madarche $
020 */
021
022package org.nuxeo.ecm.platform.ui.web.auth.cleartrust;
023
024import java.io.IOException;
025import java.util.ArrayList;
026import java.util.Enumeration;
027import java.util.List;
028import java.util.Map;
029
030import javax.servlet.http.Cookie;
031import javax.servlet.http.HttpServletRequest;
032import javax.servlet.http.HttpServletResponse;
033
034import org.apache.commons.logging.Log;
035import org.apache.commons.logging.LogFactory;
036import org.nuxeo.ecm.platform.api.login.UserIdentificationInfo;
037import org.nuxeo.ecm.platform.ui.web.auth.interfaces.NuxeoAuthenticationPlugin;
038import org.nuxeo.ecm.platform.ui.web.auth.interfaces.NuxeoAuthenticationPluginLogoutExtension;
039
040/**
041 * @author M.-A. Darche
042 */
043public class ClearTrustAuthenticator implements NuxeoAuthenticationPlugin, NuxeoAuthenticationPluginLogoutExtension {
044
045    protected static final String CLEARTRUST_HEADER_UID = "REMOTE_USER";
046
047    protected static final String CLEARTRUST_COOKIE_SESSION_A = "ACTSESSION";
048
049    protected static final String CLEARTRUST_COOKIE_SESSION = "CTSESSION";
050
051    protected String cookieDomain = "";
052
053    protected String cleartrustLoginUrl = "";
054
055    protected String cleartrustLogoutUrl = "";
056
057    private static final Log log = LogFactory.getLog(ClearTrustAuthenticator.class);
058
059    public List<String> getUnAuthenticatedURLPrefix() {
060        // There isn't any URL that should not need authentication
061        return null;
062    }
063
064    /**
065     * Redirects to the ClearTrust login page if the request doesn't contain cookies indicating that a positive
066     * authentication occurred.
067     *
068     * @return true if AuthFilter must stop execution (ie: login prompt generated a redirect), false otherwise
069     */
070    public Boolean handleLoginPrompt(HttpServletRequest request, HttpServletResponse response, String baseURL) {
071        log.debug("handleLoginPrompt ...");
072        log.debug("handleLoginPrompt requestURL = " + request.getRequestURL());
073        Cookie[] cookies = getCookies(request);
074        displayRequestInformation(request);
075        displayCookieInformation(cookies);
076        String ctSession = getCookieValue(CLEARTRUST_COOKIE_SESSION, cookies);
077        String ctSessionA = getCookieValue(CLEARTRUST_COOKIE_SESSION_A, cookies);
078        log.debug("ctSession = " + ctSession);
079        log.debug("ctSessionA = " + ctSessionA);
080
081        boolean redirectToClearTrustLoginPage = false;
082        if (ctSession == null) {
083            log.debug("No ClearTrust session: not authorizing + redirecting to ClearTrust");
084            redirectToClearTrustLoginPage = true;
085        }
086
087        if ("%20".equals(ctSessionA)) {
088            log.debug("User has logout from ClearTrust: not authorizing + redirecting to ClearTrust");
089            redirectToClearTrustLoginPage = true;
090        }
091
092        String ctUid = request.getHeader(CLEARTRUST_HEADER_UID);
093        log.debug("ctUid = [" + ctUid + "]");
094        if (ctUid == null) {
095            redirectToClearTrustLoginPage = true;
096        }
097
098        if (redirectToClearTrustLoginPage) {
099            String loginUrl = cleartrustLoginUrl;
100            try {
101                if (cleartrustLoginUrl == null || "".equals(cleartrustLoginUrl)) {
102                    // loginUrl = baseURL
103                    // + NuxeoAuthenticationFilter.DEFAULT_START_PAGE;
104                    loginUrl = baseURL + "login.jsp";
105                }
106                log.debug("Redirecting to loginUrl: " + loginUrl);
107                response.sendRedirect(loginUrl);
108                return true;
109            } catch (IOException ex) {
110                log.error("Unable to redirect to ClearTrust login URL [" + loginUrl + "]:", ex);
111                return false;
112            }
113        }
114        log.debug("ClearTrust authentication is OK, letting the user in.");
115        return false;
116    }
117
118    public UserIdentificationInfo handleRetrieveIdentity(HttpServletRequest request, HttpServletResponse httpResponse) {
119        log.debug("handleRetrieveIdentity ...");
120        Cookie[] cookies = getCookies(request);
121        displayRequestInformation(request);
122        displayCookieInformation(cookies);
123
124        String ctUid = request.getHeader(CLEARTRUST_HEADER_UID);
125        log.debug("handleRetrieveIdentity ctUid = [" + ctUid + "]");
126        String userName = ctUid;
127        UserIdentificationInfo uui = new UserIdentificationInfo(userName,
128                "No password needed for ClearTrust authentication");
129        log.debug("handleRetrieveIdentity going on with authenticated user = [" + userName + "]");
130        return uui;
131    }
132
133    public Boolean needLoginPrompt(HttpServletRequest request) {
134        // Returning true means that the handleLoginPrompt method will be called
135        return true;
136    }
137
138    /**
139     * @return true if there is a redirection
140     */
141    public Boolean handleLogout(HttpServletRequest request, HttpServletResponse response) {
142        log.debug("handleLogout ...");
143        expireCookie(CLEARTRUST_COOKIE_SESSION, request, response);
144        expireCookie(CLEARTRUST_COOKIE_SESSION_A, request, response);
145
146        if (cleartrustLogoutUrl == null || "".equals(cleartrustLogoutUrl)) {
147            return false;
148        }
149
150        try {
151            log.debug("Redirecting to logoutUrl = [" + cleartrustLogoutUrl + "] ...");
152            response.sendRedirect(cleartrustLogoutUrl);
153            log.debug("handleLogout DONE!");
154            return true;
155        } catch (IOException e) {
156            log.error("Unable to redirect to the logout URL [" + cleartrustLogoutUrl + "] :", e);
157            return false;
158        }
159    }
160
161    protected Cookie[] getCookies(HttpServletRequest request) {
162        Cookie[] cookies = request.getCookies();
163        if (cookies == null) {
164            cookies = new Cookie[0];
165        }
166        return cookies;
167    }
168
169    private String getCookieValue(String cookieName, Cookie[] cookies) {
170        String cookieValue = null;
171        for (Cookie cookie : cookies) {
172            if (cookieName.equals(cookie.getName())) {
173                cookieValue = cookie.getValue();
174            }
175        }
176        return cookieValue;
177    }
178
179    private void expireCookie(String cookieName, HttpServletRequest request, HttpServletResponse response) {
180        log.debug("expiring cookie [" + cookieName + "]  ...");
181        Cookie cookie = new Cookie(cookieName, "");
182        // A zero value causes the cookie to be deleted
183        cookie.setMaxAge(0);
184        cookie.setPath("/");
185        response.addCookie(cookie);
186    }
187
188    protected void displayCookieInformation(Cookie[] cookies) {
189        log.debug(">>>>>>>>>>>>> Here are the cookies: ");
190        for (Cookie cookie : cookies) {
191            log.debug("displayCookieInformation cookie name: [" + cookie.getName() + "] path: [" + cookie.getPath()
192                    + "] domain: " + cookie.getDomain() + " max age: " + cookie.getMaxAge() + " value: ["
193                    + cookie.getValue() + "]");
194        }
195    }
196
197    protected void displayRequestInformation(HttpServletRequest request) {
198        log.debug(">>>>>>>>>>>>> Here is the request: ");
199        for (Enumeration headerNames = request.getHeaderNames(); headerNames.hasMoreElements();) {
200            String headerName = (String) headerNames.nextElement();
201            log.debug("header " + headerName + " : [" + request.getHeader(headerName) + "]");
202        }
203        for (Enumeration attributeNames = request.getAttributeNames(); attributeNames.hasMoreElements();) {
204            String attributeName = (String) attributeNames.nextElement();
205            log.debug("attribute " + attributeName + " : [" + request.getAttribute(attributeName) + "]");
206        }
207        for (Enumeration parameterNames = request.getParameterNames(); parameterNames.hasMoreElements();) {
208            String parameterName = (String) parameterNames.nextElement();
209            log.debug("parameter " + parameterName + " : [" + request.getParameter(parameterName) + "]");
210        }
211    }
212
213    public void initPlugin(Map<String, String> parameters) {
214        log.debug("initPlugin v 1.1");
215        if (parameters.containsKey(ClearTrustParameters.COOKIE_DOMAIN)) {
216            cookieDomain = parameters.get(ClearTrustParameters.COOKIE_DOMAIN);
217            log.debug("initPlugin cookieDomain = [" + cookieDomain + "]");
218        }
219        if (parameters.containsKey(ClearTrustParameters.CLEARTRUST_LOGIN_URL)) {
220            cleartrustLoginUrl = parameters.get(ClearTrustParameters.CLEARTRUST_LOGIN_URL);
221            log.debug("initPlugin cleartrustLoginUrl = [" + cleartrustLoginUrl + "]");
222        }
223        if (parameters.containsKey(ClearTrustParameters.CLEARTRUST_LOGOUT_URL)) {
224            cleartrustLogoutUrl = parameters.get(ClearTrustParameters.CLEARTRUST_LOGOUT_URL);
225            log.debug("initPlugin cleartrustLogoutUrl = [" + cleartrustLogoutUrl + "]");
226        }
227        log.debug("initPlugin DONE");
228    }
229
230}