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.http.NtlmHttpFilter;
052
053 import jcifs.util.Base64;
054
055
063 public class NtlmFilter extends BasePortalFilter {
064
065 @Override
066 public void init(FilterConfig filterConfig) {
067 super.init(filterConfig);
068
069 try {
070 NtlmHttpFilter ntlmFilter = new NtlmHttpFilter();
071
072 ntlmFilter.init(filterConfig);
073
074 Properties properties = PropsUtil.getProperties("jcifs.", false);
075
076 for (Map.Entry<Object, Object> entry : properties.entrySet()) {
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 = _portalCache.get(request.getRemoteAddr());
209
210 if (serverChallenge == null) {
211 response.setContentLength(0);
212 response.setHeader(HttpHeaders.WWW_AUTHENTICATE, "NTLM");
213 response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
214
215 response.flushBuffer();
216
217 return;
218 }
219
220 NtlmUserAccount ntlmUserAccount = null;
221
222 try {
223 ntlmUserAccount = ntlmManager.authenticate(
224 src, serverChallenge);
225 }
226 catch (Exception e) {
227 if (_log.isErrorEnabled()) {
228 _log.error("Unable to perform NTLM authentication", e);
229 }
230 }
231 finally {
232 _portalCache.remove(request.getRemoteAddr());
233 }
234
235 if (ntlmUserAccount == null) {
236 response.setContentLength(0);
237 response.setHeader(HttpHeaders.WWW_AUTHENTICATE, "NTLM");
238 response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
239
240 response.flushBuffer();
241
242 return;
243 }
244
245 if (_log.isDebugEnabled()) {
246 _log.debug("NTLM remote user " + ntlmUserAccount.getUserName());
247 }
248
249 request.setAttribute(
250 WebKeys.NTLM_REMOTE_USER, ntlmUserAccount.getUserName());
251
252 if (session != null) {
253 session.setAttribute(
254 WebKeys.NTLM_USER_ACCOUNT, ntlmUserAccount);
255 }
256 }
257
258 String path = request.getPathInfo();
259
260 if ((path != null) && path.endsWith("/login")) {
261 NtlmUserAccount ntlmUserAccount = null;
262
263 if (session != null) {
264 ntlmUserAccount = (NtlmUserAccount)session.getAttribute(
265 WebKeys.NTLM_USER_ACCOUNT);
266 }
267
268 if (ntlmUserAccount == null) {
269 response.setContentLength(0);
270 response.setHeader(HttpHeaders.WWW_AUTHENTICATE, "NTLM");
271 response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
272
273 response.flushBuffer();
274
275 return;
276 }
277 }
278
279 processFilter(NtlmPostFilter.class, request, response, filterChain);
280 }
281
282 private static Log _log = LogFactoryUtil.getLog(NtlmFilter.class);
283
284 private Map<Long, NtlmManager> _ntlmManagers =
285 new ConcurrentHashMap<Long, NtlmManager>();
286 private PortalCache<String, byte[]> _portalCache =
287 SingleVMPoolUtil.getCache(NtlmFilter.class.getName());
288 private SecureRandom _secureRandom = new SecureRandom();
289
290 }