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.StringBundler;
021 import com.liferay.portal.kernel.util.StringPool;
022 import com.liferay.portal.kernel.util.StringUtil;
023 import com.liferay.portal.kernel.util.Validator;
024 import com.liferay.util.CookieUtil;
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 mfue) {
150 _log.error(mfue.getMessage());
151
152 if (_log.isDebugEnabled()) {
153 _log.debug(mfue, mfue);
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(
191 new InputStreamReader(inputStream));
192
193 int responseCode = httpURLConnection.getResponseCode();
194
195 if (responseCode != HttpURLConnection.HTTP_OK) {
196 if (_log.isDebugEnabled()) {
197 _log.debug(url + " has response code " + responseCode);
198 }
199 }
200 else {
201 String line = null;
202
203 while ((line = unsyncBufferedReader.readLine()) != null) {
204 if (line.startsWith("string=")) {
205 line = line.replaceFirst("string=", "");
206
207 cookieName = line;
208 }
209 }
210 }
211
212 url = serviceUrl.concat(_GET_COOKIE_NAMES);
213
214 urlObj = new URL(url);
215
216 httpURLConnection = (HttpURLConnection)urlObj.openConnection();
217
218 inputStream = (InputStream)httpURLConnection.getContent();
219
220 unsyncBufferedReader = new UnsyncBufferedReader(
221 new InputStreamReader(inputStream));
222
223 if (httpURLConnection.getResponseCode() !=
224 HttpURLConnection.HTTP_OK) {
225
226 if (_log.isDebugEnabled()) {
227 _log.debug(url + " has response code " + responseCode);
228 }
229 }
230 else {
231 String line = null;
232
233 while ((line = unsyncBufferedReader.readLine()) != null) {
234 if (line.startsWith("string=")) {
235 line = line.replaceFirst("string=", "");
236
237 if (cookieName.equals(line)) {
238 cookieNamesList.add(0, cookieName);
239 }
240 else {
241 cookieNamesList.add(line);
242 }
243 }
244 }
245 }
246 }
247 catch (IOException ioe) {
248 if (_log.isWarnEnabled()) {
249 _log.warn(ioe, ioe);
250 }
251 }
252
253 cookieNames = cookieNamesList.toArray(
254 new String[cookieNamesList.size()]);
255
256 if (cookieNames.length > 0) {
257 _cookieNamesMap.put(serviceUrl, cookieNames);
258 }
259
260 return cookieNames;
261 }
262
263 private String _getSubjectId(
264 HttpServletRequest request, String serviceUrl) {
265
266 String cookieName = _getCookieNames(serviceUrl)[0];
267
268 return CookieUtil.get(request, cookieName);
269 }
270
271 private boolean _isAuthenticated(
272 HttpServletRequest request, String serviceUrl)
273 throws IOException {
274
275 boolean authenticated = false;
276
277 boolean hasCookieNames = false;
278
279 String[] cookieNames = _getCookieNames(serviceUrl);
280
281 for (String cookieName : cookieNames) {
282 if (CookieUtil.get(request, cookieName) != null) {
283 hasCookieNames = true;
284
285 break;
286 }
287 }
288
289 if (!hasCookieNames) {
290 if (_log.isWarnEnabled()) {
291 _log.warn(
292 "User is not logged in because he has no OpenSSO cookies");
293 }
294
295 return false;
296 }
297
298 String url = serviceUrl.concat(_VALIDATE_TOKEN);
299
300 URL urlObj = new URL(url);
301
302 HttpURLConnection httpURLConnection =
303 (HttpURLConnection)urlObj.openConnection();
304
305 httpURLConnection.setDoOutput(true);
306 httpURLConnection.setRequestMethod("POST");
307 httpURLConnection.setRequestProperty(
308 "Content-type", "application/x-www-form-urlencoded");
309
310 _setCookieProperty(request, httpURLConnection, cookieNames);
311
312 OutputStreamWriter outputStreamWriter = new OutputStreamWriter(
313 httpURLConnection.getOutputStream());
314
315 outputStreamWriter.write("dummy");
316
317 outputStreamWriter.flush();
318
319 int responseCode = httpURLConnection.getResponseCode();
320
321 if (responseCode == HttpURLConnection.HTTP_OK) {
322 String data = StringUtil.read(httpURLConnection.getInputStream());
323
324 if (data.toLowerCase().indexOf("boolean=true") != -1) {
325 authenticated = true;
326 }
327 }
328 else if (_log.isDebugEnabled()) {
329 _log.debug("Authentication response code " + responseCode);
330 }
331
332 return authenticated;
333 }
334
335 private boolean _isValidServiceUrl(String serviceUrl) {
336 if (Validator.isNull(serviceUrl)) {
337 return false;
338 }
339
340 String[] cookieNames = _instance._getCookieNames(serviceUrl);
341
342 if (cookieNames.length == 0) {
343 return false;
344 }
345
346 return true;
347 }
348
349 private boolean _isValidUrl(String url) {
350 if (Validator.isNull(url)) {
351 return false;
352 }
353
354 try {
355 URL urlObj = new URL(url);
356
357 HttpURLConnection httpURLConnection =
358 (HttpURLConnection)urlObj.openConnection();
359
360 int responseCode = httpURLConnection.getResponseCode();
361
362 if (responseCode != HttpURLConnection.HTTP_OK) {
363 if (_log.isDebugEnabled()) {
364 _log.debug("Attributes response code " + responseCode);
365 }
366
367 return false;
368 }
369 }
370 catch (IOException ioe) {
371 if (_log.isWarnEnabled()) {
372 _log.warn(ioe, ioe);
373 }
374
375 return false;
376 }
377
378 return true;
379 }
380
381 private boolean _isValidUrls(String[] urls) {
382 for (String url : urls) {
383 if (!_isValidUrl(url)) {
384 return false;
385 }
386 }
387
388 return true;
389 }
390
391 private void _setCookieProperty(
392 HttpServletRequest request, HttpURLConnection urlc,
393 String[] cookieNames) {
394
395 if (cookieNames.length == 0) {
396 return;
397 }
398
399 StringBundler sb = new StringBundler(cookieNames.length * 4);
400
401 for (String cookieName : cookieNames) {
402 String cookieValue = CookieUtil.get(request, cookieName);
403
404 sb.append(cookieName);
405 sb.append(StringPool.EQUAL);
406 sb.append(StringPool.QUOTE);
407 sb.append(cookieValue);
408 sb.append(StringPool.QUOTE);
409 sb.append(StringPool.SEMICOLON);
410 }
411
412 urlc.setRequestProperty("Cookie", sb.toString());
413 }
414
415 private static final String _GET_ATTRIBUTES = "/identity/attributes";
416
417 private static final String _GET_COOKIE_NAME =
418 "/identity/getCookieNameForToken";
419
420 private static final String _GET_COOKIE_NAMES =
421 "/identity/getCookieNamesToForward";
422
423 private static final String _VALIDATE_TOKEN = "/identity/isTokenValid";
424
425 private static Log _log = LogFactoryUtil.getLog(OpenSSOUtil.class);
426
427 private static OpenSSOUtil _instance = new OpenSSOUtil();
428
429 private Map<String, String[]> _cookieNamesMap =
430 new ConcurrentHashMap<String, String[]>();
431
432 }