1
14
15 package com.liferay.portal.servlet.filters.sso.ntlm;
16
17 import com.liferay.portal.SystemException;
18 import com.liferay.portal.kernel.cache.PortalCache;
19 import com.liferay.portal.kernel.cache.SingleVMPoolUtil;
20 import com.liferay.portal.kernel.log.Log;
21 import com.liferay.portal.kernel.log.LogFactoryUtil;
22 import com.liferay.portal.kernel.servlet.HttpHeaders;
23 import com.liferay.portal.kernel.util.GetterUtil;
24 import com.liferay.portal.kernel.util.PropsKeys;
25 import com.liferay.portal.kernel.util.Validator;
26 import com.liferay.portal.security.auth.AuthSettingsUtil;
27 import com.liferay.portal.security.ntlm.NtlmManager;
28 import com.liferay.portal.security.ntlm.NtlmUserAccount;
29 import com.liferay.portal.servlet.filters.BasePortalFilter;
30 import com.liferay.portal.util.PortalInstances;
31 import com.liferay.portal.util.PrefsPropsUtil;
32 import com.liferay.portal.util.PropsUtil;
33 import com.liferay.portal.util.PropsValues;
34 import com.liferay.portal.util.WebKeys;
35
36 import java.security.SecureRandom;
37
38 import java.util.Iterator;
39 import java.util.Map;
40 import java.util.Properties;
41 import java.util.concurrent.ConcurrentHashMap;
42
43 import javax.servlet.FilterChain;
44 import javax.servlet.FilterConfig;
45 import javax.servlet.http.HttpServletRequest;
46 import javax.servlet.http.HttpServletResponse;
47 import javax.servlet.http.HttpSession;
48
49 import jcifs.Config;
50
51 import jcifs.http.NtlmHttpFilter;
52
53 import jcifs.util.Base64;
54
55
65 public class NtlmFilter extends BasePortalFilter {
66
67 public void init(FilterConfig filterConfig) {
68 try {
69 NtlmHttpFilter ntlmFilter = new NtlmHttpFilter();
70
71 ntlmFilter.init(filterConfig);
72
73 Properties properties = PropsUtil.getProperties("jcifs.", false);
74
75 Iterator<Map.Entry<Object, Object>> itr =
76 properties.entrySet().iterator();
77
78 while (itr.hasNext()) {
79 Map.Entry<Object, Object> entry = itr.next();
80
81 String key = (String)entry.getKey();
82 String value = (String)entry.getValue();
83
84 Config.setProperty(key, value);
85 }
86 }
87 catch (Exception e) {
88 _log.error(e, e);
89 }
90 }
91
92 protected Log getLog() {
93 return _log;
94 }
95
96 protected NtlmManager getNtlmManager(long companyId)
97 throws SystemException {
98
99 String domain = PrefsPropsUtil.getString(
100 companyId, PropsKeys.NTLM_DOMAIN, PropsValues.NTLM_DOMAIN);
101 String domainController = PrefsPropsUtil.getString(
102 companyId, PropsKeys.NTLM_DOMAIN_CONTROLLER,
103 PropsValues.NTLM_DOMAIN_CONTROLLER);
104 String domainControllerName = PrefsPropsUtil.getString(
105 companyId, PropsKeys.NTLM_DOMAIN_CONTROLLER_NAME,
106 PropsValues.NTLM_DOMAIN_CONTROLLER_NAME);
107 String serviceAccount = PrefsPropsUtil.getString(
108 companyId, PropsKeys.NTLM_SERVICE_ACCOUNT,
109 PropsValues.NTLM_SERVICE_ACCOUNT);
110 String servicePassword = PrefsPropsUtil.getString(
111 companyId, PropsKeys.NTLM_SERVICE_PASSWORD,
112 PropsValues.NTLM_SERVICE_PASSWORD);
113
114 NtlmManager ntlmManager = _ntlmManagers.get(companyId);
115
116 if (ntlmManager == null) {
117 ntlmManager = new NtlmManager(
118 domain, domainController, domainControllerName, serviceAccount,
119 servicePassword);
120
121 _ntlmManagers.put(companyId, ntlmManager);
122 }
123 else {
124 if (!Validator.equals(ntlmManager.getDomain(), domain) ||
125 !Validator.equals(
126 ntlmManager.getDomainController(), domainController) ||
127 !Validator.equals(
128 ntlmManager.getDomainControllerName(),
129 domainControllerName) ||
130 !Validator.equals(
131 ntlmManager.getServiceAccount(), serviceAccount) ||
132 !Validator.equals(
133 ntlmManager.getServicePassword(), servicePassword)) {
134
135 ntlmManager.setConfiguration(
136 domain, domainController, domainControllerName,
137 serviceAccount, servicePassword);
138 }
139 }
140
141 return ntlmManager;
142 }
143
144 protected void processFilter(
145 HttpServletRequest request, HttpServletResponse response,
146 FilterChain filterChain)
147 throws Exception {
148
149 long companyId = PortalInstances.getCompanyId(request);
150
151 if (AuthSettingsUtil.isNtlmEnabled(companyId)) {
152
153
158 HttpSession session = request.getSession(false);
159
160 String authorization = GetterUtil.getString(
161 request.getHeader(HttpHeaders.AUTHORIZATION));
162
163 if (authorization.startsWith("NTLM")) {
164 NtlmManager ntlmManager = getNtlmManager(companyId);
165
166 byte[] src = Base64.decode(authorization.substring(5));
167
168 if (src[8] == 1) {
169 byte[] serverChallenge = new byte[8];
170
171 _secureRandom.nextBytes(serverChallenge);
172
173 byte[] challengeMessage = ntlmManager.negotiate(
174 src, serverChallenge);
175
176 authorization = Base64.encode(challengeMessage);
177
178 response.setHeader(
179 HttpHeaders.WWW_AUTHENTICATE, "NTLM " + authorization);
180 response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
181 response.setContentLength(0);
182
183 response.flushBuffer();
184
185 _serverChallenges.put(
186 request.getRemoteAddr(), serverChallenge);
187
188
191 return;
192 }
193 else {
194 byte[] serverChallenge = (byte[])_serverChallenges.get(
195 request.getRemoteAddr());
196
197 if (serverChallenge == null) {
198 response.setHeader(
199 HttpHeaders.WWW_AUTHENTICATE, "NTLM");
200 response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
201 response.setContentLength(0);
202
203 response.flushBuffer();
204
205 return;
206 }
207
208 NtlmUserAccount ntlmUserAccount = null;
209
210 try {
211 ntlmUserAccount = ntlmManager.authenticate(
212 src, serverChallenge);
213 }
214 catch (Exception e) {
215 if (_log.isErrorEnabled()) {
216 _log.error(
217 "Unable to perform NTLM authentication", e);
218 }
219 }
220 finally {
221 _serverChallenges.remove(request.getRemoteAddr());
222 }
223
224 if (ntlmUserAccount == null) {
225 response.setHeader(
226 HttpHeaders.WWW_AUTHENTICATE, "NTLM");
227 response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
228 response.setContentLength(0);
229
230 response.flushBuffer();
231
232 return;
233 }
234
235 if (_log.isDebugEnabled()) {
236 _log.debug(
237 "NTLM remote user " +
238 ntlmUserAccount.getUserName());
239 }
240
241 request.setAttribute(
242 WebKeys.NTLM_REMOTE_USER,
243 ntlmUserAccount.getUserName());
244
245 if (session != null) {
246 session.setAttribute(
247 WebKeys.NTLM_USER_ACCOUNT, ntlmUserAccount);
248 }
249 }
250 }
251
252 String path = request.getPathInfo();
253
254 if ((path != null) && path.endsWith("/login")) {
255 NtlmUserAccount ntlmUserAccount = null;
256
257 if (session != null) {
258 ntlmUserAccount = (NtlmUserAccount)session.getAttribute(
259 WebKeys.NTLM_USER_ACCOUNT);
260 }
261
262 if (ntlmUserAccount == null) {
263 response.setHeader(HttpHeaders.WWW_AUTHENTICATE, "NTLM");
264 response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
265 response.setContentLength(0);
266
267 response.flushBuffer();
268
269 return;
270 }
271 }
272 }
273
274 processFilter(NtlmPostFilter.class, request, response, filterChain);
275 }
276
277 private static Log _log = LogFactoryUtil.getLog(NtlmFilter.class);
278
279 private Map<Long, NtlmManager> _ntlmManagers =
280 new ConcurrentHashMap<Long, NtlmManager>();
281 private SecureRandom _secureRandom = new SecureRandom();
282 private PortalCache _serverChallenges = SingleVMPoolUtil.getCache(
283 NtlmFilter.class.getName());
284
285 }