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