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        log.debug("handleRetrieveIdentity going on with authenticated user = [" + userName + "]");
131        return uui;
132    }
133
134    @Override
135    public Boolean needLoginPrompt(HttpServletRequest request) {
136        // Returning true means that the handleLoginPrompt method will be called
137        return true;
138    }
139
140    /**
141     * @return true if there is a redirection
142     */
143    @Override
144    public Boolean handleLogout(HttpServletRequest request, HttpServletResponse response) {
145        log.debug("handleLogout ...");
146        expireCookie(CLEARTRUST_COOKIE_SESSION, request, response);
147        expireCookie(CLEARTRUST_COOKIE_SESSION_A, request, response);
148
149        if (cleartrustLogoutUrl == null || "".equals(cleartrustLogoutUrl)) {
150            return false;
151        }
152
153        try {
154            log.debug("Redirecting to logoutUrl = [" + cleartrustLogoutUrl + "] ...");
155            response.sendRedirect(cleartrustLogoutUrl);
156            log.debug("handleLogout DONE!");
157            return true;
158        } catch (IOException e) {
159            log.error("Unable to redirect to the logout URL [" + cleartrustLogoutUrl + "] :", e);
160            return false;
161        }
162    }
163
164    protected Cookie[] getCookies(HttpServletRequest request) {
165        Cookie[] cookies = request.getCookies();
166        if (cookies == null) {
167            cookies = new Cookie[0];
168        }
169        return cookies;
170    }
171
172    private String getCookieValue(String cookieName, Cookie[] cookies) {
173        String cookieValue = null;
174        for (Cookie cookie : cookies) {
175            if (cookieName.equals(cookie.getName())) {
176                cookieValue = cookie.getValue();
177            }
178        }
179        return cookieValue;
180    }
181
182    private void expireCookie(String cookieName, HttpServletRequest request, HttpServletResponse response) {
183        log.debug("expiring cookie [" + cookieName + "]  ...");
184        Cookie cookie = new Cookie(cookieName, "");
185        // A zero value causes the cookie to be deleted
186        cookie.setMaxAge(0);
187        cookie.setPath("/");
188        response.addCookie(cookie);
189    }
190
191    protected void displayCookieInformation(Cookie[] cookies) {
192        log.debug(">>>>>>>>>>>>> Here are the cookies: ");
193        for (Cookie cookie : cookies) {
194            log.debug("displayCookieInformation cookie name: [" + cookie.getName() + "] path: [" + cookie.getPath()
195                    + "] domain: " + cookie.getDomain() + " max age: " + cookie.getMaxAge() + " value: ["
196                    + cookie.getValue() + "]");
197        }
198    }
199
200    protected void displayRequestInformation(HttpServletRequest request) {
201        log.debug(">>>>>>>>>>>>> Here is the request: ");
202        for (Enumeration<String> headerNames = request.getHeaderNames(); headerNames.hasMoreElements();) {
203            String headerName = (String) headerNames.nextElement();
204            log.debug("header " + headerName + " : [" + request.getHeader(headerName) + "]");
205        }
206        for (Enumeration<String> attributeNames = request.getAttributeNames(); attributeNames.hasMoreElements();) {
207            String attributeName = (String) attributeNames.nextElement();
208            log.debug("attribute " + attributeName + " : [" + request.getAttribute(attributeName) + "]");
209        }
210        for (Enumeration<String> parameterNames = request.getParameterNames(); parameterNames.hasMoreElements();) {
211            String parameterName = (String) parameterNames.nextElement();
212            log.debug("parameter " + parameterName + " : [" + request.getParameter(parameterName) + "]");
213        }
214    }
215
216    @Override
217    public void initPlugin(Map<String, String> parameters) {
218        log.debug("initPlugin v 1.1");
219        if (parameters.containsKey(ClearTrustParameters.COOKIE_DOMAIN)) {
220            cookieDomain = parameters.get(ClearTrustParameters.COOKIE_DOMAIN);
221            log.debug("initPlugin cookieDomain = [" + cookieDomain + "]");
222        }
223        if (parameters.containsKey(ClearTrustParameters.CLEARTRUST_LOGIN_URL)) {
224            cleartrustLoginUrl = parameters.get(ClearTrustParameters.CLEARTRUST_LOGIN_URL);
225            log.debug("initPlugin cleartrustLoginUrl = [" + cleartrustLoginUrl + "]");
226        }
227        if (parameters.containsKey(ClearTrustParameters.CLEARTRUST_LOGOUT_URL)) {
228            cleartrustLogoutUrl = parameters.get(ClearTrustParameters.CLEARTRUST_LOGOUT_URL);
229            log.debug("initPlugin cleartrustLogoutUrl = [" + cleartrustLogoutUrl + "]");
230        }
231        log.debug("initPlugin DONE");
232    }
233
234}