001
014
015 package com.liferay.portal.servlet.filters.secure;
016
017 import com.liferay.portal.kernel.log.Log;
018 import com.liferay.portal.kernel.log.LogFactoryUtil;
019 import com.liferay.portal.kernel.servlet.HttpHeaders;
020 import com.liferay.portal.kernel.servlet.ProtectedServletRequest;
021 import com.liferay.portal.kernel.util.GetterUtil;
022 import com.liferay.portal.kernel.util.Http;
023 import com.liferay.portal.kernel.util.HttpUtil;
024 import com.liferay.portal.kernel.util.StringBundler;
025 import com.liferay.portal.kernel.util.StringPool;
026 import com.liferay.portal.kernel.util.StringUtil;
027 import com.liferay.portal.kernel.util.Validator;
028 import com.liferay.portal.model.User;
029 import com.liferay.portal.security.auth.CompanyThreadLocal;
030 import com.liferay.portal.security.auth.PrincipalThreadLocal;
031 import com.liferay.portal.security.permission.PermissionChecker;
032 import com.liferay.portal.security.permission.PermissionCheckerFactoryUtil;
033 import com.liferay.portal.security.permission.PermissionThreadLocal;
034 import com.liferay.portal.security.sso.SSOUtil;
035 import com.liferay.portal.service.UserLocalServiceUtil;
036 import com.liferay.portal.servlet.filters.BasePortalFilter;
037 import com.liferay.portal.util.Portal;
038 import com.liferay.portal.util.PortalInstances;
039 import com.liferay.portal.util.PortalUtil;
040 import com.liferay.portal.util.PropsUtil;
041 import com.liferay.portal.util.WebKeys;
042
043 import java.util.HashSet;
044 import java.util.Set;
045
046 import javax.servlet.FilterChain;
047 import javax.servlet.FilterConfig;
048 import javax.servlet.http.HttpServletRequest;
049 import javax.servlet.http.HttpServletResponse;
050 import javax.servlet.http.HttpSession;
051
052
057 public class SecureFilter extends BasePortalFilter {
058
059 @Override
060 public void init(FilterConfig filterConfig) {
061 super.init(filterConfig);
062
063 _basicAuthEnabled = GetterUtil.getBoolean(
064 filterConfig.getInitParameter("basic_auth"));
065 _digestAuthEnabled = GetterUtil.getBoolean(
066 filterConfig.getInitParameter("digest_auth"));
067
068 String propertyPrefix = filterConfig.getInitParameter(
069 "portal_property_prefix");
070
071 String[] hostsAllowed = null;
072
073 if (Validator.isNull(propertyPrefix)) {
074 hostsAllowed = StringUtil.split(
075 filterConfig.getInitParameter("hosts.allowed"));
076 _httpsRequired = GetterUtil.getBoolean(
077 filterConfig.getInitParameter("https.required"));
078 }
079 else {
080 hostsAllowed = PropsUtil.getArray(propertyPrefix + "hosts.allowed");
081 _httpsRequired = GetterUtil.getBoolean(
082 PropsUtil.get(propertyPrefix + "https.required"));
083 }
084
085 for (String hostAllowed : hostsAllowed) {
086 _hostsAllowed.add(hostAllowed);
087 }
088
089 _usePermissionChecker = GetterUtil.getBoolean(
090 filterConfig.getInitParameter("use_permission_checker"));
091 }
092
093 protected HttpServletRequest basicAuth(
094 HttpServletRequest request, HttpServletResponse response)
095 throws Exception {
096
097 HttpSession session = request.getSession();
098
099 session.setAttribute(WebKeys.BASIC_AUTH_ENABLED, Boolean.TRUE);
100
101 long userId = GetterUtil.getLong(
102 (String)session.getAttribute(_AUTHENTICATED_USER));
103
104 if (userId > 0) {
105 request = new ProtectedServletRequest(
106 request, String.valueOf(userId), HttpServletRequest.BASIC_AUTH);
107
108 initThreadLocals(request);
109 }
110 else {
111 try {
112 userId = PortalUtil.getBasicAuthUserId(request);
113 }
114 catch (Exception e) {
115 _log.error(e, e);
116 }
117
118 if (userId > 0) {
119 request = setCredentials(
120 request, session, userId, HttpServletRequest.BASIC_AUTH);
121 }
122 else {
123 response.setHeader(HttpHeaders.WWW_AUTHENTICATE, _BASIC_REALM);
124 response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
125
126 return null;
127 }
128 }
129
130 return request;
131 }
132
133 protected HttpServletRequest digestAuth(
134 HttpServletRequest request, HttpServletResponse response)
135 throws Exception {
136
137 HttpSession session = request.getSession();
138
139 long userId = GetterUtil.getLong(
140 (String)session.getAttribute(_AUTHENTICATED_USER));
141
142 if (userId > 0) {
143 request = new ProtectedServletRequest(
144 request, String.valueOf(userId),
145 HttpServletRequest.DIGEST_AUTH);
146
147 initThreadLocals(request);
148 }
149 else {
150 try {
151 userId = PortalUtil.getDigestAuthUserId(request);
152 }
153 catch (Exception e) {
154 _log.error(e, e);
155 }
156
157 if (userId > 0) {
158 request = setCredentials(
159 request, session, userId, HttpServletRequest.DIGEST_AUTH);
160 }
161 else {
162
163
164
165 long companyId = PortalInstances.getCompanyId(request);
166
167 String remoteAddress = request.getRemoteAddr();
168
169 String nonce = NonceUtil.generate(companyId, remoteAddress);
170
171 StringBundler sb = new StringBundler(4);
172
173 sb.append(_DIGEST_REALM);
174 sb.append(", nonce=\"");
175 sb.append(nonce);
176 sb.append("\"");
177
178 response.setHeader(HttpHeaders.WWW_AUTHENTICATE, sb.toString());
179 response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
180
181 return null;
182 }
183 }
184
185 return request;
186 }
187
188 protected void initThreadLocals(HttpServletRequest request)
189 throws Exception {
190
191 HttpSession session = request.getSession();
192
193 User user = (User)session.getAttribute(WebKeys.USER);
194
195 initThreadLocals(user);
196
197 PrincipalThreadLocal.setPassword(PortalUtil.getUserPassword(request));
198 }
199
200 protected void initThreadLocals(User user) throws Exception {
201 CompanyThreadLocal.setCompanyId(user.getCompanyId());
202
203 PrincipalThreadLocal.setName(user.getUserId());
204
205 if (!_usePermissionChecker) {
206 return;
207 }
208
209 PermissionChecker permissionChecker =
210 PermissionThreadLocal.getPermissionChecker();
211
212 if (permissionChecker != null) {
213 return;
214 }
215
216 permissionChecker = PermissionCheckerFactoryUtil.create(user);
217
218 PermissionThreadLocal.setPermissionChecker(permissionChecker);
219 }
220
221 @Override
222 protected void processFilter(
223 HttpServletRequest request, HttpServletResponse response,
224 FilterChain filterChain)
225 throws Exception {
226
227 String remoteAddr = request.getRemoteAddr();
228
229 if (SSOUtil.isAccessAllowed(request, _hostsAllowed)) {
230 if (_log.isDebugEnabled()) {
231 _log.debug("Access allowed for " + remoteAddr);
232 }
233 }
234 else {
235 if (_log.isWarnEnabled()) {
236 _log.warn("Access denied for " + remoteAddr);
237 }
238
239 response.sendError(
240 HttpServletResponse.SC_FORBIDDEN,
241 "Access denied for " + remoteAddr);
242
243 return;
244 }
245
246 if (_log.isDebugEnabled()) {
247 if (_httpsRequired) {
248 _log.debug("https is required");
249 }
250 else {
251 _log.debug("https is not required");
252 }
253 }
254
255 if (_httpsRequired && !request.isSecure()) {
256 if (_log.isDebugEnabled()) {
257 String completeURL = HttpUtil.getCompleteURL(request);
258
259 _log.debug("Securing " + completeURL);
260 }
261
262 StringBundler redirectURL = new StringBundler(5);
263
264 redirectURL.append(Http.HTTPS_WITH_SLASH);
265 redirectURL.append(request.getServerName());
266 redirectURL.append(request.getServletPath());
267
268 String queryString = request.getQueryString();
269
270 if (Validator.isNotNull(queryString)) {
271 redirectURL.append(StringPool.QUESTION);
272 redirectURL.append(request.getQueryString());
273 }
274
275 if (_log.isDebugEnabled()) {
276 _log.debug("Redirect to " + redirectURL);
277 }
278
279 response.sendRedirect(redirectURL.toString());
280 }
281 else {
282 if (_log.isDebugEnabled()) {
283 String completeURL = HttpUtil.getCompleteURL(request);
284
285 _log.debug("Not securing " + completeURL);
286 }
287
288 User user = PortalUtil.getUser(request);
289
290 if (user == null) {
291 user = PortalUtil.initUser(request);
292 }
293
294 initThreadLocals(user);
295
296 if (!user.isDefaultUser()) {
297 request = setCredentials(
298 request, request.getSession(), user.getUserId(), null);
299 }
300 else {
301 if (_digestAuthEnabled) {
302 request = digestAuth(request, response);
303 }
304 else if (_basicAuthEnabled) {
305 request = basicAuth(request, response);
306 }
307 }
308
309 if (request != null) {
310 processFilter(getClass(), request, response, filterChain);
311 }
312 }
313 }
314
315 protected HttpServletRequest setCredentials(
316 HttpServletRequest request, HttpSession session, long userId,
317 String authType)
318 throws Exception {
319
320 User user = UserLocalServiceUtil.getUser(userId);
321
322 String userIdString = String.valueOf(userId);
323
324 request = new ProtectedServletRequest(request, userIdString, authType);
325
326 session.setAttribute(WebKeys.USER, user);
327 session.setAttribute(_AUTHENTICATED_USER, userIdString);
328
329 initThreadLocals(request);
330
331 return request;
332 }
333
334 protected void setUsePermissionChecker(boolean usePermissionChecker) {
335 _usePermissionChecker = usePermissionChecker;
336 }
337
338 private static final String _AUTHENTICATED_USER =
339 SecureFilter.class + "_AUTHENTICATED_USER";
340
341 private static final String _BASIC_REALM =
342 "Basic realm=\"" + Portal.PORTAL_REALM + "\"";
343
344 private static final String _DIGEST_REALM =
345 "Digest realm=\"" + Portal.PORTAL_REALM + "\"";
346
347 private static final Log _log = LogFactoryUtil.getLog(SecureFilter.class);
348
349 private boolean _basicAuthEnabled;
350 private boolean _digestAuthEnabled;
351 private final Set<String> _hostsAllowed = new HashSet<>();
352 private boolean _httpsRequired;
353 private boolean _usePermissionChecker;
354
355 }