1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.jetspeed.sso.impl;
18
19 import java.io.IOException;
20 import java.net.MalformedURLException;
21 import java.net.URL;
22 import java.security.Principal;
23 import java.util.ArrayList;
24 import java.util.Collection;
25 import java.util.HashSet;
26 import java.util.Hashtable;
27 import java.util.Iterator;
28 import java.util.List;
29 import java.util.Set;
30 import java.util.StringTokenizer;
31 import java.util.Vector;
32
33 import javax.security.auth.Subject;
34
35 import org.apache.commons.codec.binary.Base64;
36 import org.apache.commons.httpclient.HttpClient;
37 import org.apache.commons.httpclient.UsernamePasswordCredentials;
38 import org.apache.commons.httpclient.cookie.CookiePolicy;
39 import org.apache.commons.httpclient.methods.GetMethod;
40 import org.apache.commons.logging.Log;
41 import org.apache.commons.logging.LogFactory;
42 import org.apache.jetspeed.components.dao.InitablePersistenceBrokerDaoSupport;
43 import org.apache.jetspeed.security.BasePrincipal;
44 import org.apache.jetspeed.security.SecurityHelper;
45 import org.apache.jetspeed.security.UserPrincipal;
46 import org.apache.jetspeed.security.impl.GroupPrincipalImpl;
47 import org.apache.jetspeed.security.impl.UserPrincipalImpl;
48 import org.apache.jetspeed.security.om.InternalCredential;
49 import org.apache.jetspeed.security.om.InternalGroupPrincipal;
50 import org.apache.jetspeed.security.om.InternalUserPrincipal;
51 import org.apache.jetspeed.security.om.impl.InternalCredentialImpl;
52 import org.apache.jetspeed.security.om.impl.InternalGroupPrincipalImpl;
53 import org.apache.jetspeed.security.om.impl.InternalUserPrincipalImpl;
54 import org.apache.jetspeed.security.spi.impl.DefaultPasswordCredentialImpl;
55 import org.apache.jetspeed.sso.SSOContext;
56 import org.apache.jetspeed.sso.SSOException;
57 import org.apache.jetspeed.sso.SSOPrincipal;
58 import org.apache.jetspeed.sso.SSOProvider;
59 import org.apache.jetspeed.sso.SSOSite;
60 import org.apache.ojb.broker.query.Criteria;
61 import org.apache.ojb.broker.query.Query;
62 import org.apache.ojb.broker.query.QueryByCriteria;
63 import org.apache.ojb.broker.query.QueryFactory;
64
65
66 /***
67 * <p>Utility component to handle SSO requests</p>
68 *
69 * @author <a href="mailto:rogerrut@apache.org">Roger Ruttimann</a>
70 */
71 public class PersistenceBrokerSSOProvider extends
72 InitablePersistenceBrokerDaoSupport implements SSOProvider
73 {
74
75 private static final Log log = LogFactory.getLog(PersistenceBrokerSSOProvider.class);
76
77
78
79
80 private Hashtable mapSite = new Hashtable();
81 private Hashtable clientProxy = new Hashtable();
82
83 private String USER_PATH = "/user/";
84 private String GROUP_PATH = "/group/";
85
86 /***
87 * PersitenceBrokerSSOProvider()
88 * @param repository Location of repository mapping file. Must be available within the classpath.
89 * @param prefsFactoryImpl <code>java.util.prefs.PreferencesFactory</code> implementation to use.
90 * @param enablePropertyManager Whether or not we chould be suing the property manager.
91 * @throws ClassNotFoundException if the <code>prefsFactoryImpl</code> argument does not reperesent
92 * a Class that exists in the current classPath.
93 */
94 public PersistenceBrokerSSOProvider(String repositoryPath) throws ClassNotFoundException
95 {
96 super(repositoryPath);
97 }
98
99
100
101
102
103
104 public String useSSO(Subject subject, String url, String SSOSite, boolean bRefresh) throws SSOException
105 {
106
107 BasePrincipal principal = (BasePrincipal)SecurityHelper.getBestPrincipal(subject, UserPrincipal.class);
108 String fullPath = principal.getFullPath();
109
110
111
112
113 String proxyID = fullPath + "_" + SSOSite;
114
115
116 SSOSite ssoSite = getSSOSiteObject(SSOSite);
117
118 if ( ssoSite != null)
119 {
120 SSOSite[] sites = new SSOSite[1];
121 sites[0] = ssoSite;
122
123 return this.getContentFromURL(proxyID, url, sites, bRefresh);
124 }
125 else
126 {
127
128 String msg = "SSO component -- useSSO can't retrive SSO credential because SSOSite [" + SSOSite + "] doesn't exist";
129 log.error(msg);
130 SSOSite[] sites = new SSOSite[0];
131 return this.getContentFromURL(proxyID, url, sites, bRefresh);
132 }
133 }
134
135
136
137
138
139 public String useSSO(Subject subject, String url, boolean bRefresh) throws SSOException
140 {
141
142 BasePrincipal principal = (BasePrincipal)SecurityHelper.getBestPrincipal(subject, UserPrincipal.class);
143 String fullPath = principal.getFullPath();
144
145
146
147
148
149 String proxyID = fullPath;
150
151 Collection sites = this.getSitesForPrincipal(fullPath);
152
153 if (sites == null)
154 {
155 String msg = "SSO Component useSSO -- Couldn't find any SSO sites for user ["+fullPath+"]";
156 log.error(msg);
157 throw new SSOException(msg);
158 }
159
160
161 int siteSize = sites.size();
162 int siteIndex =0;
163 SSOSite[] ssoSites = new SSOSite[siteSize];
164
165 Iterator itSites = sites.iterator();
166 while(itSites.hasNext())
167 {
168 SSOSite ssoSite = (SSOSite)itSites.next();
169 if (ssoSite != null)
170 {
171 ssoSites[siteIndex] = ssoSite;
172 siteIndex++;
173 }
174 }
175
176 return this.getContentFromURL(proxyID, url, ssoSites, bRefresh);
177 }
178
179 /***
180 * Retrive cookies for an user by User full path
181 * @param fullPath
182 * @return
183 */
184 public Collection getCookiesForUser(String fullPath)
185 {
186
187 SSOPrincipal ssoPrincipal = this.getSSOPrincipal(fullPath);
188
189
190 Vector temp = new Vector();
191
192 Iterator itRemotePrincipal = ssoPrincipal.getRemotePrincipals().iterator();
193 while (itRemotePrincipal.hasNext())
194 {
195 InternalUserPrincipal rp = (InternalUserPrincipal)itRemotePrincipal.next();
196 if (rp != null)
197 {
198 temp.add(rp.getFullPath());
199 }
200 }
201
202 if (temp.size() > 0)
203 {
204
205 Criteria filter = new Criteria();
206 filter.addIn("remotePrincipals.fullPath", temp);
207
208 QueryByCriteria query = QueryFactory.newQuery(SSOCookieImpl.class, filter);
209 return getPersistenceBrokerTemplate().getCollectionByQuery(query);
210 }
211 else
212 {
213 return null;
214 }
215
216 }
217
218 /***
219 * Retrive Cookies by Subject
220 * @param user
221 * @return
222 */
223 public Collection getCookiesForUser(Subject user)
224 {
225
226 BasePrincipal principal = (BasePrincipal)SecurityHelper.getBestPrincipal(user, UserPrincipal.class);
227 String fullPath = principal.getFullPath();
228
229
230 return this.getCookiesForUser(fullPath);
231 }
232
233
234 public void setRealmForSite(String site, String realm) throws SSOException
235 {
236 SSOSite ssoSite = getSSOSiteObject(site);
237
238 if ( ssoSite != null)
239 {
240 try
241 {
242 ssoSite.setRealm(realm);
243 getPersistenceBrokerTemplate().store(ssoSite);
244 }
245 catch (Exception e)
246 {
247 throw new SSOException("Failed to set the realm for site [" + site + "] Error" +e );
248 }
249 }
250 }
251
252 public String getRealmForSite(String site) throws SSOException
253 {
254 SSOSite ssoSite = getSSOSiteObject(site);
255
256 if ( ssoSite != null)
257 {
258 return ssoSite.getRealm();
259 }
260
261 return null;
262 }
263
264 /***
265 * Get all SSOSites that the principal has access to
266 * @param userId
267 * @return
268 */
269 public Collection getSitesForPrincipal(String fullPath)
270 {
271
272 Criteria filter = new Criteria();
273 filter.addEqualTo("principals.fullPath", fullPath);
274
275 QueryByCriteria query = QueryFactory.newQuery(SSOSiteImpl.class, filter);
276 return getPersistenceBrokerTemplate().getCollectionByQuery(query);
277 }
278
279 public Iterator getSites(String filter)
280 {
281 Criteria queryCriteria = new Criteria();
282 Query query = QueryFactory.newQuery(SSOSiteImpl.class, queryCriteria);
283 Collection c = getPersistenceBrokerTemplate().getCollectionByQuery(query);
284 return c.iterator();
285 }
286
287 /***
288 * addCredentialsForSite()
289 * @param fullPath
290 * @param remoteUser
291 * @param site
292 * @param pwd
293 * @throws SSOException
294 */
295 public void addCredentialsForSite(String fullPath, String remoteUser, String site, String pwd) throws SSOException
296 {
297
298 Principal principal = null;
299 String name = null;
300
301
302 if (fullPath.indexOf("/group/") > -1 )
303 {
304 name = fullPath.substring(GROUP_PATH.length());
305 principal = new GroupPrincipalImpl(name);
306 }
307 else
308 {
309 name = fullPath.substring(USER_PATH.length());
310 principal = new UserPrincipalImpl(name);
311 }
312
313
314 Set principals = new HashSet();
315 principals.add(principal);
316 Subject subject = new Subject(true, principals, new HashSet(), new HashSet());
317
318
319 addCredentialsForSite(subject, remoteUser, site, pwd);
320 }
321
322 /***
323 * removeCredentialsForSite()
324 * @param fullPath
325 * @param site
326 * @throws SSOException
327 */
328 public void removeCredentialsForSite(String fullPath, String site) throws SSOException
329 {
330
331 Principal principal = null;
332 String name = null;
333
334
335 if (fullPath.indexOf("/group/") > -1 )
336 {
337 name = fullPath.substring(GROUP_PATH.length());
338 principal = new GroupPrincipalImpl(name);
339 }
340 else
341 {
342 name = fullPath.substring(USER_PATH.length());
343 principal = new UserPrincipalImpl(name);
344 }
345
346
347 Set principals = new HashSet();
348 principals.add(principal);
349 Subject subject = new Subject(true, principals, new HashSet(), new HashSet());
350
351
352 this.removeCredentialsForSite(subject,site);
353 }
354
355
356 /*** Retrive site information
357 *
358 * getSiteURL
359 */
360
361 public String getSiteURL(String site)
362 {
363
364 return site;
365 }
366
367 /***
368 * getSiteName
369 */
370 public String getSiteName(String site)
371 {
372 SSOSite ssoSite = getSSOSiteObject(site);
373
374 if ( ssoSite != null)
375 {
376 return ssoSite.getName();
377 }
378 else
379 {
380 return null;
381 }
382 }
383
384
385
386
387 public boolean hasSSOCredentials(Subject subject, String site) {
388
389 SSOSite ssoSite = getSSOSiteObject(site);
390
391 if ( ssoSite == null)
392 {
393 return false;
394 }
395
396
397 BasePrincipal principal = (BasePrincipal)SecurityHelper.getBestPrincipal(subject, UserPrincipal.class);
398 String fullPath = principal.getFullPath();
399
400
401
402 Collection remoteForSite = ssoSite.getRemotePrincipals();
403 Collection principalsForSite = ssoSite.getPrincipals();
404
405
406 if (principalsForSite == null || remoteForSite== null )
407 return false;
408
409 Collection remoteForPrincipals = getRemotePrincipalsForPrincipal(principalsForSite, fullPath);
410
411 if ( remoteForPrincipals == null)
412 return false;
413
414
415 if (findRemoteMatch(remoteForPrincipals, remoteForSite) == null )
416 {
417 return false;
418 }
419 else
420 {
421 return true;
422 }
423 }
424
425
426
427
428 public SSOContext getCredentials(Subject subject, String site)
429 throws SSOException {
430
431
432 SSOSite ssoSite = getSSOSiteObject(site);
433
434 if ( ssoSite == null)
435 throw new SSOException(SSOException.NO_CREDENTIALS_FOR_SITE);
436
437
438 BasePrincipal principal = (BasePrincipal)SecurityHelper.getBestPrincipal(subject, UserPrincipal.class);
439 String fullPath = principal.getFullPath();
440
441
442 SSOContext context = getCredential(ssoSite, fullPath);
443
444 if ( context == null)
445 throw new SSOException(SSOException.NO_CREDENTIALS_FOR_SITE);
446
447 return context;
448 }
449
450
451
452
453
454 public void addCredentialsForSite(Subject subject, String remoteUser, String site, String pwd)
455 throws SSOException {
456
457
458 SSOSite ssoSite = getSSOSiteObject(site);
459 if (ssoSite == null)
460 {
461
462 ssoSite = new SSOSiteImpl();
463 ssoSite.setSiteURL(site);
464 ssoSite.setName(site);
465 ssoSite.setCertificateRequired(false);
466 ssoSite.setAllowUserSet(true);
467
468 ssoSite.setChallengeResponseAuthentication(true);
469 ssoSite.setFormAuthentication(false);
470
471
472 try
473 {
474 getPersistenceBrokerTemplate().store(ssoSite);
475 }
476 catch (Exception e)
477 {
478 e.printStackTrace();
479 throw new SSOException(SSOException.FAILED_STORING_SITE_INFO_IN_DB + e.toString() );
480 }
481 }
482
483
484 String fullPath = ((BasePrincipal)SecurityHelper.getBestPrincipal(subject, UserPrincipal.class)).getFullPath();
485 String principalName = ((BasePrincipal)SecurityHelper.getBestPrincipal(subject, UserPrincipal.class)).getName();
486
487
488 SSOPrincipal principal = this.getPrincipalForSite(ssoSite, fullPath);
489
490 if (principal == null )
491 {
492 principal = getSSOPrincipal(fullPath);
493 ssoSite.addPrincipal(principal);
494 }
495 else
496 {
497
498 Collection remoteForSite = ssoSite.getRemotePrincipals();
499 Collection principalsForSite = ssoSite.getPrincipals();
500
501 if ( remoteForSite != null && principalsForSite != null)
502 {
503 Collection remoteForPrincipals = this.getRemotePrincipalsForPrincipal(principalsForSite, fullPath);
504 if ( remoteForPrincipals != null)
505 {
506 if (findRemoteMatch(remoteForPrincipals, remoteForSite) != null )
507 {
508
509 throw new SSOException(SSOException.REMOTE_PRINCIPAL_EXISTS_CALL_UPDATE);
510 }
511 }
512 }
513 }
514
515 if (principal == null)
516 throw new SSOException(SSOException.FAILED_ADDING_PRINCIPAL_TO_MAPPING_TABLE_FOR_SITE);
517
518
519 InternalUserPrincipalImpl remotePrincipal = new InternalUserPrincipalImpl(remoteUser);
520
521
522
523
524
525
526 if ( fullPath.indexOf("/group/") > -1)
527 remotePrincipal.setFullPath("/sso/" + ssoSite.getSiteId() + "/group/"+ principalName + "/" + remoteUser);
528 else
529 remotePrincipal.setFullPath("/sso/" + ssoSite.getSiteId() + "/user/"+ principalName + "/" + remoteUser);
530
531
532 InternalCredentialImpl credential =
533 new InternalCredentialImpl(remotePrincipal.getPrincipalId(),
534 this.scramble(pwd), 0, DefaultPasswordCredentialImpl.class.getName());
535
536 if ( remotePrincipal.getCredentials() == null)
537 remotePrincipal.setCredentials(new ArrayList(0));
538
539 remotePrincipal.getCredentials().add( credential);
540
541
542 principal.addRemotePrincipal(remotePrincipal);
543
544
545 ssoSite.getRemotePrincipals().add(remotePrincipal);
546
547
548
549 try
550 {
551 getPersistenceBrokerTemplate().store(ssoSite);
552
553
554 getPersistenceBrokerTemplate().store(principal);
555 }
556 catch (Exception e)
557 {
558 e.printStackTrace();
559 throw new SSOException(SSOException.FAILED_STORING_SITE_INFO_IN_DB + e.toString() );
560 }
561
562
563 this.mapSite.put(site, ssoSite);
564 }
565
566
567
568
569 public void removeCredentialsForSite(Subject subject, String site)
570 throws SSOException {
571
572
573 InternalUserPrincipal remotePrincipal = null;
574
575 SSOSite ssoSite = getSSOSiteObject(site);
576 if (ssoSite == null)
577 {
578 throw new SSOException(SSOException.NO_CREDENTIALS_FOR_SITE);
579 }
580
581
582 String fullPath = ((BasePrincipal)SecurityHelper.getBestPrincipal(subject, UserPrincipal.class)).getFullPath();
583
584 try
585 {
586
587 Collection principalsForSite = ssoSite.getPrincipals();
588 Collection remoteForSite = ssoSite.getRemotePrincipals();
589
590
591 if (principalsForSite == null || remoteForSite== null )
592 throw new SSOException(SSOException.NO_CREDENTIALS_FOR_SITE);
593
594 Collection remoteForPrincipals = getRemotePrincipalsForPrincipal(principalsForSite, fullPath);
595
596 if ( remoteForPrincipals == null)
597 throw new SSOException(SSOException.NO_CREDENTIALS_FOR_SITE);
598
599
600 if ((remotePrincipal = findRemoteMatch(remoteForPrincipals, remoteForSite)) == null )
601 {
602 throw new SSOException(SSOException.NO_CREDENTIALS_FOR_SITE);
603 }
604
605
606 ssoSite.getRemotePrincipals().remove(remotePrincipal);
607
608 if (remoteForPrincipals.remove(remotePrincipal) == true)
609
610
611 getPersistenceBrokerTemplate().store(ssoSite);
612
613
614 getPersistenceBrokerTemplate().delete(remotePrincipal);
615
616
617 }
618 catch(SSOException ssoex)
619 {
620 throw new SSOException(ssoex);
621 }
622 catch (Exception e)
623 {
624 e.printStackTrace();
625
626 mapSite.remove(site);
627 throw new SSOException(SSOException.FAILED_STORING_SITE_INFO_IN_DB + e.toString() );
628 }
629
630
631 try
632 {
633 getPersistenceBrokerTemplate().store(ssoSite);
634 }
635 catch (Exception e)
636 {
637 e.printStackTrace();
638 throw new SSOException(SSOException.FAILED_STORING_SITE_INFO_IN_DB + e.toString() );
639 }
640 finally
641 {
642
643 mapSite.remove(site);
644 }
645
646 }
647
648 /***
649 * updateCredentialsForSite
650 * @param subject Current subject
651 * @param remoteUser remote user login
652 * @param site URL or description of site
653 * @param pwd Password for credentail
654 */
655 public void updateCredentialsForSite(Subject subject, String remoteUser, String site, String pwd)
656 throws SSOException
657 {
658
659
660
661
662 InternalUserPrincipal remotePrincipal = null;
663
664
665 SSOSite ssoSite = getSSOSiteObject(site);
666 if (ssoSite == null)
667 {
668 throw new SSOException(SSOException.NO_CREDENTIALS_FOR_SITE);
669 }
670
671
672 String fullPath = ((BasePrincipal)SecurityHelper.getBestPrincipal(subject, UserPrincipal.class)).getFullPath();
673
674
675 Collection principalsForSite = ssoSite.getPrincipals();
676 Collection remoteForSite = ssoSite.getRemotePrincipals();
677
678
679 if (principalsForSite == null || remoteForSite== null )
680 throw new SSOException(SSOException.NO_CREDENTIALS_FOR_SITE);
681
682 Collection remoteForPrincipals = getRemotePrincipalsForPrincipal(principalsForSite, fullPath);
683
684 if ( remoteForPrincipals == null)
685 throw new SSOException(SSOException.NO_CREDENTIALS_FOR_SITE);
686
687
688 if ((remotePrincipal = findRemoteMatch(remoteForPrincipals, remoteForSite)) == null )
689 {
690 throw new SSOException(SSOException.NO_CREDENTIALS_FOR_SITE);
691 }
692
693
694
695
696 InternalCredential credential = (InternalCredential)remotePrincipal.getCredentials().iterator().next();
697
698
699 if ( credential != null)
700
701 credential.setValue(this.scramble(pwd));
702
703
704 try
705 {
706 getPersistenceBrokerTemplate().store(credential);
707 }
708 catch (Exception e)
709 {
710 e.printStackTrace();
711 throw new SSOException(SSOException.FAILED_STORING_SITE_INFO_IN_DB + e.toString() );
712 }
713 }
714
715
716
717
718
719
720
721
722
723
724
725 private SSOSite getSSOSiteObject(String site)
726 {
727
728 SSOSite ssoSite = null;
729
730
731 if (mapSite.containsKey(site) == false )
732 {
733
734
735
736 Criteria filter = new Criteria();
737 filter.addEqualTo("siteURL", site);
738
739 QueryByCriteria query = QueryFactory.newQuery(SSOSiteImpl.class, filter);
740 Collection ssoSiteCollection = getPersistenceBrokerTemplate().getCollectionByQuery(query);
741
742 if ( ssoSiteCollection != null && ssoSiteCollection.isEmpty() != true)
743 {
744 Iterator itSite = ssoSiteCollection.iterator();
745
746 if (itSite.hasNext())
747 {
748 ssoSite = (SSOSite) itSite.next();
749 }
750
751
752 mapSite.put(site, ssoSite);
753 }
754 else
755 {
756
757 return null;
758 }
759 }
760 else
761 {
762 ssoSite = (SSOSite)mapSite.get(site);
763 }
764
765 return ssoSite;
766 }
767
768
769
770
771
772 private SSOContext getCredential(SSOSite ssoSite, String fullPath)
773 {
774 InternalCredential credential = null;
775 InternalUserPrincipal remotePrincipal = null;
776
777 Collection principalsForSite = ssoSite.getPrincipals();
778 Collection remoteForSite = ssoSite.getRemotePrincipals();
779
780
781 if ( principalsForSite == null || remoteForSite== null )
782 return null;
783
784 Collection remoteForPrincipals = getRemotePrincipalsForPrincipal(principalsForSite, fullPath);
785
786 if ( remoteForPrincipals == null)
787 return null;
788
789
790 if ((remotePrincipal = findRemoteMatch(remoteForPrincipals, remoteForSite)) == null )
791 {
792 return null;
793 }
794 else
795 {
796
797 if ( remotePrincipal.getCredentials() != null)
798 credential = (InternalCredential)remotePrincipal.getCredentials().iterator().next();
799
800
801 if ( credential == null)
802 {
803
804 return null;
805 }
806 }
807
808
809 String name = stripPrincipalName(remotePrincipal.getFullPath());
810
811 SSOContext context = new SSOContextImpl(credential.getPrincipalId(), name, this.unscramble(credential.getValue()));
812
813 return context;
814 }
815
816 private String stripPrincipalName(String fullPath)
817 {
818 String name;
819 int ix = fullPath.lastIndexOf('/');
820 if ( ix != -1)
821 name = fullPath.substring(ix + 1);
822 else
823 name = new String(fullPath);
824
825 return name;
826 }
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860 private SSOPrincipal getPrincipalForSite(SSOSite ssoSite, String fullPath)
861 {
862 SSOPrincipal principal = null;
863 Collection principalsForSite = ssoSite.getPrincipals();
864
865 if ( principalsForSite != null)
866 {
867 Iterator itPrincipals = principalsForSite.iterator();
868 while (itPrincipals.hasNext() && principal == null)
869 {
870 SSOPrincipal tmp = (SSOPrincipal)itPrincipals.next();
871 if ( tmp != null
872 && tmp.getFullPath().compareToIgnoreCase(fullPath) == 0 )
873 principal = tmp;
874 }
875 }
876
877 return principal;
878 }
879
880 private SSOPrincipal getSSOPrincipal(String fullPath)
881 {
882
883 SSOPrincipal principal = null;
884
885 Criteria filter = new Criteria();
886 filter.addEqualTo("fullPath", fullPath);
887
888 QueryByCriteria query = QueryFactory.newQuery(SSOPrincipalImpl.class, filter);
889 Collection principals = getPersistenceBrokerTemplate().getCollectionByQuery(query);
890
891 if ( principals != null && principals.isEmpty() != true)
892 {
893 Iterator itPrincipals = principals.iterator();
894
895 if (itPrincipals.hasNext())
896 {
897 principal = (SSOPrincipal) itPrincipals.next();
898 }
899 }
900
901 return principal;
902 }
903
904
905
906 /***
907 * removeRemotePrincipalForPrincipal
908 * @param site
909 * @param fullPath
910 * @return
911 *
912 * removes remotePrincipal for a site & principal
913 *
914 private InternalUserPrincipal removeRemotePrincipalForPrincipal(SSOSite site, String fullPath) throws SSOException
915 {
916 if (site.getPrincipals() != null)
917 {
918 Iterator itPrincipals = site.getPrincipals().iterator();
919 while (itPrincipals.hasNext())
920 {
921 SSOPrincipal tmp = (SSOPrincipal)itPrincipals.next();
922 if (tmp.getFullPath().compareToIgnoreCase(fullPath) == 0)
923 {
924 // Found -- get the remotePrincipal
925 Collection collRemotePrincipals = tmp.getRemotePrincipals() ;
926 if (collRemotePrincipals != null)
927 {
928
929 Iterator itRemotePrincipals = collRemotePrincipals.iterator();
930 if (itRemotePrincipals.hasNext())
931 {
932 InternalUserPrincipal remotePrincipal = (InternalUserPrincipal)itRemotePrincipals.next();
933 // Found remove the object
934 collRemotePrincipals.remove(remotePrincipal);
935 return remotePrincipal;
936 }
937 }
938 }
939 }
940 }
941
942 throw new SSOException(SSOException.REQUESTED_PRINCIPAL_DOES_NOT_EXIST);
943 }
944 */
945
946
947
948
949
950 private InternalUserPrincipal findRemoteMatch(Collection remoteForPrincipals, Collection remoteForSite)
951 {
952
953 Iterator itRemoteForPrincipals = remoteForPrincipals.iterator();
954 while ( itRemoteForPrincipals.hasNext())
955 {
956 InternalUserPrincipal remoteForPrincipal = (InternalUserPrincipal)itRemoteForPrincipals.next();
957
958
959 Iterator itRemoteForSite = remoteForSite.iterator();
960 while ( itRemoteForSite.hasNext())
961 {
962 InternalUserPrincipal tmp = (InternalUserPrincipal)itRemoteForSite.next();
963
964 if ( tmp.getPrincipalId() == remoteForPrincipal.getPrincipalId() )
965 return remoteForPrincipal;
966 }
967 }
968
969 return null;
970 }
971
972
973
974
975
976
977 private Collection getRemotePrincipalsForPrincipal(Collection principalsForSite, String fullPath)
978 {
979 if (principalsForSite != null )
980 {
981 Iterator itPrincipalsForSite = principalsForSite.iterator();
982 while (itPrincipalsForSite.hasNext())
983 {
984 String principalFullPath = null;
985 SSOPrincipal principal = (SSOPrincipal)itPrincipalsForSite.next();
986 principalFullPath = principal.getFullPath();
987
988
989
990
991
992 if ( principalFullPath.indexOf("/group/") == -1)
993 {
994
995 if ( principalFullPath.compareToIgnoreCase(fullPath) == 0)
996 return principal.getRemotePrincipals();
997 }
998 else
999 {
1000
1001
1002
1003
1004 if ( principalFullPath.compareToIgnoreCase(fullPath) == 0)
1005 return principal.getRemotePrincipals();
1006
1007
1008 InternalGroupPrincipal groupPrincipal = getGroupPrincipals(principalFullPath);
1009
1010
1011 if (groupPrincipal != null)
1012 {
1013 Collection usersInGroup = groupPrincipal.getUserPrincipals();
1014 Iterator itUsers = usersInGroup.iterator();
1015 while (itUsers.hasNext())
1016 {
1017 InternalUserPrincipal user = (InternalUserPrincipal)itUsers.next();
1018 if (user.getFullPath().compareToIgnoreCase(fullPath) == 0)
1019 {
1020
1021 return principal.getRemotePrincipals();
1022 }
1023 }
1024 }
1025 }
1026 }
1027 }
1028
1029
1030 return null;
1031 }
1032
1033 public SSOSite getSite(String siteUrl)
1034 {
1035 Criteria filter = new Criteria();
1036 filter.addEqualTo("url", siteUrl);
1037 Query query = QueryFactory.newQuery(SSOSiteImpl.class, filter);
1038 SSOSite site = (SSOSite) getPersistenceBrokerTemplate().getObjectByQuery(query);
1039 return site;
1040 }
1041
1042 public void updateSite(SSOSite site)
1043 throws SSOException
1044 {
1045 try
1046 {
1047 getPersistenceBrokerTemplate().store(site);
1048 this.mapSite.put(site.getName(), site);
1049 }
1050 catch (Exception e)
1051 {
1052 String msg = "Unable to remove SSO Site: " + site.getName();
1053 logger.error(msg, e);
1054 throw new SSOException(msg, e);
1055 }
1056 }
1057
1058 /***
1059 * Add a new site that uses Form Authentication
1060 * @param siteName
1061 * @param siteUrl
1062 * @param realm
1063 * @param userField
1064 * @param pwdField
1065 * @throws SSOException
1066 */
1067 public void addSiteFormAuthenticated(String siteName, String siteUrl, String realm, String userField, String pwdField)
1068 throws SSOException
1069 {
1070 try
1071 {
1072 SSOSite ssoSite = new SSOSiteImpl();
1073 ssoSite.setSiteURL(siteUrl);
1074 ssoSite.setName(siteName);
1075 ssoSite.setCertificateRequired(false);
1076 ssoSite.setAllowUserSet(true);
1077 ssoSite.setRealm(realm);
1078 ssoSite.setFormAuthentication(true);
1079 ssoSite.setFormUserField(userField);
1080 ssoSite.setFormPwdField(pwdField);
1081 getPersistenceBrokerTemplate().store(ssoSite);
1082 this.mapSite.put(siteName, ssoSite);
1083 }
1084 catch (Exception e)
1085 {
1086 String msg = "Unable to add SSO Site: " + siteName;
1087 logger.error(msg, e);
1088 throw new SSOException(msg, e);
1089 }
1090 }
1091
1092 /***
1093 * Add a new site that uses ChallengeResponse Authentication
1094 * @param siteName
1095 * @param siteUrl
1096 * @param realm
1097 * @throws SSOException
1098 */
1099 public void addSiteChallengeResponse(String siteName, String siteUrl, String realm)
1100 throws SSOException
1101 {
1102 try
1103 {
1104 SSOSite ssoSite = new SSOSiteImpl();
1105 ssoSite.setSiteURL(siteUrl);
1106 ssoSite.setName(siteName);
1107 ssoSite.setCertificateRequired(false);
1108 ssoSite.setAllowUserSet(true);
1109 ssoSite.setRealm(realm);
1110 ssoSite.setChallengeResponseAuthentication(true);
1111 getPersistenceBrokerTemplate().store(ssoSite);
1112 this.mapSite.put(siteName, ssoSite);
1113 }
1114 catch (Exception e)
1115 {
1116 String msg = "Unable to add SSO Site: " + siteName;
1117 logger.error(msg, e);
1118 throw new SSOException(msg, e);
1119 }
1120 }
1121
1122 public void addSite(String siteName, String siteUrl)
1123 throws SSOException
1124 {
1125 try
1126 {
1127 SSOSite ssoSite = new SSOSiteImpl();
1128 ssoSite.setSiteURL(siteUrl);
1129 ssoSite.setName(siteName);
1130 ssoSite.setCertificateRequired(false);
1131 ssoSite.setAllowUserSet(true);
1132 getPersistenceBrokerTemplate().store(ssoSite);
1133 this.mapSite.put(siteName, ssoSite);
1134 }
1135 catch (Exception e)
1136 {
1137 String msg = "Unable to remove SSO Site: " + siteName;
1138 logger.error(msg, e);
1139 throw new SSOException(msg, e);
1140 }
1141 }
1142
1143 public void removeSite(SSOSite site)
1144 throws SSOException
1145 {
1146 try
1147 {
1148 getPersistenceBrokerTemplate().delete(site);
1149 this.mapSite.remove(site);
1150
1151 }
1152 catch (Exception e)
1153 {
1154 String msg = "Unable to remove SSO Site: " + site.getName();
1155 logger.error(msg, e);
1156 throw new SSOException(msg, e);
1157 }
1158 }
1159
1160 public List getPrincipalsForSite(SSOSite site)
1161 {
1162 List list = new ArrayList();
1163 Iterator principals = site.getRemotePrincipals().iterator();
1164 while (principals.hasNext())
1165 {
1166 InternalUserPrincipal remotePrincipal = (InternalUserPrincipal)principals.next();
1167 Iterator creds = remotePrincipal.getCredentials().iterator();
1168 while (creds.hasNext())
1169 {
1170 InternalCredential cred = (InternalCredential) creds.next();
1171 SSOContext context = new SSOContextImpl(remotePrincipal.getPrincipalId(),
1172 stripPrincipalName(remotePrincipal.getFullPath()),
1173 cred.getValue(),
1174 stripPortalPrincipalName(remotePrincipal.getFullPath()));
1175 list.add(context);
1176 }
1177 }
1178 return list;
1179 }
1180
1181
1182 private String stripPortalPrincipalName(String fullPath)
1183 {
1184 StringTokenizer tokenizer = new StringTokenizer(fullPath, "/");
1185 while (tokenizer.hasMoreTokens())
1186 {
1187 String token = tokenizer.nextToken();
1188 if (token.equals("user") || token.equals("group"))
1189 {
1190 if (tokenizer.hasMoreTokens())
1191 {
1192 return tokenizer.nextToken();
1193 }
1194 }
1195 }
1196 return fullPath;
1197 }
1198
1199 private InternalGroupPrincipal getGroupPrincipals(String principalFullPath)
1200 {
1201
1202 Criteria filter = new Criteria();
1203 filter.addEqualTo("fullPath", principalFullPath);
1204 Query query = QueryFactory.newQuery(InternalGroupPrincipalImpl.class, filter);
1205 InternalGroupPrincipal group = (InternalGroupPrincipal) getPersistenceBrokerTemplate().getObjectByQuery(query);
1206 return group;
1207 }
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220 private String getContentFromURL(String proxyID, String destUrl, SSOSite[] sites, boolean bRefresh ) throws SSOException
1221 {
1222 URL urlObj = null;
1223
1224
1225
1226 String resultPage;
1227
1228 String strErrorMessage = "SSO Component Error. Failed to get content for URL " + destUrl;
1229
1230 try
1231 {
1232 urlObj = new URL(destUrl);
1233 }
1234 catch (MalformedURLException e)
1235 {
1236 String msg = ("Error -- Malformed URL [" + destUrl +"] for SSO authenticated destination");
1237 log.error(msg);
1238 throw new SSOException(msg, e);
1239 }
1240
1241
1242
1243
1244
1245 HttpClient client = (HttpClient)this.clientProxy.get(proxyID);
1246 GetMethod get = null;
1247
1248 if (bRefresh == true || client == null)
1249 {
1250 if (log.isInfoEnabled())
1251 log.info("SSO Component -- Create new HTTP Client object for Principal/URL [" + proxyID+ "]");
1252
1253 client = new HttpClient();
1254 client.getState().setCookiePolicy(CookiePolicy.COMPATIBILITY);
1255
1256 int numberOfSites = sites.length;
1257
1258
1259 for (int i=0; i<numberOfSites; i++)
1260 {
1261 SSOSite site = sites[i];
1262
1263 if (site != null)
1264 {
1265 Iterator itRemotePrincipals = site.getRemotePrincipals().iterator();
1266 while (itRemotePrincipals.hasNext() )
1267 {
1268 InternalUserPrincipal remotePrincipal = (InternalUserPrincipal)itRemotePrincipals.next();
1269 if (remotePrincipal != null)
1270 {
1271 InternalCredential credential = null;
1272 if ( remotePrincipal.getCredentials() != null)
1273 credential = (InternalCredential)remotePrincipal.getCredentials().iterator().next();
1274
1275 if (credential != null)
1276 {
1277 if (log.isInfoEnabled())
1278 log.info("SSOComponent -- Remote Principal ["+stripPrincipalName(remotePrincipal.getFullPath())+"] has credential ["+this.unscramble(credential.getValue())+ "]");
1279
1280 client.getState().setCredentials(
1281 site.getRealm(),
1282 urlObj.getHost(),
1283 new UsernamePasswordCredentials(stripPrincipalName(remotePrincipal.getFullPath()), this.unscramble(credential.getValue()))
1284 );
1285
1286
1287 StringBuffer siteURL = new StringBuffer(site.getSiteURL());
1288
1289
1290 if (site.isFormAuthentication())
1291 {
1292 siteURL.append("?").append(site.getFormUserField()).append("=").append(stripPrincipalName(remotePrincipal.getFullPath())).append("&").append(site.getFormPwdField()).append("=").append(this.unscramble(credential.getValue()));
1293 }
1294
1295 get = new GetMethod(siteURL.toString());
1296
1297
1298
1299
1300
1301
1302 get.setDoAuthentication( true );
1303 try {
1304
1305 int status = client.executeMethod( get );
1306
1307 if (log.isInfoEnabled() )
1308 log.info("Accessing site [" + site.getSiteURL() + "]. HTTP Status [" +status+ "]" );
1309
1310
1311
1312
1313
1314
1315 if( destUrl.compareTo(site.getSiteURL()) == 0 && numberOfSites == 1)
1316 {
1317 if (log.isInfoEnabled() )
1318 log.info("SSO Component --SSO Site and destination URL match. Go and get the content." );
1319
1320
1321
1322
1323 resultPage = get.getResponseBodyAsString();
1324
1325
1326
1327
1328
1329
1330
1331 get.releaseConnection();
1332
1333
1334 this.clientProxy.put(proxyID, client);
1335
1336
1337 return resultPage;
1338 }
1339
1340 } catch (Exception e) {
1341 log.error("Exception while authentication. Error: " +e);
1342 }
1343
1344 get.releaseConnection();
1345 }
1346 }
1347 }
1348 }
1349 }
1350
1351
1352 this.clientProxy.put(proxyID, client);
1353 }
1354 else
1355 {
1356 if (log.isInfoEnabled())
1357 log.info("SSO Component -- Use cached HTTP Client object for Principal/URL [" + proxyID+ "]");
1358 }
1359
1360
1361 get = new GetMethod(destUrl);
1362 try {
1363
1364 int status = client.executeMethod( get );
1365
1366 log.info("Accessing site [" + destUrl + "]. HTTP Status [" +status+ "]" );
1367
1368 } catch (Exception e) {
1369 log.error("Exception while authentication. Error: " +e);
1370 }
1371
1372
1373 try
1374 {
1375
1376 resultPage = get.getResponseBodyAsString();
1377 }
1378 catch(IOException ioe)
1379 {
1380 log.error(strErrorMessage, ioe);
1381 throw new SSOException (strErrorMessage, ioe);
1382 }
1383 catch (Exception e)
1384 {
1385 log.error(strErrorMessage, e);
1386 throw new SSOException (strErrorMessage, e);
1387
1388 }
1389 finally
1390 {
1391 get.releaseConnection();
1392 }
1393
1394
1395 return resultPage;
1396 }
1397
1398
1399
1400
1401
1402
1403 static char[] scrambler ="Jestspeed-2 is getting ready for release".toCharArray();
1404
1405 private String scramble(String pwd)
1406 {
1407
1408
1409
1410
1411
1412 String xored = new String(xor(pwd.toCharArray(), scrambler));
1413 byte[] bytes = Base64.encodeBase64(xored.getBytes());
1414 String scrambled = new String(bytes);
1415 return scrambled;
1416 }
1417
1418 private String unscramble(String pwd)
1419 {
1420 byte[] bytes = pwd.getBytes();
1421 bytes = Base64.decodeBase64(bytes);
1422 String chars = new String(bytes);
1423 String unscrambled = new String(xor(chars.toCharArray(), scrambler));
1424 return unscrambled;
1425 }
1426
1427 private char[] xor(char[] a, char[]b)
1428 {
1429 int len = Math.min(a.length, b.length);
1430 char[] result = new char[len];
1431 for(int i=0; i<len;i++)
1432 {
1433 result[i] = (char) (a[i] ^ b[i]);
1434 }
1435 return result;
1436 }
1437 }