001
014
015 package com.liferay.portal.servlet.filters.sso.opensso;
016
017 import com.liferay.portal.kernel.io.unsync.UnsyncBufferedReader;
018 import com.liferay.portal.kernel.log.Log;
019 import com.liferay.portal.kernel.log.LogFactoryUtil;
020 import com.liferay.portal.kernel.util.CookieKeys;
021 import com.liferay.portal.kernel.util.StringBundler;
022 import com.liferay.portal.kernel.util.StringPool;
023 import com.liferay.portal.kernel.util.StringUtil;
024 import com.liferay.portal.kernel.util.Validator;
025
026 import java.io.IOException;
027 import java.io.InputStream;
028 import java.io.InputStreamReader;
029 import java.io.OutputStreamWriter;
030
031 import java.net.HttpURLConnection;
032 import java.net.MalformedURLException;
033 import java.net.URL;
034
035 import java.util.ArrayList;
036 import java.util.HashMap;
037 import java.util.List;
038 import java.util.Map;
039 import java.util.concurrent.ConcurrentHashMap;
040
041 import javax.servlet.http.HttpServletRequest;
042
043
052 public class OpenSSOUtil {
053
054 public static Map<String, String> getAttributes(
055 HttpServletRequest request, String serviceUrl) {
056
057 return _instance._getAttributes(request, serviceUrl);
058 }
059
060 public static String getSubjectId(
061 HttpServletRequest request, String serviceUrl) {
062
063 return _instance._getSubjectId(request, serviceUrl);
064 }
065
066 public static boolean isAuthenticated(
067 HttpServletRequest request, String serviceUrl)
068 throws IOException {
069
070 return _instance._isAuthenticated(request, serviceUrl);
071 }
072
073 public static boolean isValidServiceUrl(String serviceUrl) {
074 return _instance._isValidServiceUrl(serviceUrl);
075 }
076
077 public static boolean isValidUrl(String url) {
078 return _instance._isValidUrl(url);
079 }
080
081 public static boolean isValidUrls(String[] urls) {
082 return _instance._isValidUrls(urls);
083 }
084
085 private OpenSSOUtil() {
086 }
087
088 private Map<String, String> _getAttributes(
089 HttpServletRequest request, String serviceUrl) {
090
091 Map<String, String> nameValues = new HashMap<String, String>();
092
093 String url = serviceUrl.concat(_GET_ATTRIBUTES);
094
095 try {
096 URL urlObj = new URL(url);
097
098 HttpURLConnection httpURLConnection =
099 (HttpURLConnection)urlObj.openConnection();
100
101 httpURLConnection.setDoOutput(true);
102 httpURLConnection.setRequestMethod("POST");
103 httpURLConnection.setRequestProperty(
104 "Content-type", "application/x-www-form-urlencoded");
105
106 String[] cookieNames = _getCookieNames(serviceUrl);
107
108 _setCookieProperty(request, httpURLConnection, cookieNames);
109
110 OutputStreamWriter osw = new OutputStreamWriter(
111 httpURLConnection.getOutputStream());
112
113 osw.write("dummy");
114
115 osw.flush();
116
117 int responseCode = httpURLConnection.getResponseCode();
118
119 if (responseCode == HttpURLConnection.HTTP_OK) {
120 InputStream inputStream =
121 (InputStream)httpURLConnection.getContent();
122
123 UnsyncBufferedReader unsyncBufferedReader =
124 new UnsyncBufferedReader(
125 new InputStreamReader(inputStream));
126
127 String line = null;
128
129 while ((line = unsyncBufferedReader.readLine()) != null) {
130 if (line.startsWith("userdetails.attribute.name=")) {
131 String name = line.replaceFirst(
132 "userdetails.attribute.name=", "");
133
134 line = unsyncBufferedReader.readLine();
135
136 if (line.startsWith("userdetails.attribute.value=")) {
137 String value = line.replaceFirst(
138 "userdetails.attribute.value=", "");
139
140 nameValues.put(name, value);
141 }
142 }
143 }
144 }
145 else if (_log.isDebugEnabled()) {
146 _log.debug("Attributes response code " + responseCode);
147 }
148 }
149 catch (MalformedURLException murle) {
150 _log.error(murle.getMessage());
151
152 if (_log.isDebugEnabled()) {
153 _log.debug(murle, murle);
154 }
155 }
156 catch (IOException ioe) {
157 _log.error(ioe.getMessage());
158
159 if (_log.isDebugEnabled()) {
160 _log.debug(ioe, ioe);
161 }
162 }
163
164 return nameValues;
165 }
166
167 private String[] _getCookieNames(String serviceUrl) {
168 String[] cookieNames = _cookieNamesMap.get(serviceUrl);
169
170 if (cookieNames != null) {
171 return cookieNames;
172 }
173
174 List<String> cookieNamesList = new ArrayList<String>();
175
176 try {
177 String cookieName = null;
178
179 String url = serviceUrl.concat(_GET_COOKIE_NAME);
180
181 URL urlObj = new URL(url);
182
183 HttpURLConnection httpURLConnection =
184 (HttpURLConnection)urlObj.openConnection();
185
186 InputStream inputStream =
187 (InputStream)httpURLConnection.getContent();
188
189 UnsyncBufferedReader unsyncBufferedReader =
190 new UnsyncBufferedReader(new InputStreamReader(inputStream));
191
192 int responseCode = httpURLConnection.getResponseCode();
193
194 if (responseCode != HttpURLConnection.HTTP_OK) {
195 if (_log.isDebugEnabled()) {
196 _log.debug(url + " has response code " + responseCode);
197 }
198 }
199 else {
200 String line = null;
201
202 while ((line = unsyncBufferedReader.readLine()) != null) {
203 if (line.startsWith("string=")) {
204 line = line.replaceFirst("string=", "");
205
206 cookieName = line;
207 }
208 }
209 }
210
211 url = serviceUrl.concat(_GET_COOKIE_NAMES);
212
213 urlObj = new URL(url);
214
215 httpURLConnection = (HttpURLConnection)urlObj.openConnection();
216
217 inputStream = (InputStream)httpURLConnection.getContent();
218
219 unsyncBufferedReader = new UnsyncBufferedReader(
220 new InputStreamReader(inputStream));
221
222 if (httpURLConnection.getResponseCode() !=
223 HttpURLConnection.HTTP_OK) {
224
225 if (_log.isDebugEnabled()) {
226 _log.debug(url + " has response code " + responseCode);
227 }
228 }
229 else {
230 String line = null;
231
232 while ((line = unsyncBufferedReader.readLine()) != null) {
233 if (line.startsWith("string=")) {
234 line = line.replaceFirst("string=", "");
235
236 if (cookieName.equals(line)) {
237 cookieNamesList.add(0, cookieName);
238 }
239 else {
240 cookieNamesList.add(line);
241 }
242 }
243 }
244 }
245 }
246 catch (IOException ioe) {
247 if (_log.isWarnEnabled()) {
248 _log.warn(ioe, ioe);
249 }
250 }
251
252 cookieNames = cookieNamesList.toArray(
253 new String[cookieNamesList.size()]);
254
255 if (cookieNames.length > 0) {
256 _cookieNamesMap.put(serviceUrl, cookieNames);
257 }
258
259 return cookieNames;
260 }
261
262 private String _getSubjectId(
263 HttpServletRequest request, String serviceUrl) {
264
265 String cookieName = _getCookieNames(serviceUrl)[0];
266
267 return CookieKeys.getCookie(request, cookieName);
268 }
269
270 private boolean _isAuthenticated(
271 HttpServletRequest request, String serviceUrl)
272 throws IOException {
273
274 boolean authenticated = false;
275
276 boolean hasCookieNames = false;
277
278 String[] cookieNames = _getCookieNames(serviceUrl);
279
280 for (String cookieName : cookieNames) {
281 if (CookieKeys.getCookie(request, cookieName) != null) {
282 hasCookieNames = true;
283
284 break;
285 }
286 }
287
288 if (!hasCookieNames) {
289 if (_log.isWarnEnabled()) {
290 _log.warn(
291 "User is not logged in because he has no OpenSSO cookies");
292 }
293
294 return false;
295 }
296
297 String url = serviceUrl.concat(_VALIDATE_TOKEN);
298
299 URL urlObj = new URL(url);
300
301 HttpURLConnection httpURLConnection =
302 (HttpURLConnection)urlObj.openConnection();
303
304 httpURLConnection.setDoOutput(true);
305 httpURLConnection.setRequestMethod("POST");
306 httpURLConnection.setRequestProperty(
307 "Content-type", "application/x-www-form-urlencoded");
308
309 _setCookieProperty(request, httpURLConnection, cookieNames);
310
311 OutputStreamWriter outputStreamWriter = new OutputStreamWriter(
312 httpURLConnection.getOutputStream());
313
314 outputStreamWriter.write("dummy");
315
316 outputStreamWriter.flush();
317
318 int responseCode = httpURLConnection.getResponseCode();
319
320 if (responseCode == HttpURLConnection.HTTP_OK) {
321 String data = StringUtil.read(httpURLConnection.getInputStream());
322
323 if (StringUtil.toLowerCase(data).contains("boolean=true")) {
324 authenticated = true;
325 }
326 }
327 else if (_log.isDebugEnabled()) {
328 _log.debug("Authentication response code " + responseCode);
329 }
330
331 return authenticated;
332 }
333
334 private boolean _isValidServiceUrl(String serviceUrl) {
335 if (Validator.isNull(serviceUrl)) {
336 return false;
337 }
338
339 String[] cookieNames = _instance._getCookieNames(serviceUrl);
340
341 if (cookieNames.length == 0) {
342 return false;
343 }
344
345 return true;
346 }
347
348 private boolean _isValidUrl(String url) {
349 if (Validator.isNull(url)) {
350 return false;
351 }
352
353 try {
354 URL urlObj = new URL(url);
355
356 HttpURLConnection httpURLConnection =
357 (HttpURLConnection)urlObj.openConnection();
358
359 int responseCode = httpURLConnection.getResponseCode();
360
361 if (responseCode != HttpURLConnection.HTTP_OK) {
362 if (_log.isDebugEnabled()) {
363 _log.debug("Attributes response code " + responseCode);
364 }
365
366 return false;
367 }
368 }
369 catch (IOException ioe) {
370 if (_log.isWarnEnabled()) {
371 _log.warn(ioe, ioe);
372 }
373
374 return false;
375 }
376
377 return true;
378 }
379
380 private boolean _isValidUrls(String[] urls) {
381 for (String url : urls) {
382 if (!_isValidUrl(url)) {
383 return false;
384 }
385 }
386
387 return true;
388 }
389
390 private void _setCookieProperty(
391 HttpServletRequest request, HttpURLConnection urlc,
392 String[] cookieNames) {
393
394 if (cookieNames.length == 0) {
395 return;
396 }
397
398 StringBundler sb = new StringBundler(cookieNames.length * 4);
399
400 for (String cookieName : cookieNames) {
401 String cookieValue = CookieKeys.getCookie(request, cookieName);
402
403 sb.append(cookieName);
404 sb.append(StringPool.EQUAL);
405 sb.append(StringPool.QUOTE);
406 sb.append(cookieValue);
407 sb.append(StringPool.QUOTE);
408 sb.append(StringPool.SEMICOLON);
409 }
410
411 urlc.setRequestProperty("Cookie", sb.toString());
412 }
413
414 private static final String _GET_ATTRIBUTES = "/identity/attributes";
415
416 private static final String _GET_COOKIE_NAME =
417 "/identity/getCookieNameForToken";
418
419 private static final String _GET_COOKIE_NAMES =
420 "/identity/getCookieNamesToForward";
421
422 private static final String _VALIDATE_TOKEN = "/identity/isTokenValid";
423
424 private static Log _log = LogFactoryUtil.getLog(OpenSSOUtil.class);
425
426 private static OpenSSOUtil _instance = new OpenSSOUtil();
427
428 private Map<String, String[]> _cookieNamesMap =
429 new ConcurrentHashMap<String, String[]>();
430
431 }