1
14
15 package com.liferay.portal.servlet.filters.sso.opensso;
16
17 import com.liferay.portal.kernel.io.unsync.UnsyncBufferedReader;
18 import com.liferay.portal.kernel.log.Log;
19 import com.liferay.portal.kernel.log.LogFactoryUtil;
20 import com.liferay.portal.kernel.util.StringBundler;
21 import com.liferay.portal.kernel.util.StringPool;
22 import com.liferay.portal.kernel.util.StringUtil;
23 import com.liferay.portal.kernel.util.Validator;
24 import com.liferay.util.CookieUtil;
25
26 import java.io.IOException;
27 import java.io.InputStream;
28 import java.io.InputStreamReader;
29 import java.io.OutputStreamWriter;
30
31 import java.net.HttpURLConnection;
32 import java.net.MalformedURLException;
33 import java.net.URL;
34
35 import java.util.ArrayList;
36 import java.util.HashMap;
37 import java.util.List;
38 import java.util.Map;
39 import java.util.concurrent.ConcurrentHashMap;
40
41 import javax.servlet.http.HttpServletRequest;
42
43
54 public class OpenSSOUtil {
55
56 public static Map<String, String> getAttributes(
57 HttpServletRequest request, String serviceUrl) {
58
59 return _instance._getAttributes(request, serviceUrl);
60 }
61
62 public static String getSubjectId(
63 HttpServletRequest request, String serviceUrl) {
64
65 return _instance._getSubjectId(request, serviceUrl);
66 }
67
68 public static boolean isAuthenticated(
69 HttpServletRequest request, String serviceUrl)
70 throws IOException {
71
72 return _instance._isAuthenticated(request, serviceUrl);
73 }
74
75 public static boolean isValidServiceUrl(String serviceUrl) {
76 return _instance._isValidServiceUrl(serviceUrl);
77 }
78
79 public static boolean isValidUrl(String url) {
80 return _instance._isValidUrl(url);
81 }
82
83 public static boolean isValidUrls(String[] urls) {
84 return _instance._isValidUrls(urls);
85 }
86
87 private OpenSSOUtil() {
88 }
89
90 private Map<String, String> _getAttributes(
91 HttpServletRequest request, String serviceUrl) {
92
93 Map<String, String> nameValues = new HashMap<String, String>();
94
95 String url = serviceUrl + _GET_ATTRIBUTES;
96
97 try {
98 URL urlObj = new URL(url);
99
100 HttpURLConnection urlc = (HttpURLConnection)urlObj.openConnection();
101
102 urlc.setDoOutput(true);
103 urlc.setRequestMethod("POST");
104 urlc.setRequestProperty(
105 "Content-type", "application/x-www-form-urlencoded");
106
107 String[] cookieNames = _getCookieNames(serviceUrl);
108
109 _setCookieProperty(request, urlc, cookieNames);
110
111 OutputStreamWriter osw = new OutputStreamWriter(
112 urlc.getOutputStream());
113
114 osw.write("dummy");
115
116 osw.flush();
117
118 int responseCode = urlc.getResponseCode();
119
120 if (responseCode == HttpURLConnection.HTTP_OK) {
121 UnsyncBufferedReader unsyncBufferedReader =
122 new UnsyncBufferedReader(
123 new InputStreamReader((InputStream)urlc.getContent()));
124
125 String line = null;
126
127 while ((line = unsyncBufferedReader.readLine()) != null) {
128 if (line.startsWith("userdetails.attribute.name=")) {
129 String name = line.replaceFirst(
130 "userdetails.attribute.name=", "");
131
132 line = unsyncBufferedReader.readLine();
133
134 if (line.startsWith("userdetails.attribute.value=")) {
135 String value = line.replaceFirst(
136 "userdetails.attribute.value=", "");
137
138 nameValues.put(name, value);
139 }
140 }
141 }
142 }
143 else if (_log.isDebugEnabled()) {
144 _log.debug("Attributes response code " + responseCode);
145 }
146 }
147 catch (MalformedURLException mfue) {
148 _log.error(mfue.getMessage());
149
150 if (_log.isDebugEnabled()) {
151 _log.debug(mfue, mfue);
152 }
153 }
154 catch (IOException ioe) {
155 _log.error(ioe.getMessage());
156
157 if (_log.isDebugEnabled()) {
158 _log.debug(ioe, ioe);
159 }
160 }
161
162 return nameValues;
163 }
164
165 private String[] _getCookieNames(String serviceUrl) {
166 String[] cookieNames = _cookieNamesMap.get(serviceUrl);
167
168 if (cookieNames != null) {
169 return cookieNames;
170 }
171
172 List<String> cookieNamesList = new ArrayList<String>();
173
174 try {
175 String cookieName = null;
176
177 String url = serviceUrl + _GET_COOKIE_NAME;
178
179 URL urlObj = new URL(url);
180
181 HttpURLConnection urlc = (HttpURLConnection)urlObj.openConnection();
182
183 UnsyncBufferedReader unsyncBufferedReader =
184 new UnsyncBufferedReader(
185 new InputStreamReader((InputStream)urlc.getContent()));
186
187 int responseCode = urlc.getResponseCode();
188
189 if (responseCode != HttpURLConnection.HTTP_OK) {
190 if (_log.isDebugEnabled()) {
191 _log.debug(url + " has response code " + responseCode);
192 }
193 }
194 else {
195 String line = null;
196
197 while ((line = unsyncBufferedReader.readLine()) != null) {
198 if (line.startsWith("string=")) {
199 line = line.replaceFirst("string=", "");
200
201 cookieName = line;
202 }
203 }
204 }
205
206 url = serviceUrl + _GET_COOKIE_NAMES;
207
208 urlObj = new URL(url);
209
210 urlc = (HttpURLConnection)urlObj.openConnection();
211
212 unsyncBufferedReader = new UnsyncBufferedReader(
213 new InputStreamReader((InputStream)urlc.getContent()));
214
215 if (urlc.getResponseCode() != HttpURLConnection.HTTP_OK) {
216 if (_log.isDebugEnabled()) {
217 _log.debug(url + " has response code " + responseCode);
218 }
219 }
220 else {
221 String line = null;
222
223 while ((line = unsyncBufferedReader.readLine()) != null) {
224 if (line.startsWith("string=")) {
225 line = line.replaceFirst("string=", "");
226
227 if (cookieName.equals(line)) {
228 cookieNamesList.add(0, cookieName);
229 }
230 else {
231 cookieNamesList.add(line);
232 }
233 }
234 }
235 }
236 }
237 catch (IOException ioe) {
238 if (_log.isWarnEnabled()) {
239 _log.warn(ioe, ioe);
240 }
241 }
242
243 cookieNames = cookieNamesList.toArray(
244 new String[cookieNamesList.size()]);
245
246 if (cookieNames.length > 0) {
247 _cookieNamesMap.put(serviceUrl, cookieNames);
248 }
249
250 return cookieNames;
251 }
252
253 private String _getSubjectId(
254 HttpServletRequest request, String serviceUrl) {
255
256 String cookieName = _getCookieNames(serviceUrl)[0];
257
258 return CookieUtil.get(request, cookieName);
259 }
260
261 private boolean _isAuthenticated(
262 HttpServletRequest request, String serviceUrl)
263 throws IOException {
264
265 boolean authenticated = false;
266
267 String url = serviceUrl + _VALIDATE_TOKEN;
268
269 URL urlObj = new URL(url);
270
271 HttpURLConnection urlc = (HttpURLConnection)urlObj.openConnection();
272
273 urlc.setDoOutput(true);
274 urlc.setRequestMethod("POST");
275 urlc.setRequestProperty(
276 "Content-type", "application/x-www-form-urlencoded");
277
278 String[] cookieNames = _getCookieNames(serviceUrl);
279
280 if (cookieNames.length == 0) {
281 throw new IOException(
282 "Cookie names from OpenSSO service are not accessible");
283 }
284
285 _setCookieProperty(request, urlc, cookieNames);
286
287 OutputStreamWriter osw = new OutputStreamWriter(urlc.getOutputStream());
288
289 osw.write("dummy");
290
291 osw.flush();
292
293 int responseCode = urlc.getResponseCode();
294
295 if (responseCode == HttpURLConnection.HTTP_OK) {
296 String data = StringUtil.read(urlc.getInputStream());
297
298 if (data.toLowerCase().indexOf("boolean=true") != -1) {
299 authenticated = true;
300 }
301 }
302 else if (_log.isDebugEnabled()) {
303 _log.debug("Authentication response code " + responseCode);
304 }
305
306 return authenticated;
307 }
308
309 private boolean _isValidServiceUrl(String serviceUrl) {
310 if (Validator.isNull(serviceUrl)) {
311 return false;
312 }
313
314 String[] cookieNames = _instance._getCookieNames(serviceUrl);
315
316 if (cookieNames.length == 0) {
317 return false;
318 }
319
320 return true;
321 }
322
323 private boolean _isValidUrl(String url) {
324 if (Validator.isNull(url)) {
325 return false;
326 }
327
328 try {
329 URL urlObj = new URL(url);
330
331 HttpURLConnection urlc = (HttpURLConnection)urlObj.openConnection();
332
333 int responseCode = urlc.getResponseCode();
334
335 if (responseCode != HttpURLConnection.HTTP_OK) {
336 if (_log.isDebugEnabled()) {
337 _log.debug("Attributes response code " + responseCode);
338 }
339
340 return false;
341 }
342 }
343 catch (IOException ioe) {
344 if (_log.isWarnEnabled()) {
345 _log.warn(ioe, ioe);
346 }
347
348 return false;
349 }
350
351 return true;
352 }
353
354 private boolean _isValidUrls(String[] urls) {
355 for (String url : urls) {
356 if (!_isValidUrl(url)) {
357 return false;
358 }
359 }
360
361 return true;
362 }
363
364 private void _setCookieProperty(
365 HttpServletRequest request, HttpURLConnection urlc,
366 String[] cookieNames) {
367
368 if (cookieNames.length == 0) {
369 return;
370 }
371
372 StringBundler sb = new StringBundler(cookieNames.length * 4);
373
374 for (String cookieName : cookieNames) {
375 String cookieValue = CookieUtil.get(request, cookieName);
376
377 sb.append(cookieName);
378 sb.append(StringPool.EQUAL);
379 sb.append(StringPool.QUOTE);
380 sb.append(cookieValue);
381 sb.append(StringPool.QUOTE);
382 sb.append(StringPool.SEMICOLON);
383 }
384
385 urlc.setRequestProperty("Cookie", sb.toString());
386 }
387
388 private static final String _GET_ATTRIBUTES = "/identity/attributes";
389
390 private static final String _GET_COOKIE_NAME =
391 "/identity/getCookieNameForToken";
392
393 private static final String _GET_COOKIE_NAMES =
394 "/identity/getCookieNamesToForward";
395
396 private static final String _VALIDATE_TOKEN = "/identity/isTokenValid";
397
398 private static Log _log = LogFactoryUtil.getLog(OpenSSOUtil.class);
399
400 private static OpenSSOUtil _instance = new OpenSSOUtil();
401
402 private Map<String, String[]> _cookieNamesMap =
403 new ConcurrentHashMap<String, String[]>();
404
405 }