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 throw new SSOException(SSOException.FAILED_STORING_SITE_INFO_IN_DB + e.toString() );
626 }
627
628
629 try
630 {
631 getPersistenceBrokerTemplate().store(ssoSite);
632 }
633 catch (Exception e)
634 {
635 e.printStackTrace();
636 throw new SSOException(SSOException.FAILED_STORING_SITE_INFO_IN_DB + e.toString() );
637 }
638
639 }
640
641 /***
642 * updateCredentialsForSite
643 * @param subject Current subject
644 * @param remoteUser remote user login
645 * @param site URL or description of site
646 * @param pwd Password for credentail
647 */
648 public void updateCredentialsForSite(Subject subject, String remoteUser, String site, String pwd)
649 throws SSOException
650 {
651
652
653
654
655 InternalUserPrincipal remotePrincipal = null;
656
657
658 SSOSite ssoSite = getSSOSiteObject(site);
659 if (ssoSite == null)
660 {
661 throw new SSOException(SSOException.NO_CREDENTIALS_FOR_SITE);
662 }
663
664
665 String fullPath = ((BasePrincipal)SecurityHelper.getBestPrincipal(subject, UserPrincipal.class)).getFullPath();
666
667
668 Collection principalsForSite = ssoSite.getPrincipals();
669 Collection remoteForSite = ssoSite.getRemotePrincipals();
670
671
672 if (principalsForSite == null || remoteForSite== null )
673 throw new SSOException(SSOException.NO_CREDENTIALS_FOR_SITE);
674
675 Collection remoteForPrincipals = getRemotePrincipalsForPrincipal(principalsForSite, fullPath);
676
677 if ( remoteForPrincipals == null)
678 throw new SSOException(SSOException.NO_CREDENTIALS_FOR_SITE);
679
680
681 if ((remotePrincipal = findRemoteMatch(remoteForPrincipals, remoteForSite)) == null )
682 {
683 throw new SSOException(SSOException.NO_CREDENTIALS_FOR_SITE);
684 }
685
686
687
688
689 InternalCredential credential = (InternalCredential)remotePrincipal.getCredentials().iterator().next();
690
691
692 if ( credential != null)
693
694 credential.setValue(this.scramble(pwd));
695
696
697 try
698 {
699 getPersistenceBrokerTemplate().store(credential);
700 }
701 catch (Exception e)
702 {
703 e.printStackTrace();
704 throw new SSOException(SSOException.FAILED_STORING_SITE_INFO_IN_DB + e.toString() );
705 }
706 }
707
708
709
710
711
712
713
714
715
716
717
718 private SSOSite getSSOSiteObject(String site)
719 {
720
721 SSOSite ssoSite = null;
722
723
724 if (mapSite.containsKey(site) == false )
725 {
726
727
728
729 Criteria filter = new Criteria();
730 filter.addEqualTo("siteURL", site);
731
732 QueryByCriteria query = QueryFactory.newQuery(SSOSiteImpl.class, filter);
733 Collection ssoSiteCollection = getPersistenceBrokerTemplate().getCollectionByQuery(query);
734
735 if ( ssoSiteCollection != null && ssoSiteCollection.isEmpty() != true)
736 {
737 Iterator itSite = ssoSiteCollection.iterator();
738
739 if (itSite.hasNext())
740 {
741 ssoSite = (SSOSite) itSite.next();
742 }
743
744
745 mapSite.put(site, ssoSite);
746 }
747 else
748 {
749
750 return null;
751 }
752 }
753 else
754 {
755 ssoSite = (SSOSite)mapSite.get(site);
756 }
757
758 return ssoSite;
759 }
760
761
762
763
764
765 private SSOContext getCredential(SSOSite ssoSite, String fullPath)
766 {
767 InternalCredential credential = null;
768 InternalUserPrincipal remotePrincipal = null;
769
770 Collection principalsForSite = ssoSite.getPrincipals();
771 Collection remoteForSite = ssoSite.getRemotePrincipals();
772
773
774 if ( principalsForSite == null || remoteForSite== null )
775 return null;
776
777 Collection remoteForPrincipals = getRemotePrincipalsForPrincipal(principalsForSite, fullPath);
778
779 if ( remoteForPrincipals == null)
780 return null;
781
782
783 if ((remotePrincipal = findRemoteMatch(remoteForPrincipals, remoteForSite)) == null )
784 {
785 return null;
786 }
787 else
788 {
789
790 if ( remotePrincipal.getCredentials() != null)
791 credential = (InternalCredential)remotePrincipal.getCredentials().iterator().next();
792
793
794 if ( credential == null)
795 {
796
797 return null;
798 }
799 }
800
801
802 String name = stripPrincipalName(remotePrincipal.getFullPath());
803
804 SSOContext context = new SSOContextImpl(credential.getPrincipalId(), name, this.unscramble(credential.getValue()));
805
806 return context;
807 }
808
809 private String stripPrincipalName(String fullPath)
810 {
811 String name;
812 int ix = fullPath.lastIndexOf('/');
813 if ( ix != -1)
814 name = fullPath.substring(ix + 1);
815 else
816 name = new String(fullPath);
817
818 return name;
819 }
820
821
822
823
824
825
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 private SSOPrincipal getPrincipalForSite(SSOSite ssoSite, String fullPath)
854 {
855 SSOPrincipal principal = null;
856 Collection principalsForSite = ssoSite.getPrincipals();
857
858 if ( principalsForSite != null)
859 {
860 Iterator itPrincipals = principalsForSite.iterator();
861 while (itPrincipals.hasNext() && principal == null)
862 {
863 SSOPrincipal tmp = (SSOPrincipal)itPrincipals.next();
864 if ( tmp != null
865 && tmp.getFullPath().compareToIgnoreCase(fullPath) == 0 )
866 principal = tmp;
867 }
868 }
869
870 return principal;
871 }
872
873 private SSOPrincipal getSSOPrincipal(String fullPath)
874 {
875
876 SSOPrincipal principal = null;
877
878 Criteria filter = new Criteria();
879 filter.addEqualTo("fullPath", fullPath);
880
881 QueryByCriteria query = QueryFactory.newQuery(SSOPrincipalImpl.class, filter);
882 Collection principals = getPersistenceBrokerTemplate().getCollectionByQuery(query);
883
884 if ( principals != null && principals.isEmpty() != true)
885 {
886 Iterator itPrincipals = principals.iterator();
887
888 if (itPrincipals.hasNext())
889 {
890 principal = (SSOPrincipal) itPrincipals.next();
891 }
892 }
893
894 return principal;
895 }
896
897
898
899 /***
900 * removeRemotePrincipalForPrincipal
901 * @param site
902 * @param fullPath
903 * @return
904 *
905 * removes remotePrincipal for a site & principal
906 *
907 private InternalUserPrincipal removeRemotePrincipalForPrincipal(SSOSite site, String fullPath) throws SSOException
908 {
909 if (site.getPrincipals() != null)
910 {
911 Iterator itPrincipals = site.getPrincipals().iterator();
912 while (itPrincipals.hasNext())
913 {
914 SSOPrincipal tmp = (SSOPrincipal)itPrincipals.next();
915 if (tmp.getFullPath().compareToIgnoreCase(fullPath) == 0)
916 {
917 // Found -- get the remotePrincipal
918 Collection collRemotePrincipals = tmp.getRemotePrincipals() ;
919 if (collRemotePrincipals != null)
920 {
921
922 Iterator itRemotePrincipals = collRemotePrincipals.iterator();
923 if (itRemotePrincipals.hasNext())
924 {
925 InternalUserPrincipal remotePrincipal = (InternalUserPrincipal)itRemotePrincipals.next();
926 // Found remove the object
927 collRemotePrincipals.remove(remotePrincipal);
928 return remotePrincipal;
929 }
930 }
931 }
932 }
933 }
934
935 throw new SSOException(SSOException.REQUESTED_PRINCIPAL_DOES_NOT_EXIST);
936 }
937 */
938
939
940
941
942
943 private InternalUserPrincipal findRemoteMatch(Collection remoteForPrincipals, Collection remoteForSite)
944 {
945
946 Iterator itRemoteForPrincipals = remoteForPrincipals.iterator();
947 while ( itRemoteForPrincipals.hasNext())
948 {
949 InternalUserPrincipal remoteForPrincipal = (InternalUserPrincipal)itRemoteForPrincipals.next();
950
951
952 Iterator itRemoteForSite = remoteForSite.iterator();
953 while ( itRemoteForSite.hasNext())
954 {
955 InternalUserPrincipal tmp = (InternalUserPrincipal)itRemoteForSite.next();
956
957 if ( tmp.getPrincipalId() == remoteForPrincipal.getPrincipalId() )
958 return remoteForPrincipal;
959 }
960 }
961
962 return null;
963 }
964
965
966
967
968
969
970 private Collection getRemotePrincipalsForPrincipal(Collection principalsForSite, String fullPath)
971 {
972 if (principalsForSite != null )
973 {
974 Iterator itPrincipalsForSite = principalsForSite.iterator();
975 while (itPrincipalsForSite.hasNext())
976 {
977 String principalFullPath = null;
978 SSOPrincipal principal = (SSOPrincipal)itPrincipalsForSite.next();
979 principalFullPath = principal.getFullPath();
980
981
982
983
984
985 if ( principalFullPath.indexOf("/group/") == -1)
986 {
987
988 if ( principalFullPath.compareToIgnoreCase(fullPath) == 0)
989 return principal.getRemotePrincipals();
990 }
991 else
992 {
993
994
995
996
997 if ( principalFullPath.compareToIgnoreCase(fullPath) == 0)
998 return principal.getRemotePrincipals();
999
1000
1001 InternalGroupPrincipal groupPrincipal = getGroupPrincipals(principalFullPath);
1002
1003
1004 if (groupPrincipal != null)
1005 {
1006 Collection usersInGroup = groupPrincipal.getUserPrincipals();
1007 Iterator itUsers = usersInGroup.iterator();
1008 while (itUsers.hasNext())
1009 {
1010 InternalUserPrincipal user = (InternalUserPrincipal)itUsers.next();
1011 if (user.getFullPath().compareToIgnoreCase(fullPath) == 0)
1012 {
1013
1014 return principal.getRemotePrincipals();
1015 }
1016 }
1017 }
1018 }
1019 }
1020 }
1021
1022
1023 return null;
1024 }
1025
1026 public SSOSite getSite(String siteUrl)
1027 {
1028 Criteria filter = new Criteria();
1029 filter.addEqualTo("url", siteUrl);
1030 Query query = QueryFactory.newQuery(SSOSiteImpl.class, filter);
1031 SSOSite site = (SSOSite) getPersistenceBrokerTemplate().getObjectByQuery(query);
1032 return site;
1033 }
1034
1035 public void updateSite(SSOSite site)
1036 throws SSOException
1037 {
1038 try
1039 {
1040 getPersistenceBrokerTemplate().store(site);
1041 this.mapSite.put(site.getName(), site);
1042 }
1043 catch (Exception e)
1044 {
1045 String msg = "Unable to remove SSO Site: " + site.getName();
1046 logger.error(msg, e);
1047 throw new SSOException(msg, e);
1048 }
1049 }
1050
1051 /***
1052 * Add a new site that uses Form Authentication
1053 * @param siteName
1054 * @param siteUrl
1055 * @param realm
1056 * @param userField
1057 * @param pwdField
1058 * @throws SSOException
1059 */
1060 public void addSiteFormAuthenticated(String siteName, String siteUrl, String realm, String userField, String pwdField)
1061 throws SSOException
1062 {
1063 try
1064 {
1065 SSOSite ssoSite = new SSOSiteImpl();
1066 ssoSite.setSiteURL(siteUrl);
1067 ssoSite.setName(siteName);
1068 ssoSite.setCertificateRequired(false);
1069 ssoSite.setAllowUserSet(true);
1070 ssoSite.setRealm(realm);
1071 ssoSite.setFormAuthentication(true);
1072 ssoSite.setFormUserField(userField);
1073 ssoSite.setFormPwdField(pwdField);
1074 getPersistenceBrokerTemplate().store(ssoSite);
1075 this.mapSite.put(siteName, ssoSite);
1076 }
1077 catch (Exception e)
1078 {
1079 String msg = "Unable to add SSO Site: " + siteName;
1080 logger.error(msg, e);
1081 throw new SSOException(msg, e);
1082 }
1083 }
1084
1085 /***
1086 * Add a new site that uses ChallengeResponse Authentication
1087 * @param siteName
1088 * @param siteUrl
1089 * @param realm
1090 * @throws SSOException
1091 */
1092 public void addSiteChallengeResponse(String siteName, String siteUrl, String realm)
1093 throws SSOException
1094 {
1095 try
1096 {
1097 SSOSite ssoSite = new SSOSiteImpl();
1098 ssoSite.setSiteURL(siteUrl);
1099 ssoSite.setName(siteName);
1100 ssoSite.setCertificateRequired(false);
1101 ssoSite.setAllowUserSet(true);
1102 ssoSite.setRealm(realm);
1103 ssoSite.setChallengeResponseAuthentication(true);
1104 getPersistenceBrokerTemplate().store(ssoSite);
1105 this.mapSite.put(siteName, ssoSite);
1106 }
1107 catch (Exception e)
1108 {
1109 String msg = "Unable to add SSO Site: " + siteName;
1110 logger.error(msg, e);
1111 throw new SSOException(msg, e);
1112 }
1113 }
1114
1115 public void addSite(String siteName, String siteUrl)
1116 throws SSOException
1117 {
1118 try
1119 {
1120 SSOSite ssoSite = new SSOSiteImpl();
1121 ssoSite.setSiteURL(siteUrl);
1122 ssoSite.setName(siteName);
1123 ssoSite.setCertificateRequired(false);
1124 ssoSite.setAllowUserSet(true);
1125 getPersistenceBrokerTemplate().store(ssoSite);
1126 this.mapSite.put(siteName, ssoSite);
1127 }
1128 catch (Exception e)
1129 {
1130 String msg = "Unable to remove SSO Site: " + siteName;
1131 logger.error(msg, e);
1132 throw new SSOException(msg, e);
1133 }
1134 }
1135
1136 public void removeSite(SSOSite site)
1137 throws SSOException
1138 {
1139 try
1140 {
1141 getPersistenceBrokerTemplate().delete(site);
1142 this.mapSite.remove(site);
1143
1144 }
1145 catch (Exception e)
1146 {
1147 String msg = "Unable to remove SSO Site: " + site.getName();
1148 logger.error(msg, e);
1149 throw new SSOException(msg, e);
1150 }
1151 }
1152
1153 public List getPrincipalsForSite(SSOSite site)
1154 {
1155 List list = new ArrayList();
1156 Iterator principals = site.getRemotePrincipals().iterator();
1157 while (principals.hasNext())
1158 {
1159 InternalUserPrincipal remotePrincipal = (InternalUserPrincipal)principals.next();
1160 Iterator creds = remotePrincipal.getCredentials().iterator();
1161 while (creds.hasNext())
1162 {
1163 InternalCredential cred = (InternalCredential) creds.next();
1164 SSOContext context = new SSOContextImpl(remotePrincipal.getPrincipalId(),
1165 stripPrincipalName(remotePrincipal.getFullPath()),
1166 cred.getValue(),
1167 stripPortalPrincipalName(remotePrincipal.getFullPath()));
1168 list.add(context);
1169 }
1170 }
1171 return list;
1172 }
1173
1174
1175 private String stripPortalPrincipalName(String fullPath)
1176 {
1177 StringTokenizer tokenizer = new StringTokenizer(fullPath, "/");
1178 while (tokenizer.hasMoreTokens())
1179 {
1180 String token = tokenizer.nextToken();
1181 if (token.equals("user") || token.equals("group"))
1182 {
1183 if (tokenizer.hasMoreTokens())
1184 {
1185 return tokenizer.nextToken();
1186 }
1187 }
1188 }
1189 return fullPath;
1190 }
1191
1192 private InternalGroupPrincipal getGroupPrincipals(String principalFullPath)
1193 {
1194
1195 Criteria filter = new Criteria();
1196 filter.addEqualTo("fullPath", principalFullPath);
1197 Query query = QueryFactory.newQuery(InternalGroupPrincipalImpl.class, filter);
1198 InternalGroupPrincipal group = (InternalGroupPrincipal) getPersistenceBrokerTemplate().getObjectByQuery(query);
1199 return group;
1200 }
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213 private String getContentFromURL(String proxyID, String destUrl, SSOSite[] sites, boolean bRefresh ) throws SSOException
1214 {
1215 URL urlObj = null;
1216
1217
1218
1219 String resultPage;
1220
1221 String strErrorMessage = "SSO Component Error. Failed to get content for URL " + destUrl;
1222
1223 try
1224 {
1225 urlObj = new URL(destUrl);
1226 }
1227 catch (MalformedURLException e)
1228 {
1229 String msg = ("Error -- Malformed URL [" + destUrl +"] for SSO authenticated destination");
1230 log.error(msg);
1231 throw new SSOException(msg, e);
1232 }
1233
1234
1235
1236
1237
1238 HttpClient client = (HttpClient)this.clientProxy.get(proxyID);
1239 GetMethod get = null;
1240
1241 if (bRefresh == true || client == null)
1242 {
1243 if (log.isInfoEnabled())
1244 log.info("SSO Component -- Create new HTTP Client object for Principal/URL [" + proxyID+ "]");
1245
1246 client = new HttpClient();
1247 client.getState().setCookiePolicy(CookiePolicy.COMPATIBILITY);
1248
1249 int numberOfSites = sites.length;
1250
1251
1252 for (int i=0; i<numberOfSites; i++)
1253 {
1254 SSOSite site = sites[i];
1255
1256 if (site != null)
1257 {
1258 Iterator itRemotePrincipals = site.getRemotePrincipals().iterator();
1259 while (itRemotePrincipals.hasNext() )
1260 {
1261 InternalUserPrincipal remotePrincipal = (InternalUserPrincipal)itRemotePrincipals.next();
1262 if (remotePrincipal != null)
1263 {
1264 InternalCredential credential = null;
1265 if ( remotePrincipal.getCredentials() != null)
1266 credential = (InternalCredential)remotePrincipal.getCredentials().iterator().next();
1267
1268 if (credential != null)
1269 {
1270 if (log.isInfoEnabled())
1271 log.info("SSOComponent -- Remote Principal ["+stripPrincipalName(remotePrincipal.getFullPath())+"] has credential ["+this.unscramble(credential.getValue())+ "]");
1272
1273 client.getState().setCredentials(
1274 site.getRealm(),
1275 urlObj.getHost(),
1276 new UsernamePasswordCredentials(stripPrincipalName(remotePrincipal.getFullPath()), this.unscramble(credential.getValue()))
1277 );
1278
1279
1280 StringBuffer siteURL = new StringBuffer(site.getSiteURL());
1281
1282
1283 if (site.isFormAuthentication())
1284 {
1285 siteURL.append("?").append(site.getFormUserField()).append("=").append(stripPrincipalName(remotePrincipal.getFullPath())).append("&").append(site.getFormPwdField()).append("=").append(this.unscramble(credential.getValue()));
1286 }
1287
1288 get = new GetMethod(siteURL.toString());
1289
1290
1291
1292
1293
1294
1295 get.setDoAuthentication( true );
1296 try {
1297
1298 int status = client.executeMethod( get );
1299
1300 if (log.isInfoEnabled() )
1301 log.info("Accessing site [" + site.getSiteURL() + "]. HTTP Status [" +status+ "]" );
1302
1303
1304
1305
1306
1307
1308 if( destUrl.compareTo(site.getSiteURL()) == 0 && numberOfSites == 1)
1309 {
1310 if (log.isInfoEnabled() )
1311 log.info("SSO Component --SSO Site and destination URL match. Go and get the content." );
1312
1313
1314
1315
1316 resultPage = get.getResponseBodyAsString();
1317
1318
1319
1320
1321
1322
1323
1324 get.releaseConnection();
1325
1326
1327 this.clientProxy.put(proxyID, client);
1328
1329
1330 return resultPage;
1331 }
1332
1333 } catch (Exception e) {
1334 log.error("Exception while authentication. Error: " +e);
1335 }
1336
1337 get.releaseConnection();
1338 }
1339 }
1340 }
1341 }
1342 }
1343
1344
1345 this.clientProxy.put(proxyID, client);
1346 }
1347 else
1348 {
1349 if (log.isInfoEnabled())
1350 log.info("SSO Component -- Use cached HTTP Client object for Principal/URL [" + proxyID+ "]");
1351 }
1352
1353
1354 get = new GetMethod(destUrl);
1355 try {
1356
1357 int status = client.executeMethod( get );
1358
1359 log.info("Accessing site [" + destUrl + "]. HTTP Status [" +status+ "]" );
1360
1361 } catch (Exception e) {
1362 log.error("Exception while authentication. Error: " +e);
1363 }
1364
1365
1366 try
1367 {
1368
1369 resultPage = get.getResponseBodyAsString();
1370 }
1371 catch(IOException ioe)
1372 {
1373 log.error(strErrorMessage, ioe);
1374 throw new SSOException (strErrorMessage, ioe);
1375 }
1376 catch (Exception e)
1377 {
1378 log.error(strErrorMessage, e);
1379 throw new SSOException (strErrorMessage, e);
1380
1381 }
1382 finally
1383 {
1384 get.releaseConnection();
1385 }
1386
1387
1388 return resultPage;
1389 }
1390
1391
1392
1393
1394
1395
1396 static char[] scrambler ="Jestspeed-2 is getting ready for release".toCharArray();
1397
1398 private String scramble(String pwd)
1399 {
1400
1401
1402
1403
1404
1405 String xored = new String(xor(pwd.toCharArray(), scrambler));
1406 byte[] bytes = Base64.encodeBase64(xored.getBytes());
1407 String scrambled = new String(bytes);
1408 return scrambled;
1409 }
1410
1411 private String unscramble(String pwd)
1412 {
1413 byte[] bytes = pwd.getBytes();
1414 bytes = Base64.decodeBase64(bytes);
1415 String chars = new String(bytes);
1416 String unscrambled = new String(xor(chars.toCharArray(), scrambler));
1417 return unscrambled;
1418 }
1419
1420 private char[] xor(char[] a, char[]b)
1421 {
1422 int len = Math.min(a.length, b.length);
1423 char[] result = new char[len];
1424 for(int i=0; i<len;i++)
1425 {
1426 result[i] = (char) (a[i] ^ b[i]);
1427 }
1428 return result;
1429 }
1430 }