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