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 @Override
156 protected void processFilter(
157 HttpServletRequest request, HttpServletResponse response,
158 FilterChain filterChain)
159 throws Exception {
160
161
162
163
164
165 HttpSession session = request.getSession(false);
166
167 long companyId = PortalInstances.getCompanyId(request);
168
169 String authorization = GetterUtil.getString(
170 request.getHeader(HttpHeaders.AUTHORIZATION));
171
172 if (authorization.startsWith("NTLM")) {
173 NtlmManager ntlmManager = getNtlmManager(companyId);
174
175 byte[] src = Base64.decode(authorization.substring(5));
176
177 if (src[8] == 1) {
178 byte[] serverChallenge = new byte[8];
179
180 _secureRandom.nextBytes(serverChallenge);
181
182 byte[] challengeMessage = ntlmManager.negotiate(
183 src, serverChallenge);
184
185 authorization = Base64.encode(challengeMessage);
186
187 response.setContentLength(0);
188 response.setHeader(
189 HttpHeaders.WWW_AUTHENTICATE, "NTLM " + authorization);
190 response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
191
192 response.flushBuffer();
193
194 _portalCache.put(request.getRemoteAddr(), serverChallenge);
195
196
197
198
199 return;
200 }
201
202 byte[] serverChallenge = _portalCache.get(request.getRemoteAddr());
203
204 if (serverChallenge == null) {
205 response.setContentLength(0);
206 response.setHeader(HttpHeaders.WWW_AUTHENTICATE, "NTLM");
207 response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
208
209 response.flushBuffer();
210
211 return;
212 }
213
214 NtlmUserAccount ntlmUserAccount = null;
215
216 try {
217 ntlmUserAccount = ntlmManager.authenticate(
218 src, serverChallenge);
219 }
220 catch (Exception e) {
221 if (_log.isErrorEnabled()) {
222 _log.error("Unable to perform NTLM authentication", e);
223 }
224 }
225 finally {
226 _portalCache.remove(request.getRemoteAddr());
227 }
228
229 if (ntlmUserAccount == null) {
230 response.setContentLength(0);
231 response.setHeader(HttpHeaders.WWW_AUTHENTICATE, "NTLM");
232 response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
233
234 response.flushBuffer();
235
236 return;
237 }
238
239 if (_log.isDebugEnabled()) {
240 _log.debug("NTLM remote user " + ntlmUserAccount.getUserName());
241 }
242
243 request.setAttribute(
244 WebKeys.NTLM_REMOTE_USER, ntlmUserAccount.getUserName());
245
246 if (session != null) {
247 session.setAttribute(
248 WebKeys.NTLM_USER_ACCOUNT, ntlmUserAccount);
249 }
250 }
251
252 String path = request.getPathInfo();
253
254 if ((path != null) && path.endsWith("/login")) {
255 NtlmUserAccount ntlmUserAccount = null;
256
257 if (session != null) {
258 ntlmUserAccount = (NtlmUserAccount)session.getAttribute(
259 WebKeys.NTLM_USER_ACCOUNT);
260 }
261
262 if (ntlmUserAccount == null) {
263 response.setContentLength(0);
264 response.setHeader(HttpHeaders.WWW_AUTHENTICATE, "NTLM");
265 response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
266
267 response.flushBuffer();
268
269 return;
270 }
271 }
272
273 processFilter(NtlmPostFilter.class, request, response, filterChain);
274 }
275
276 private static Log _log = LogFactoryUtil.getLog(NtlmFilter.class);
277
278 private Map<Long, NtlmManager> _ntlmManagers =
279 new ConcurrentHashMap<Long, NtlmManager>();
280 private PortalCache<String, byte[]> _portalCache =
281 SingleVMPoolUtil.getCache(NtlmFilter.class.getName());
282 private SecureRandom _secureRandom = new SecureRandom();
283
284 }