1   /**
2    * Copyright (c) 2000-2010 Liferay, Inc. All rights reserved.
3    *
4    * This library is free software; you can redistribute it and/or modify it under
5    * the terms of the GNU Lesser General Public License as published by the Free
6    * Software Foundation; either version 2.1 of the License, or (at your option)
7    * any later version.
8    *
9    * This library is distributed in the hope that it will be useful, but WITHOUT
10   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11   * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
12   * details.
13   */
14  
15  package com.liferay.portal.servlet.filters.sso.cas;
16  
17  import com.liferay.portal.kernel.log.Log;
18  import com.liferay.portal.kernel.log.LogFactoryUtil;
19  import com.liferay.portal.kernel.util.HttpUtil;
20  import com.liferay.portal.kernel.util.ParamUtil;
21  import com.liferay.portal.kernel.util.PropsKeys;
22  import com.liferay.portal.kernel.util.Validator;
23  import com.liferay.portal.servlet.filters.BasePortalFilter;
24  import com.liferay.portal.util.PortalUtil;
25  import com.liferay.portal.util.PrefsPropsUtil;
26  import com.liferay.portal.util.PropsValues;
27  
28  import java.util.HashMap;
29  import java.util.Map;
30  import java.util.concurrent.ConcurrentHashMap;
31  
32  import javax.servlet.FilterChain;
33  import javax.servlet.http.HttpServletRequest;
34  import javax.servlet.http.HttpServletResponse;
35  import javax.servlet.http.HttpSession;
36  
37  import org.jasig.cas.client.authentication.AttributePrincipal;
38  import org.jasig.cas.client.validation.Assertion;
39  import org.jasig.cas.client.validation.Cas20ProxyTicketValidator;
40  import org.jasig.cas.client.validation.TicketValidator;
41  
42  /**
43   * <a href="CASFilter.java.html"><b><i>View Source</i></b></a>
44   *
45   * @author Michael Young
46   * @author Brian Wing Shun Chan
47   * @author Raymond Augé
48   * @author Tina Tian
49   */
50  public class CASFilter extends BasePortalFilter {
51  
52      public static String LOGIN = CASFilter.class.getName() + "LOGIN";
53  
54      public static void reload(long companyId) {
55          _ticketValidators.remove(companyId);
56      }
57  
58      protected Log getLog() {
59          return _log;
60      }
61  
62      protected TicketValidator getTicketValidator(long companyId)
63          throws Exception {
64  
65          TicketValidator ticketValidator = _ticketValidators.get(companyId);
66  
67          if (ticketValidator != null) {
68              return ticketValidator;
69          }
70  
71          String serverName = PrefsPropsUtil.getString(
72              companyId, PropsKeys.CAS_SERVER_NAME, PropsValues.CAS_SERVER_NAME);
73          String serverUrl = PrefsPropsUtil.getString(
74              companyId, PropsKeys.CAS_SERVER_URL, PropsValues.CAS_SERVER_URL);
75          String loginUrl = PrefsPropsUtil.getString(
76              companyId, PropsKeys.CAS_LOGIN_URL, PropsValues.CAS_LOGIN_URL);
77  
78          Cas20ProxyTicketValidator cas20ProxyTicketValidator =
79              new Cas20ProxyTicketValidator(serverUrl);
80  
81          Map<String, String> parameters = new HashMap<String, String>();
82  
83          parameters.put("serverName", serverName);
84          parameters.put("casServerUrlPrefix", serverUrl);
85          parameters.put("casServerLoginUrl", loginUrl);
86          parameters.put("redirectAfterValidation", "false");
87  
88          cas20ProxyTicketValidator.setCustomParameters(parameters);
89  
90          _ticketValidators.put(companyId, cas20ProxyTicketValidator);
91  
92          return cas20ProxyTicketValidator;
93      }
94  
95      protected void processFilter(
96              HttpServletRequest request, HttpServletResponse response,
97              FilterChain filterChain)
98          throws Exception {
99  
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             else {
120                 String login = (String)session.getAttribute(LOGIN);
121 
122                 String serviceUrl = PrefsPropsUtil.getString(
123                     companyId, PropsKeys.CAS_SERVICE_URL,
124                     PropsValues.CAS_SERVICE_URL);
125                 String loginUrl = PrefsPropsUtil.getString(
126                     companyId, PropsKeys.CAS_LOGIN_URL,
127                     PropsValues.CAS_LOGIN_URL);
128 
129                 String ticket = ParamUtil.getString(request, "ticket");
130 
131                 if (Validator.isNull(ticket)) {
132                     if (Validator.isNotNull(login)) {
133                         processFilter(
134                             CASFilter.class, request, response, filterChain);
135                     }
136                     else {
137                         loginUrl = HttpUtil.addParameter(
138                             loginUrl, "service", serviceUrl);
139 
140                         response.sendRedirect(loginUrl);
141                     }
142 
143                     return;
144                 }
145 
146                 TicketValidator ticketValidator = getTicketValidator(
147                     companyId);
148 
149                 Assertion assertion = ticketValidator.validate(
150                     ticket, serviceUrl);
151 
152                 if (assertion != null) {
153                     AttributePrincipal attributePrincipal =
154                         assertion.getPrincipal();
155 
156                     login = attributePrincipal.getName();
157 
158                     session.setAttribute(LOGIN, login);
159                 }
160             }
161         }
162 
163         processFilter(CASFilter.class, request, response, filterChain);
164     }
165 
166     private static Log _log = LogFactoryUtil.getLog(CASFilter.class);
167 
168     private static Map<Long, TicketValidator> _ticketValidators =
169         new ConcurrentHashMap<Long, TicketValidator>();
170 
171 }