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.PropsKeys;
20  import com.liferay.portal.servlet.filters.BasePortalFilter;
21  import com.liferay.portal.util.PortalUtil;
22  import com.liferay.portal.util.PrefsPropsUtil;
23  import com.liferay.portal.util.PropsValues;
24  import com.liferay.util.servlet.filters.DynamicFilterConfig;
25  
26  import java.util.Map;
27  import java.util.concurrent.ConcurrentHashMap;
28  
29  import javax.servlet.Filter;
30  import javax.servlet.FilterChain;
31  import javax.servlet.FilterConfig;
32  import javax.servlet.ServletContext;
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.authentication.AuthenticationFilter;
39  import org.jasig.cas.client.util.AbstractCasFilter;
40  import org.jasig.cas.client.validation.Assertion;
41  import org.jasig.cas.client.validation.Cas20ProxyReceivingTicketValidationFilter;
42  
43  /**
44   * <a href="CASFilter.java.html"><b><i>View Source</i></b></a>
45   *
46   * @author Michael Young
47   * @author Brian Wing Shun Chan
48   * @author Raymond Augé
49   * @author Tina Tian
50   */
51  public class CASFilter extends BasePortalFilter {
52  
53      public static String LOGIN = CASFilter.class.getName() + "LOGIN";
54  
55      public static void reload(long companyId) {
56          _casAuthenticationFilters.remove(companyId);
57          _casTicketValidationFilters.remove(companyId);
58      }
59  
60      public void init(FilterConfig filterConfig) {
61          super.init(filterConfig);
62  
63          _servletContext = getFilterConfig().getServletContext();
64      }
65  
66      protected Filter getCASAuthenticationFilter(long companyId)
67          throws Exception {
68  
69          Filter casAuthenticationFilter = _casAuthenticationFilters.get(
70              companyId);
71  
72          if (casAuthenticationFilter == null) {
73              casAuthenticationFilter = new AuthenticationFilter();
74  
75              DynamicFilterConfig dynamicFilterConfig = new DynamicFilterConfig(
76                  _filterName, _servletContext);
77  
78              String serverName = PrefsPropsUtil.getString(
79                  companyId, PropsKeys.CAS_SERVER_NAME,
80                  PropsValues.CAS_SERVER_NAME);
81              String loginUrl = PrefsPropsUtil.getString(
82                  companyId, PropsKeys.CAS_LOGIN_URL, PropsValues.CAS_LOGIN_URL);
83  
84              dynamicFilterConfig.addInitParameter("serverName", serverName);
85              dynamicFilterConfig.addInitParameter("casServerLoginUrl", loginUrl);
86  
87              casAuthenticationFilter.init(dynamicFilterConfig);
88  
89              _casAuthenticationFilters.put(companyId, casAuthenticationFilter);
90          }
91  
92          return casAuthenticationFilter;
93      }
94  
95      protected Filter getCASTicketValidationFilter(long companyId)
96          throws Exception {
97  
98          Filter casTicketValidationFilter = _casTicketValidationFilters.get(
99              companyId);
100 
101         if (casTicketValidationFilter == null) {
102             casTicketValidationFilter =
103                 new Cas20ProxyReceivingTicketValidationFilter();
104 
105             DynamicFilterConfig dynamicFilterConfig = new DynamicFilterConfig(
106                 _filterName, _servletContext);
107 
108             String serverName = PrefsPropsUtil.getString(
109                 companyId, PropsKeys.CAS_SERVER_NAME,
110                 PropsValues.CAS_SERVER_NAME);
111             String serverUrl = PrefsPropsUtil.getString(
112                 companyId, PropsKeys.CAS_SERVER_URL,
113                 PropsValues.CAS_SERVER_URL);
114             String loginUrl = PrefsPropsUtil.getString(
115                 companyId, PropsKeys.CAS_LOGIN_URL, PropsValues.CAS_LOGIN_URL);
116 
117             dynamicFilterConfig.addInitParameter("serverName", serverName);
118             dynamicFilterConfig.addInitParameter(
119                 "casServerUrlPrefix", serverUrl);
120             dynamicFilterConfig.addInitParameter("casServerLoginUrl", loginUrl);
121             dynamicFilterConfig.addInitParameter(
122                 "redirectAfterValidation", "false");
123 
124             casTicketValidationFilter.init(dynamicFilterConfig);
125 
126             _casTicketValidationFilters.put(
127                 companyId, casTicketValidationFilter);
128         }
129 
130         return casTicketValidationFilter;
131     }
132 
133     protected Log getLog() {
134         return _log;
135     }
136 
137     protected void processFilter(
138             HttpServletRequest request, HttpServletResponse response,
139             FilterChain filterChain)
140         throws Exception {
141 
142         long companyId = PortalUtil.getCompanyId(request);
143 
144         if (PrefsPropsUtil.getBoolean(
145                 companyId, PropsKeys.CAS_AUTH_ENABLED,
146                 PropsValues.CAS_AUTH_ENABLED)) {
147 
148             HttpSession session = request.getSession();
149 
150             String pathInfo = request.getPathInfo();
151 
152             if (pathInfo.indexOf("/portal/logout") != -1) {
153                 session.invalidate();
154 
155                 String logoutUrl = PrefsPropsUtil.getString(
156                     companyId, PropsKeys.CAS_LOGOUT_URL,
157                     PropsValues.CAS_LOGOUT_URL);
158 
159                 response.sendRedirect(logoutUrl);
160             }
161             else {
162                 Filter casAuthenticationFilter = getCASAuthenticationFilter(
163                     companyId);
164 
165                 casAuthenticationFilter.doFilter(
166                     request, response, filterChain);
167 
168                 Filter casTicketValidationFilter = getCASTicketValidationFilter(
169                     companyId);
170 
171                 casTicketValidationFilter.doFilter(
172                     request, response, filterChain);
173 
174                 Assertion assertion = (Assertion)session.getAttribute(
175                     AbstractCasFilter.CONST_CAS_ASSERTION);
176 
177                 if (assertion != null) {
178                     AttributePrincipal attributePrincipal =
179                         assertion.getPrincipal();
180 
181                     String login = attributePrincipal.getName();
182 
183                     session.setAttribute(LOGIN, login);
184                 }
185             }
186         }
187         else {
188             processFilter(CASFilter.class, request, response, filterChain);
189         }
190     }
191 
192     private static Log _log = LogFactoryUtil.getLog(CASFilter.class);
193 
194     private static Map<Long, Filter> _casAuthenticationFilters =
195         new ConcurrentHashMap<Long, Filter>();
196     private static Map<Long, Filter> _casTicketValidationFilters =
197         new ConcurrentHashMap<Long, Filter>();
198 
199     private String _filterName;
200     private ServletContext _servletContext;
201 
202 }