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