001
014
015 package com.liferay.portal.servlet.filters.sso.ntlm;
016
017 import com.liferay.portal.kernel.cache.PortalCache;
018 import com.liferay.portal.kernel.cache.SingleVMPoolUtil;
019 import com.liferay.portal.kernel.exception.SystemException;
020 import com.liferay.portal.kernel.log.Log;
021 import com.liferay.portal.kernel.log.LogFactoryUtil;
022 import com.liferay.portal.kernel.servlet.BrowserSnifferUtil;
023 import com.liferay.portal.kernel.servlet.HttpHeaders;
024 import com.liferay.portal.kernel.util.GetterUtil;
025 import com.liferay.portal.kernel.util.PropsKeys;
026 import com.liferay.portal.kernel.util.Validator;
027 import com.liferay.portal.security.auth.AuthSettingsUtil;
028 import com.liferay.portal.security.ntlm.NtlmManager;
029 import com.liferay.portal.security.ntlm.NtlmUserAccount;
030 import com.liferay.portal.servlet.filters.BasePortalFilter;
031 import com.liferay.portal.util.PortalInstances;
032 import com.liferay.portal.util.PrefsPropsUtil;
033 import com.liferay.portal.util.PropsUtil;
034 import com.liferay.portal.util.PropsValues;
035 import com.liferay.portal.util.WebKeys;
036
037 import java.security.SecureRandom;
038
039 import java.util.Map;
040 import java.util.Properties;
041 import java.util.concurrent.ConcurrentHashMap;
042
043 import javax.servlet.FilterChain;
044 import javax.servlet.FilterConfig;
045 import javax.servlet.http.HttpServletRequest;
046 import javax.servlet.http.HttpServletResponse;
047 import javax.servlet.http.HttpSession;
048
049 import jcifs.Config;
050
051 import jcifs.util.Base64;
052
053
061 public class NtlmFilter extends BasePortalFilter {
062
063 @Override
064 public void init(FilterConfig filterConfig) {
065 super.init(filterConfig);
066
067 try {
068 Properties properties = PropsUtil.getProperties("jcifs.", false);
069
070 for (Map.Entry<Object, Object> entry : properties.entrySet()) {
071 String key = (String)entry.getKey();
072 String value = (String)entry.getValue();
073
074 Config.setProperty(key, value);
075 }
076 }
077 catch (Exception e) {
078 _log.error(e, e);
079 }
080 }
081
082 @Override
083 public boolean isFilterEnabled(
084 HttpServletRequest request, HttpServletResponse response) {
085
086 try {
087 long companyId = PortalInstances.getCompanyId(request);
088
089 if (BrowserSnifferUtil.isIe(request) &&
090 AuthSettingsUtil.isNtlmEnabled(companyId)) {
091
092 return true;
093 }
094 }
095 catch (Exception e) {
096 _log.error(e, e);
097 }
098
099 return false;
100 }
101
102 @Override
103 protected Log getLog() {
104 return _log;
105 }
106
107 protected NtlmManager getNtlmManager(long companyId)
108 throws SystemException {
109
110 String domain = PrefsPropsUtil.getString(
111 companyId, PropsKeys.NTLM_DOMAIN, PropsValues.NTLM_DOMAIN);
112 String domainController = PrefsPropsUtil.getString(
113 companyId, PropsKeys.NTLM_DOMAIN_CONTROLLER,
114 PropsValues.NTLM_DOMAIN_CONTROLLER);
115 String domainControllerName = PrefsPropsUtil.getString(
116 companyId, PropsKeys.NTLM_DOMAIN_CONTROLLER_NAME,
117 PropsValues.NTLM_DOMAIN_CONTROLLER_NAME);
118 String serviceAccount = PrefsPropsUtil.getString(
119 companyId, PropsKeys.NTLM_SERVICE_ACCOUNT,
120 PropsValues.NTLM_SERVICE_ACCOUNT);
121 String servicePassword = PrefsPropsUtil.getString(
122 companyId, PropsKeys.NTLM_SERVICE_PASSWORD,
123 PropsValues.NTLM_SERVICE_PASSWORD);
124
125 NtlmManager ntlmManager = _ntlmManagers.get(companyId);
126
127 if (ntlmManager == null) {
128 ntlmManager = new NtlmManager(
129 domain, domainController, domainControllerName, serviceAccount,
130 servicePassword);
131
132 _ntlmManagers.put(companyId, ntlmManager);
133 }
134 else {
135 if (!Validator.equals(ntlmManager.getDomain(), domain) ||
136 !Validator.equals(
137 ntlmManager.getDomainController(), domainController) ||
138 !Validator.equals(
139 ntlmManager.getDomainControllerName(),
140 domainControllerName) ||
141 !Validator.equals(
142 ntlmManager.getServiceAccount(), serviceAccount) ||
143 !Validator.equals(
144 ntlmManager.getServicePassword(), servicePassword)) {
145
146 ntlmManager.setConfiguration(
147 domain, domainController, domainControllerName,
148 serviceAccount, servicePassword);
149 }
150 }
151
152 return ntlmManager;
153 }
154
155 protected String getPortalCacheKey(HttpServletRequest request) {
156 HttpSession session = request.getSession(false);
157
158 if (session == null) {
159 return request.getRemoteAddr();
160 }
161
162 return session.getId();
163 }
164
165 @Override
166 protected void processFilter(
167 HttpServletRequest request, HttpServletResponse response,
168 FilterChain filterChain)
169 throws Exception {
170
171
172
173
174
175 HttpSession session = request.getSession(false);
176
177 long companyId = PortalInstances.getCompanyId(request);
178
179 String authorization = GetterUtil.getString(
180 request.getHeader(HttpHeaders.AUTHORIZATION));
181
182 if (authorization.startsWith("NTLM")) {
183 NtlmManager ntlmManager = getNtlmManager(companyId);
184
185 String portalCacheKey = getPortalCacheKey(request);
186
187 byte[] src = Base64.decode(authorization.substring(5));
188
189 if (src[8] == 1) {
190 byte[] serverChallenge = new byte[8];
191
192 _secureRandom.nextBytes(serverChallenge);
193
194 byte[] challengeMessage = ntlmManager.negotiate(
195 src, serverChallenge);
196
197 authorization = Base64.encode(challengeMessage);
198
199 response.setContentLength(0);
200 response.setHeader(
201 HttpHeaders.WWW_AUTHENTICATE, "NTLM " + authorization);
202 response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
203
204 response.flushBuffer();
205
206 _portalCache.put(portalCacheKey, serverChallenge);
207
208
209
210
211 return;
212 }
213
214 byte[] serverChallenge = _portalCache.get(portalCacheKey);
215
216 if (serverChallenge == null) {
217 response.setContentLength(0);
218 response.setHeader(HttpHeaders.WWW_AUTHENTICATE, "NTLM");
219 response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
220
221 response.flushBuffer();
222
223 return;
224 }
225
226 NtlmUserAccount ntlmUserAccount = null;
227
228 try {
229 ntlmUserAccount = ntlmManager.authenticate(
230 src, serverChallenge);
231 }
232 catch (Exception e) {
233 if (_log.isErrorEnabled()) {
234 _log.error("Unable to perform NTLM authentication", e);
235 }
236 }
237 finally {
238 _portalCache.remove(portalCacheKey);
239 }
240
241 if (ntlmUserAccount == null) {
242 response.setContentLength(0);
243 response.setHeader(HttpHeaders.WWW_AUTHENTICATE, "NTLM");
244 response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
245
246 response.flushBuffer();
247
248 return;
249 }
250
251 if (_log.isDebugEnabled()) {
252 _log.debug("NTLM remote user " + ntlmUserAccount.getUserName());
253 }
254
255 request.setAttribute(
256 WebKeys.NTLM_REMOTE_USER, ntlmUserAccount.getUserName());
257
258 if (session != null) {
259 session.setAttribute(
260 WebKeys.NTLM_USER_ACCOUNT, ntlmUserAccount);
261 }
262 }
263
264 String path = request.getPathInfo();
265
266 if ((path != null) && path.endsWith("/login")) {
267 NtlmUserAccount ntlmUserAccount = null;
268
269 if (session != null) {
270 ntlmUserAccount = (NtlmUserAccount)session.getAttribute(
271 WebKeys.NTLM_USER_ACCOUNT);
272 }
273
274 if (ntlmUserAccount == null) {
275 response.setContentLength(0);
276 response.setHeader(HttpHeaders.WWW_AUTHENTICATE, "NTLM");
277 response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
278
279 response.flushBuffer();
280
281 return;
282 }
283 else {
284 request.setAttribute(
285 WebKeys.NTLM_REMOTE_USER, ntlmUserAccount.getUserName());
286 }
287 }
288
289 processFilter(NtlmPostFilter.class, request, response, filterChain);
290 }
291
292 private static Log _log = LogFactoryUtil.getLog(NtlmFilter.class);
293
294 private Map<Long, NtlmManager> _ntlmManagers =
295 new ConcurrentHashMap<Long, NtlmManager>();
296 private PortalCache<String, byte[]> _portalCache =
297 SingleVMPoolUtil.getCache(NtlmFilter.class.getName());
298 private SecureRandom _secureRandom = new SecureRandom();
299
300 }