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