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