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 super.init(filterConfig);
069
070 try {
071 NtlmHttpFilter ntlmFilter = new NtlmHttpFilter();
072
073 ntlmFilter.init(filterConfig);
074
075 Properties properties = PropsUtil.getProperties("jcifs.", false);
076
077 Iterator<Map.Entry<Object, Object>> itr =
078 properties.entrySet().iterator();
079
080 while (itr.hasNext()) {
081 Map.Entry<Object, Object> entry = itr.next();
082
083 String key = (String)entry.getKey();
084 String value = (String)entry.getValue();
085
086 Config.setProperty(key, value);
087 }
088 }
089 catch (Exception e) {
090 _log.error(e, e);
091 }
092 }
093
094 @Override
095 public boolean isFilterEnabled(
096 HttpServletRequest request, HttpServletResponse response) {
097
098 try {
099 long companyId = PortalInstances.getCompanyId(request);
100
101 if (BrowserSnifferUtil.isIe(request) &&
102 AuthSettingsUtil.isNtlmEnabled(companyId)) {
103
104 return true;
105 }
106 }
107 catch (Exception e) {
108 _log.error(e, e);
109 }
110
111 return false;
112 }
113
114 @Override
115 protected Log getLog() {
116 return _log;
117 }
118
119 protected NtlmManager getNtlmManager(long companyId)
120 throws SystemException {
121
122 String domain = PrefsPropsUtil.getString(
123 companyId, PropsKeys.NTLM_DOMAIN, PropsValues.NTLM_DOMAIN);
124 String domainController = PrefsPropsUtil.getString(
125 companyId, PropsKeys.NTLM_DOMAIN_CONTROLLER,
126 PropsValues.NTLM_DOMAIN_CONTROLLER);
127 String domainControllerName = PrefsPropsUtil.getString(
128 companyId, PropsKeys.NTLM_DOMAIN_CONTROLLER_NAME,
129 PropsValues.NTLM_DOMAIN_CONTROLLER_NAME);
130 String serviceAccount = PrefsPropsUtil.getString(
131 companyId, PropsKeys.NTLM_SERVICE_ACCOUNT,
132 PropsValues.NTLM_SERVICE_ACCOUNT);
133 String servicePassword = PrefsPropsUtil.getString(
134 companyId, PropsKeys.NTLM_SERVICE_PASSWORD,
135 PropsValues.NTLM_SERVICE_PASSWORD);
136
137 NtlmManager ntlmManager = _ntlmManagers.get(companyId);
138
139 if (ntlmManager == null) {
140 ntlmManager = new NtlmManager(
141 domain, domainController, domainControllerName, serviceAccount,
142 servicePassword);
143
144 _ntlmManagers.put(companyId, ntlmManager);
145 }
146 else {
147 if (!Validator.equals(ntlmManager.getDomain(), domain) ||
148 !Validator.equals(
149 ntlmManager.getDomainController(), domainController) ||
150 !Validator.equals(
151 ntlmManager.getDomainControllerName(),
152 domainControllerName) ||
153 !Validator.equals(
154 ntlmManager.getServiceAccount(), serviceAccount) ||
155 !Validator.equals(
156 ntlmManager.getServicePassword(), servicePassword)) {
157
158 ntlmManager.setConfiguration(
159 domain, domainController, domainControllerName,
160 serviceAccount, servicePassword);
161 }
162 }
163
164 return ntlmManager;
165 }
166
167 @Override
168 protected void processFilter(
169 HttpServletRequest request, HttpServletResponse response,
170 FilterChain filterChain)
171 throws Exception {
172
173
174
175
176
177 HttpSession session = request.getSession(false);
178
179 long companyId = PortalInstances.getCompanyId(request);
180
181 String authorization = GetterUtil.getString(
182 request.getHeader(HttpHeaders.AUTHORIZATION));
183
184 if (authorization.startsWith("NTLM")) {
185 NtlmManager ntlmManager = getNtlmManager(companyId);
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(request.getRemoteAddr(), serverChallenge);
207
208
209
210
211 return;
212 }
213
214 byte[] serverChallenge = (byte[])_portalCache.get(
215 request.getRemoteAddr());
216
217 if (serverChallenge == null) {
218 response.setContentLength(0);
219 response.setHeader(HttpHeaders.WWW_AUTHENTICATE, "NTLM");
220 response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
221
222 response.flushBuffer();
223
224 return;
225 }
226
227 NtlmUserAccount ntlmUserAccount = null;
228
229 try {
230 ntlmUserAccount = ntlmManager.authenticate(
231 src, serverChallenge);
232 }
233 catch (Exception e) {
234 if (_log.isErrorEnabled()) {
235 _log.error("Unable to perform NTLM authentication", e);
236 }
237 }
238 finally {
239 _portalCache.remove(request.getRemoteAddr());
240 }
241
242 if (ntlmUserAccount == null) {
243 response.setContentLength(0);
244 response.setHeader(HttpHeaders.WWW_AUTHENTICATE, "NTLM");
245 response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
246
247 response.flushBuffer();
248
249 return;
250 }
251
252 if (_log.isDebugEnabled()) {
253 _log.debug("NTLM remote user " + ntlmUserAccount.getUserName());
254 }
255
256 request.setAttribute(
257 WebKeys.NTLM_REMOTE_USER, ntlmUserAccount.getUserName());
258
259 if (session != null) {
260 session.setAttribute(
261 WebKeys.NTLM_USER_ACCOUNT, ntlmUserAccount);
262 }
263 }
264
265 String path = request.getPathInfo();
266
267 if ((path != null) && path.endsWith("/login")) {
268 NtlmUserAccount ntlmUserAccount = null;
269
270 if (session != null) {
271 ntlmUserAccount = (NtlmUserAccount)session.getAttribute(
272 WebKeys.NTLM_USER_ACCOUNT);
273 }
274
275 if (ntlmUserAccount == null) {
276 response.setContentLength(0);
277 response.setHeader(HttpHeaders.WWW_AUTHENTICATE, "NTLM");
278 response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
279
280 response.flushBuffer();
281
282 return;
283 }
284 }
285
286 processFilter(NtlmPostFilter.class, request, response, filterChain);
287 }
288
289 private static Log _log = LogFactoryUtil.getLog(NtlmFilter.class);
290
291 private Map<Long, NtlmManager> _ntlmManagers =
292 new ConcurrentHashMap<Long, NtlmManager>();
293 private PortalCache _portalCache = SingleVMPoolUtil.getCache(
294 NtlmFilter.class.getName());
295 private SecureRandom _secureRandom = new SecureRandom();
296
297 }