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.Iterator;
040 import java.util.Map;
041 import java.util.Properties;
042 import java.util.concurrent.ConcurrentHashMap;
043
044 import javax.servlet.FilterChain;
045 import javax.servlet.FilterConfig;
046 import javax.servlet.http.HttpServletRequest;
047 import javax.servlet.http.HttpServletResponse;
048 import javax.servlet.http.HttpSession;
049
050 import jcifs.Config;
051
052 import jcifs.http.NtlmHttpFilter;
053
054 import jcifs.util.Base64;
055
056
064 public class NtlmFilter extends BasePortalFilter {
065
066 @Override
067 public void init(FilterConfig filterConfig) {
068 try {
069 NtlmHttpFilter ntlmFilter = new NtlmHttpFilter();
070
071 ntlmFilter.init(filterConfig);
072
073 Properties properties = PropsUtil.getProperties("jcifs.", false);
074
075 Iterator<Map.Entry<Object, Object>> itr =
076 properties.entrySet().iterator();
077
078 while (itr.hasNext()) {
079 Map.Entry<Object, Object> entry = itr.next();
080
081 String key = (String)entry.getKey();
082 String value = (String)entry.getValue();
083
084 Config.setProperty(key, value);
085 }
086 }
087 catch (Exception e) {
088 _log.error(e, e);
089 }
090 }
091
092 @Override
093 public boolean isFilterEnabled(
094 HttpServletRequest request, HttpServletResponse response) {
095
096 try {
097 long companyId = PortalInstances.getCompanyId(request);
098
099 if (BrowserSnifferUtil.isIe(request) &&
100 AuthSettingsUtil.isNtlmEnabled(companyId)) {
101
102 return true;
103 }
104 }
105 catch (Exception e) {
106 _log.error(e, e);
107 }
108
109 return false;
110 }
111
112 @Override
113 protected Log getLog() {
114 return _log;
115 }
116
117 protected NtlmManager getNtlmManager(long companyId)
118 throws SystemException {
119
120 String domain = PrefsPropsUtil.getString(
121 companyId, PropsKeys.NTLM_DOMAIN, PropsValues.NTLM_DOMAIN);
122 String domainController = PrefsPropsUtil.getString(
123 companyId, PropsKeys.NTLM_DOMAIN_CONTROLLER,
124 PropsValues.NTLM_DOMAIN_CONTROLLER);
125 String domainControllerName = PrefsPropsUtil.getString(
126 companyId, PropsKeys.NTLM_DOMAIN_CONTROLLER_NAME,
127 PropsValues.NTLM_DOMAIN_CONTROLLER_NAME);
128 String serviceAccount = PrefsPropsUtil.getString(
129 companyId, PropsKeys.NTLM_SERVICE_ACCOUNT,
130 PropsValues.NTLM_SERVICE_ACCOUNT);
131 String servicePassword = PrefsPropsUtil.getString(
132 companyId, PropsKeys.NTLM_SERVICE_PASSWORD,
133 PropsValues.NTLM_SERVICE_PASSWORD);
134
135 NtlmManager ntlmManager = _ntlmManagers.get(companyId);
136
137 if (ntlmManager == null) {
138 ntlmManager = new NtlmManager(
139 domain, domainController, domainControllerName, serviceAccount,
140 servicePassword);
141
142 _ntlmManagers.put(companyId, ntlmManager);
143 }
144 else {
145 if (!Validator.equals(ntlmManager.getDomain(), domain) ||
146 !Validator.equals(
147 ntlmManager.getDomainController(), domainController) ||
148 !Validator.equals(
149 ntlmManager.getDomainControllerName(),
150 domainControllerName) ||
151 !Validator.equals(
152 ntlmManager.getServiceAccount(), serviceAccount) ||
153 !Validator.equals(
154 ntlmManager.getServicePassword(), servicePassword)) {
155
156 ntlmManager.setConfiguration(
157 domain, domainController, domainControllerName,
158 serviceAccount, servicePassword);
159 }
160 }
161
162 return ntlmManager;
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 byte[] src = Base64.decode(authorization.substring(5));
186
187 if (src[8] == 1) {
188 byte[] serverChallenge = new byte[8];
189
190 _secureRandom.nextBytes(serverChallenge);
191
192 byte[] challengeMessage = ntlmManager.negotiate(
193 src, serverChallenge);
194
195 authorization = Base64.encode(challengeMessage);
196
197 response.setContentLength(0);
198 response.setHeader(
199 HttpHeaders.WWW_AUTHENTICATE, "NTLM " + authorization);
200 response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
201
202 response.flushBuffer();
203
204 _portalCache.put(request.getRemoteAddr(), serverChallenge);
205
206
207
208
209 return;
210 }
211
212 byte[] serverChallenge = (byte[])_portalCache.get(
213 request.getRemoteAddr());
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(request.getRemoteAddr());
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 }
283
284 processFilter(NtlmPostFilter.class, request, response, filterChain);
285 }
286
287 private static Log _log = LogFactoryUtil.getLog(NtlmFilter.class);
288
289 private Map<Long, NtlmManager> _ntlmManagers =
290 new ConcurrentHashMap<Long, NtlmManager>();
291 private PortalCache _portalCache = SingleVMPoolUtil.getCache(
292 NtlmFilter.class.getName());
293 private SecureRandom _secureRandom = new SecureRandom();
294
295 }