001    /**
002     * Copyright (c) 2000-2010 Liferay, Inc. All rights reserved.
003     *
004     * The contents of this file are subject to the terms of the Liferay Enterprise
005     * Subscription License ("License"). You may not use this file except in
006     * compliance with the License. You can obtain a copy of the License by
007     * contacting Liferay, Inc. See the License for the specific language governing
008     * permissions and limitations under the License, including but not limited to
009     * distribution rights of the Software.
010     *
011     *
012     *
013     */
014    
015    package com.liferay.portal.servlet.filters.sso.cas;
016    
017    import com.liferay.portal.kernel.log.Log;
018    import com.liferay.portal.kernel.log.LogFactoryUtil;
019    import com.liferay.portal.kernel.util.HttpUtil;
020    import com.liferay.portal.kernel.util.ParamUtil;
021    import com.liferay.portal.kernel.util.PropsKeys;
022    import com.liferay.portal.kernel.util.Validator;
023    import com.liferay.portal.servlet.filters.BasePortalFilter;
024    import com.liferay.portal.util.PortalUtil;
025    import com.liferay.portal.util.PrefsPropsUtil;
026    import com.liferay.portal.util.PropsValues;
027    
028    import java.util.HashMap;
029    import java.util.Map;
030    import java.util.concurrent.ConcurrentHashMap;
031    
032    import javax.servlet.FilterChain;
033    import javax.servlet.http.HttpServletRequest;
034    import javax.servlet.http.HttpServletResponse;
035    import javax.servlet.http.HttpSession;
036    
037    import org.jasig.cas.client.authentication.AttributePrincipal;
038    import org.jasig.cas.client.util.CommonUtils;
039    import org.jasig.cas.client.validation.Assertion;
040    import org.jasig.cas.client.validation.Cas20ProxyTicketValidator;
041    import org.jasig.cas.client.validation.TicketValidator;
042    
043    /**
044     * @author Michael Young
045     * @author Brian Wing Shun Chan
046     * @author Raymond Augé
047     * @author Tina Tian
048     * @author Zsolt Balogh
049     */
050    public class CASFilter extends BasePortalFilter {
051    
052            public static String LOGIN = CASFilter.class.getName() + "LOGIN";
053    
054            public static void reload(long companyId) {
055                    _ticketValidators.remove(companyId);
056            }
057    
058            protected Log getLog() {
059                    return _log;
060            }
061    
062            protected TicketValidator getTicketValidator(long companyId)
063                    throws Exception {
064    
065                    TicketValidator ticketValidator = _ticketValidators.get(companyId);
066    
067                    if (ticketValidator != null) {
068                            return ticketValidator;
069                    }
070    
071                    String serverName = PrefsPropsUtil.getString(
072                            companyId, PropsKeys.CAS_SERVER_NAME, PropsValues.CAS_SERVER_NAME);
073                    String serverUrl = PrefsPropsUtil.getString(
074                            companyId, PropsKeys.CAS_SERVER_URL, PropsValues.CAS_SERVER_URL);
075                    String loginUrl = PrefsPropsUtil.getString(
076                            companyId, PropsKeys.CAS_LOGIN_URL, PropsValues.CAS_LOGIN_URL);
077    
078                    Cas20ProxyTicketValidator cas20ProxyTicketValidator =
079                            new Cas20ProxyTicketValidator(serverUrl);
080    
081                    Map<String, String> parameters = new HashMap<String, String>();
082    
083                    parameters.put("serverName", serverName);
084                    parameters.put("casServerUrlPrefix", serverUrl);
085                    parameters.put("casServerLoginUrl", loginUrl);
086                    parameters.put("redirectAfterValidation", "false");
087    
088                    cas20ProxyTicketValidator.setCustomParameters(parameters);
089    
090                    _ticketValidators.put(companyId, cas20ProxyTicketValidator);
091    
092                    return cas20ProxyTicketValidator;
093            }
094    
095            protected void processFilter(
096                            HttpServletRequest request, HttpServletResponse response,
097                            FilterChain filterChain)
098                    throws Exception {
099    
100                    long companyId = PortalUtil.getCompanyId(request);
101    
102                    if (PrefsPropsUtil.getBoolean(
103                                    companyId, PropsKeys.CAS_AUTH_ENABLED,
104                                    PropsValues.CAS_AUTH_ENABLED)) {
105    
106                            HttpSession session = request.getSession();
107    
108                            String pathInfo = request.getPathInfo();
109    
110                            if (pathInfo.indexOf("/portal/logout") != -1) {
111                                    session.invalidate();
112    
113                                    String logoutUrl = PrefsPropsUtil.getString(
114                                            companyId, PropsKeys.CAS_LOGOUT_URL,
115                                            PropsValues.CAS_LOGOUT_URL);
116    
117                                    response.sendRedirect(logoutUrl);
118    
119                                    return;
120                            }
121                            else {
122                                    String login = (String)session.getAttribute(LOGIN);
123    
124                                    String serverName = PrefsPropsUtil.getString(
125                                            companyId, PropsKeys.CAS_SERVER_NAME,
126                                            PropsValues.CAS_SERVER_NAME);
127    
128                                    String serviceUrl = PrefsPropsUtil.getString(
129                                            companyId, PropsKeys.CAS_SERVICE_URL,
130                                            PropsValues.CAS_SERVICE_URL);
131    
132                                    if (Validator.isNull(serviceUrl)) {
133                                            serviceUrl = CommonUtils.constructServiceUrl(
134                                                    request, response, serviceUrl, serverName, "ticket",
135                                                    false);
136                                    }
137    
138                                    String ticket = ParamUtil.getString(request, "ticket");
139    
140                                    if (Validator.isNull(ticket)) {
141                                            if (Validator.isNotNull(login)) {
142                                                    processFilter(
143                                                            CASFilter.class, request, response, filterChain);
144                                            }
145                                            else {
146                                                    String loginUrl = PrefsPropsUtil.getString(
147                                                            companyId, PropsKeys.CAS_LOGIN_URL,
148                                                            PropsValues.CAS_LOGIN_URL);
149    
150                                                    loginUrl = HttpUtil.addParameter(
151                                                            loginUrl, "service", serviceUrl);
152    
153                                                    response.sendRedirect(loginUrl);
154                                            }
155    
156                                            return;
157                                    }
158    
159                                    TicketValidator ticketValidator = getTicketValidator(
160                                            companyId);
161    
162                                    Assertion assertion = ticketValidator.validate(
163                                            ticket, serviceUrl);
164    
165                                    if (assertion != null) {
166                                            AttributePrincipal attributePrincipal =
167                                                    assertion.getPrincipal();
168    
169                                            login = attributePrincipal.getName();
170    
171                                            session.setAttribute(LOGIN, login);
172                                    }
173                            }
174                    }
175    
176                    processFilter(CASFilter.class, request, response, filterChain);
177            }
178    
179            private static Log _log = LogFactoryUtil.getLog(CASFilter.class);
180    
181            private static Map<Long, TicketValidator> _ticketValidators =
182                    new ConcurrentHashMap<Long, TicketValidator>();
183    
184    }