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