1
22
23 package com.liferay.portal.servlet.filters.sso.ntlm;
24
25 import com.liferay.portal.kernel.log.Log;
26 import com.liferay.portal.kernel.log.LogFactoryUtil;
27 import com.liferay.portal.kernel.servlet.HttpHeaders;
28 import com.liferay.portal.kernel.util.GetterUtil;
29 import com.liferay.portal.kernel.util.PropsKeys;
30 import com.liferay.portal.kernel.util.StringPool;
31 import com.liferay.portal.kernel.util.Validator;
32 import com.liferay.portal.security.ldap.PortalLDAPUtil;
33 import com.liferay.portal.servlet.filters.BasePortalFilter;
34 import com.liferay.portal.util.PortalInstances;
35 import com.liferay.portal.util.PrefsPropsUtil;
36 import com.liferay.portal.util.PropsUtil;
37 import com.liferay.portal.util.PropsValues;
38 import com.liferay.portal.util.WebKeys;
39 import com.liferay.util.servlet.filters.DynamicFilterConfig;
40
41 import java.util.Iterator;
42 import java.util.Map;
43 import java.util.Properties;
44
45 import javax.servlet.FilterChain;
46 import javax.servlet.FilterConfig;
47 import javax.servlet.http.HttpServletRequest;
48 import javax.servlet.http.HttpServletResponse;
49 import javax.servlet.http.HttpSession;
50
51 import jcifs.Config;
52 import jcifs.UniAddress;
53
54 import jcifs.http.NtlmHttpFilter;
55 import jcifs.http.NtlmSsp;
56
57 import jcifs.ntlmssp.Type1Message;
58 import jcifs.ntlmssp.Type2Message;
59
60 import jcifs.smb.NtlmPasswordAuthentication;
61 import jcifs.smb.SmbSession;
62
63 import jcifs.util.Base64;
64
65
73 public class NtlmFilter extends BasePortalFilter {
74
75 public void init(FilterConfig filterConfig) {
76 try {
77 NtlmHttpFilter ntlmFilter = new NtlmHttpFilter();
78
79 ntlmFilter.init(filterConfig);
80
81 Properties properties = PropsUtil.getProperties("jcifs.", false);
82
83 Iterator<Map.Entry<Object, Object>> itr =
84 properties.entrySet().iterator();
85
86 while (itr.hasNext()) {
87 Map.Entry<Object, Object> entry = itr.next();
88
89 String key = (String)entry.getKey();
90 String value = (String)entry.getValue();
91
92 Config.setProperty(key, value);
93 }
94 }
95 catch (Exception e) {
96 _log.error(e, e);
97 }
98
99 _filterConfig = new DynamicFilterConfig(filterConfig);
100 }
101
102 protected Log getLog() {
103 return _log;
104 }
105
106 protected void processFilter(
107 HttpServletRequest request, HttpServletResponse response,
108 FilterChain filterChain)
109 throws Exception {
110
111 long companyId = PortalInstances.getCompanyId(request);
112
113 if (PortalLDAPUtil.isNtlmEnabled(companyId)) {
114 String domainController = _filterConfig.getInitParameter(
115 "jcifs.http.domainController");
116 String domain = _filterConfig.getInitParameter(
117 "jcifs.smb.client.domain");
118
119 String preferencesDomainController = PrefsPropsUtil.getString(
120 companyId, PropsKeys.NTLM_DOMAIN_CONTROLLER,
121 PropsValues.NTLM_DOMAIN_CONTROLLER);
122 String preferencesDomain = PrefsPropsUtil.getString(
123 companyId, PropsKeys.NTLM_DOMAIN, PropsValues.NTLM_DOMAIN);
124
125 if (!Validator.equals(
126 domainController, preferencesDomainController) ||
127 !Validator.equals(domain, preferencesDomain)) {
128
129 domainController = preferencesDomainController;
130 domain = preferencesDomain;
131
132 _filterConfig.addInitParameter(
133 "jcifs.http.domainController", domainController);
134 _filterConfig.addInitParameter(
135 "jcifs.smb.client.domain", domain);
136
137 super.init(_filterConfig);
138 }
139
140 if (_log.isDebugEnabled()) {
141 _log.debug("Host " + domainController);
142 _log.debug("Domain " + domain);
143 }
144
145
150 String authorization = GetterUtil.getString(
151 request.getHeader(HttpHeaders.AUTHORIZATION));
152
153 if (authorization.startsWith("NTLM")) {
154 byte[] src = Base64.decode(authorization.substring(5));
155
156 if (src[8] == 1) {
157 UniAddress dc = UniAddress.getByName(
158 domainController, true);
159
160 byte[] challenge = SmbSession.getChallenge(dc);
161
162 Type1Message type1 = new Type1Message(src);
163 Type2Message type2 = new Type2Message(
164 type1, challenge, null);
165
166 authorization = Base64.encode(type2.toByteArray());
167
168 response.setHeader(
169 HttpHeaders.WWW_AUTHENTICATE, "NTLM " + authorization);
170 response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
171 response.setContentLength(0);
172
173 response.flushBuffer();
174
175
178 return;
179 }
180 }
181
182 String path = request.getPathInfo();
183
184 if ((path != null) && path.endsWith("/login")) {
185 NtlmPasswordAuthentication ntlm = negotiate(
186 request, response, false);
187
188 if (ntlm == null) {
189 return;
190 }
191
192 String remoteUser = ntlm.getName();
193
194 int pos = remoteUser.indexOf(StringPool.BACK_SLASH);
195
196 if (pos != -1) {
197 remoteUser = remoteUser.substring(pos + 1);
198 }
199
200 if (_log.isDebugEnabled()) {
201 _log.debug("NTLM remote user " + remoteUser);
202 }
203
204 request.setAttribute(WebKeys.NTLM_REMOTE_USER, remoteUser);
205 }
206 }
207
208 processFilter(NtlmPostFilter.class, request, response, filterChain);
209 }
210
211 protected NtlmPasswordAuthentication negotiate(
212 HttpServletRequest request, HttpServletResponse response,
213 boolean skipAuthentication)
214 throws Exception {
215
216 NtlmPasswordAuthentication ntlm = null;
217
218 HttpSession session = request.getSession(false);
219
220 String authorization = GetterUtil.getString(
221 request.getHeader(HttpHeaders.AUTHORIZATION));
222
223 if (_log.isDebugEnabled()) {
224 _log.debug("Authorization header " + authorization);
225 }
226
227 if (authorization.startsWith("NTLM ")) {
228 String domainController = _filterConfig.getInitParameter(
229 "jcifs.http.domainController");
230
231 UniAddress uniAddress = UniAddress.getByName(
232 domainController, true);
233
234 if (_log.isDebugEnabled()) {
235 _log.debug("Address " + uniAddress);
236 }
237
238 byte[] challenge = SmbSession.getChallenge(uniAddress);
239
240 ntlm = NtlmSsp.authenticate(request, response, challenge);
241
242 try {
243 SmbSession.logon(uniAddress, ntlm);
244 }
245 catch (Exception e) {
246 response.setHeader(HttpHeaders.WWW_AUTHENTICATE, "NTLM");
247 response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
248 response.setContentLength(0);
249
250 response.flushBuffer();
251
252 return null;
253 }
254
255 session.setAttribute("NtlmHttpAuth", ntlm);
256 }
257 else {
258 if (session != null) {
259 ntlm = (NtlmPasswordAuthentication)session.getAttribute(
260 "NtlmHttpAuth");
261 }
262
263 if (ntlm == null) {
264 response.setHeader(HttpHeaders.WWW_AUTHENTICATE, "NTLM");
265 response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
266 response.setContentLength(0);
267
268 response.flushBuffer();
269
270 return null;
271 }
272 }
273
274 if (_log.isDebugEnabled()) {
275 _log.debug("Password authentication " + ntlm);
276 }
277
278 return ntlm;
279 }
280
281 private static Log _log = LogFactoryUtil.getLog(NtlmFilter.class);
282
283 private DynamicFilterConfig _filterConfig;
284
285 }