rogerrut 2004/12/04 14:28:19
Modified: components/sso/src/java/org/apache/jetspeed/sso/impl
SSOSiteImpl.java PersistenceBrokerSSOProvider.java
components/sso/src/test/org/apache/jetspeed/sso
TestSSOComponent.java
components/sso/src/java/META-INF sso_repository.xml
Log:
Fix for SSO
Entries where not unique to a user/site which required an new association
table (SSO_SITE_TO_REMOTE)
Re factored the code for the API to include the mapping table
Updated Unit test
Revision Changes Path
1.5 +16 -3
jakarta-jetspeed-2/components/sso/src/java/org/apache/jetspeed/sso/impl/SSOSiteImpl.java
Index: SSOSiteImpl.java
===================================================================
RCS file:
/home/cvs/jakarta-jetspeed-2/components/sso/src/java/org/apache/jetspeed/sso/impl/SSOSiteImpl.java,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- SSOSiteImpl.java 30 Nov 2004 18:19:10 -0000 1.4
+++ SSOSiteImpl.java 4 Dec 2004 22:28:19 -0000 1.5
@@ -43,8 +43,9 @@
private boolean isAllowUserSet;
private boolean isCertificateRequired;
- private Collection credentials = new Vector();//= new ArrayList(0);
- private Collection principals = new Vector();// = new ArrayList(0);
+ private Collection credentials = new Vector();
+ private Collection principals = new Vector();
+ private Collection remotePrincipals = new Vector();
/**
*
@@ -246,4 +247,16 @@
}
}
+ /**
+ * @return Returns the remotePrincipals.
+ */
+ public Collection getRemotePrincipals() {
+ return remotePrincipals;
+ }
+ /**
+ * @param remotePrincipals The remotePrincipals to set.
+ */
+ public void setRemotePrincipals(Collection remotePrincipals) {
+ this.remotePrincipals = remotePrincipals;
+ }
}
1.9 +179 -106
jakarta-jetspeed-2/components/sso/src/java/org/apache/jetspeed/sso/impl/PersistenceBrokerSSOProvider.java
Index: PersistenceBrokerSSOProvider.java
===================================================================
RCS file:
/home/cvs/jakarta-jetspeed-2/components/sso/src/java/org/apache/jetspeed/sso/impl/PersistenceBrokerSSOProvider.java,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -r1.8 -r1.9
--- PersistenceBrokerSSOProvider.java 3 Dec 2004 23:53:33 -0000 1.8
+++ PersistenceBrokerSSOProvider.java 4 Dec 2004 22:28:19 -0000 1.9
@@ -83,18 +83,32 @@
return false; // no entry for site
}
-
// Get the principal from the subject
BasePrincipal principal =
(BasePrincipal)SecurityHelper.getBestPrincipal(subject, UserPrincipal.class);
String fullPath = principal.getFullPath();
- // Check if the principal has any remote principals
- Collection remotePrincipals =
getRemotePrincipalsForPrincipal(ssoSite, fullPath);
+ // Get remotePrincipals for Site and match them with the Remote
Principal for the Principal attached to site
+ Collection principalsForSite = ssoSite.getPrincipals();
+ Collection remoteForSite = ssoSite.getRemotePrincipals();
+
+ // If any of them don't exist just return
+ if (principalsForSite == null || remoteForSite== null )
+ return false; // no entry
+
+ Collection remoteForPrincipals =
getRemotePrincipalsForPrincipal(principalsForSite, fullPath);
- if (remotePrincipals == null || remotePrincipals.size() < 1)
- return false; // No remote credentials for Principal
+ if ( remoteForPrincipals == null)
+ return false; // no entry
+
+ // Get remote Principal that matches the site and the principal
+ if (FindRemoteMatch(remoteForPrincipals, remoteForSite) == null
)
+ {
+ return false; // No entry
+ }
else
- return true; // User has credentials for site
+ {
+ return true; // Has an entry
+ }
}
/* (non-Javadoc)
@@ -148,10 +162,29 @@
// Add an entry for the principal to the site if it doesn't
exist
SSOPrincipal principal = this.getPrincipalForSite(ssoSite,
fullPath);
+ if (principal == null )
+ {
+ principal = getSSOPrincipa(fullPath);
+ ssoSite.addPrincipal(principal);
+ }
+ else
+ {
+ // Check if the entry the user likes to update exists
already
+ Collection remoteForSite = ssoSite.getRemotePrincipals();
+ if ( remoteForSite != null)
+ {
+ if (FindRemoteMatch(principal.getRemotePrincipals(),
remoteForSite) != null )
+ {
+ // Entry exists can't to an add has to call update
+ throw new
SSOException(SSOException.REMOTE_PRINCIPAL_EXISTS_CALL_UPDATE);
+ }
+ }
+ }
+
if (principal == null)
throw new
SSOException(SSOException.FAILED_ADDING_PRINCIPAL_TO_MAPPING_TABLE_FOR_SITE);
- // Create a remote principal and add it to the principal
+ // Create a remote principal and credentials
InternalUserPrincipalImpl remotePrincipal = new
InternalUserPrincipalImpl(remoteUser);
remotePrincipal.setFullPath("/sso/user/"+ principalName + "/" +
remoteUser);
@@ -164,9 +197,12 @@
remotePrincipal.setCredentials(new ArrayList(0));
remotePrincipal.getCredentials().add( credential);
-
-
- principal.addRemotePrincipal(remotePrincipal);
+
+ // Add it to Principals remotePrincipals list
+ principal.addRemotePrincipal(remotePrincipal);
+
+ // Update the site remotePrincipals list
+ ssoSite.getRemotePrincipals().add(remotePrincipal);
// Update database and reset cache
try
@@ -182,7 +218,6 @@
this.mapSite.put(site, ssoSite);
// Clear cache
//this.mapSite.clear();
-
}
/* (non-Javadoc)
@@ -207,17 +242,31 @@
try
{
- // Remove remote principal from the association table
- remotePrincipal =
removeRemotePrincipalForPrincipal(ssoSite, fullPath);
+ // Get remotePrincipals for Site and match them
with the Remote Principal for the Principal attached to site
+ Collection principalsForSite = ssoSite.getPrincipals();
+ Collection remoteForSite =
ssoSite.getRemotePrincipals();
+
+ // If any of them don't exist just return
+ if (principalsForSite == null || remoteForSite== null )
+ throw new
SSOException(SSOException.NO_CREDENTIALS_FOR_SITE);
- // Remove the principal association
- principal = this.getPrincipalForSite(ssoSite, fullPath);
- if ( principal != null )
- ssoSite.getPrincipals().remove(principal);
-
- // Remove Remote principal and associated credential
from persistence store
- if (remotePrincipal != null)
-
getPersistenceBrokerTemplate().delete(remotePrincipal);
+ Collection remoteForPrincipals =
getRemotePrincipalsForPrincipal(principalsForSite, fullPath);
+
+ if ( remoteForPrincipals == null)
+ throw new
SSOException(SSOException.NO_CREDENTIALS_FOR_SITE);
+
+ // Get remote Principal that matches the site and the
principal
+ if ((remotePrincipal =
FindRemoteMatch(remoteForPrincipals, remoteForSite)) == null )
+ {
+ throw new
SSOException(SSOException.NO_CREDENTIALS_FOR_SITE);
+ }
+
+ // Update assocation tables
+ ssoSite.getRemotePrincipals().remove(remotePrincipal);
+ getRemotePrincipalsForPrincipal(principalsForSite,
fullPath).remove(remotePrincipal);
+
+ // delete the remote Principal from the
SECURITY_PRINCIPAL table
+ getPersistenceBrokerTemplate().delete(remotePrincipal);
}
catch(SSOException ssoex)
@@ -230,7 +279,7 @@
throw new
SSOException(SSOException.FAILED_STORING_SITE_INFO_IN_DB + e.toString() );
}
- // Update database and reset cache
+ // Update database
try
{
getPersistenceBrokerTemplate().store(ssoSite);
@@ -272,15 +321,25 @@
String fullPath =
((BasePrincipal)SecurityHelper.getBestPrincipal(subject,
UserPrincipal.class)).getFullPath();
String principalName =
((BasePrincipal)SecurityHelper.getBestPrincipal(subject,
UserPrincipal.class)).getName();
- // Get collection of remote principals and find a match
for the one to remove
- Collection remotePrincipals =
getRemotePrincipalsForPrincipal(ssoSite, fullPath);
- if ( remotePrincipals == null ||
remotePrincipals.size() < 1)
- throw new
SSOException(SSOException.REQUESTED_PRINCIPAL_DOES_NOT_EXIST);
-
- // User can have one remote user per site
- Iterator itRemotePrincipals =
remotePrincipals.iterator();
- remotePrincipal =
(InternalUserPrincipal)itRemotePrincipals.next();
+ // Get remotePrincipals for Site and match them
with the Remote Principal for the Principal attached to site
+ Collection principalsForSite = ssoSite.getPrincipals();
+ Collection remoteForSite =
ssoSite.getRemotePrincipals();
+
+ // If any of them don't exist just return
+ if (principalsForSite == null || remoteForSite== null )
+ throw new
SSOException(SSOException.NO_CREDENTIALS_FOR_SITE);
+
+ Collection remoteForPrincipals =
getRemotePrincipalsForPrincipal(principalsForSite, fullPath);
+ if ( remoteForPrincipals == null)
+ throw new
SSOException(SSOException.NO_CREDENTIALS_FOR_SITE);
+
+ // Get remote Principal that matches the site and the
principal
+ if ((remotePrincipal =
FindRemoteMatch(remoteForPrincipals, remoteForSite)) == null )
+ {
+ throw new
SSOException(SSOException.NO_CREDENTIALS_FOR_SITE);
+ }
+
// Update principal information
remotePrincipal.setFullPath("/sso/user/"+ principalName
+ "/" + remoteUser);
InternalCredential credential =
(InternalCredential)remotePrincipal.getCredentials().iterator().next();
@@ -299,11 +358,7 @@
{
e.printStackTrace();
throw new
SSOException(SSOException.FAILED_STORING_SITE_INFO_IN_DB + e.toString() );
- }
-
- // Clear cache
- // this.mapSite.clear();
-
+ }
}
/*
@@ -366,60 +421,43 @@
private SSOContext getCredential(SSOSite ssoSite, String fullPath)
{
InternalCredential credential = null;
+ InternalUserPrincipal remotePrincipal = null;
String remoteUser = null;
String remoteFullPath = null;
+
+ // Get remotePrincipals for Site and match them with the
Remote Principal for the Principal attached to site
+ Collection principalsForSite = ssoSite.getPrincipals();
+ Collection remoteForSite = ssoSite.getRemotePrincipals();
+
+ // If any of them don't exist just return
+ if (principalsForSite == null || remoteForSite== null )
+ return null; // no entry
+
+ Collection remoteForPrincipals =
getRemotePrincipalsForPrincipal(principalsForSite, fullPath);
- /* Error checking
- * 1) should have at least one principal
- *
- * If one of the above fails return null wich means that the
user doesn't have credentials for that site
- */
- Collection principals = ssoSite.getPrincipals();
+ if ( remoteForPrincipals == null)
+ return null; // no entry
- if ( principals == null )
+ // Get remote Principal that matches the site and the principal
+ if ((remotePrincipal = FindRemoteMatch(remoteForPrincipals,
remoteForSite)) == null )
{
- return null;
+ return null; // No entry
}
-
- // Iterate over the principals and extract the principal id for
the given full path
- SSOPrincipal principal = null;
-
- Iterator itPrincipals = principals.iterator();
- while (itPrincipals.hasNext() && principal == null /*not found
yet*/)
+ else
{
- SSOPrincipal tmp = (SSOPrincipal)itPrincipals.next();
- if ( tmp != null
- &&
tmp.getFullPath().compareToIgnoreCase(fullPath) == 0
- && tmp.getSiteID() == ssoSite.getSiteId())
+ // Has an entry
+ if ( remotePrincipal.getCredentials() != null)
+ credential =
(InternalCredential)remotePrincipal.getCredentials().iterator().next();
+
+ // Error checking -- should have a credential at this
point
+ if ( credential == null)
{
- // Found it stop iteration
- principal = tmp;
+ System.out.println("Warning: Remote User " +
remotePrincipal.getFullPath() + " doesn't have a credential");
+ return null;
}
}
- if ( principal == null)
- return null; // No principal found for that site
-
- // Extract the remote principal
- Collection remotePrincipals = principal.getRemotePrincipals();
- if (remotePrincipals == null || remotePrincipals.size() < 1)
- return null; // no remote principals
-
- InternalUserPrincipal remotePrincipal =
(InternalUserPrincipal)remotePrincipals.iterator().next();
-
- // Get credentail for this remote user
- if ( remotePrincipal.getCredentials() != null)
- credential =
(InternalCredential)remotePrincipal.getCredentials().iterator().next();
-
- // Error checking -- should have a credential at this point
- if ( credential == null)
- {
- System.out.println("Warning: Remote User " +
remotePrincipal.getFullPath() + " doesn't have a credential");
- return null;
- }
-
-
- // Create new context
+ // Create new context
String name = remotePrincipal.getFullPath();
int ix = name.lastIndexOf('/');
if ( ix != -1)
@@ -479,36 +517,30 @@
}
}
- // Not yest in the site list. Add it but make sure that a user
exists
- if ( principal == null)
- {
- Criteria filter = new Criteria();
- filter.addEqualTo("fullPath", fullPath);
-
- QueryByCriteria query =
QueryFactory.newQuery(SSOPrincipalImpl.class, filter);
- Collection principals =
getPersistenceBrokerTemplate().getCollectionByQuery(query);
-
- if ( principals != null && principals.isEmpty() != true)
+ return principal;
+ }
+
+ private SSOPrincipal getSSOPrincipa(String fullPath)
+ {
+ // FInd if the principal exists in the SECURITY_PRINCIPAL table
+ SSOPrincipal principal = null;
+
+ Criteria filter = new Criteria();
+ filter.addEqualTo("fullPath", fullPath);
+
+ QueryByCriteria query =
QueryFactory.newQuery(SSOPrincipalImpl.class, filter);
+ Collection principals =
getPersistenceBrokerTemplate().getCollectionByQuery(query);
+
+ if ( principals != null && principals.isEmpty() != true)
+ {
+ Iterator itPrincipals = principals.iterator();
+ // Get the site from the collection. There should be only one
entry (uniqueness)
+ if (itPrincipals.hasNext())
{
- Iterator itPrincipals = principals.iterator();
- // Get the site from the collection. There should be
only one entry (uniqueness)
- if (itPrincipals.hasNext())
- {
- principal = (SSOPrincipal) itPrincipals.next();
- try
- {
- // Set the Site ID for this principal
- principal.setSiteID(ssoSite.getSiteId());
- ssoSite.addPrincipal(principal);
- }
- catch (SSOException ssoex)
- {
- System.out.println("ERROR-SSO: Failed
adding principal to principla map. Error: " + ssoex.getMessage());
- }
- }
+ principal = (SSOPrincipal) itPrincipals.next();
}
- }
-
+ }
+
return principal;
}
@@ -572,5 +604,46 @@
}
throw new
SSOException(SSOException.REQUESTED_PRINCIPAL_DOES_NOT_EXIST);
+ }
+
+ /*
+ *
+ *
+ */
+ private InternalUserPrincipal FindRemoteMatch(Collection
remoteForPrincipals, Collection remoteForSite)
+ {
+ // Iterate over the lists and find match
+ Iterator itRemoteForPrincipals = remoteForPrincipals.iterator();
+ while ( itRemoteForPrincipals.hasNext())
+ {
+ InternalUserPrincipal remoteForPrincipal =
(InternalUserPrincipal)itRemoteForPrincipals.next();
+
+ // Find a match in the site list
+ Iterator itRemoteForSite = remoteForSite.iterator();
+ while ( itRemoteForSite.hasNext())
+ {
+ InternalUserPrincipal tmp =
(InternalUserPrincipal)itRemoteForSite.next();
+
+ if ( tmp.getPrincipalId() ==
remoteForPrincipal.getPrincipalId() )
+ return remoteForPrincipal;
+ }
+ }
+ // No match found
+ return null;
+ }
+
+ private Collection getRemotePrincipalsForPrincipal(Collection
principalsForSite, String fullPath)
+ {
+ if (principalsForSite == null )
+ return null;
+
+ Iterator itPrincipalsForSite = principalsForSite.iterator();
+ while (itPrincipalsForSite.hasNext())
+ {
+ SSOPrincipal principal =
(SSOPrincipal)itPrincipalsForSite.next();
+ if ( principal.getFullPath().compareToIgnoreCase(fullPath) == 0)
+ return principal.getRemotePrincipals();
+ }
+ return null;
}
}
1.7 +34 -3
jakarta-jetspeed-2/components/sso/src/test/org/apache/jetspeed/sso/TestSSOComponent.java
Index: TestSSOComponent.java
===================================================================
RCS file:
/home/cvs/jakarta-jetspeed-2/components/sso/src/test/org/apache/jetspeed/sso/TestSSOComponent.java,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- TestSSOComponent.java 4 Dec 2004 05:11:38 -0000 1.6
+++ TestSSOComponent.java 4 Dec 2004 22:28:19 -0000 1.7
@@ -49,8 +49,10 @@
* test url for this UnitTest
*/
static private String TEST_URL= "http://localhost/jetspeed";
+ static private String TEST_URL2= "http://localhost/jetspeed-2";
static private String TEST_USER= "joe";
static private String REMOTE_USER= "remoteJS";
+ static private String REMOTE_USER2= "remoteJS-2";
static private String REMOTE_PWD_1 = "remote_1";
static private String REMOTE_PWD_2 = "remote_2";
@@ -99,11 +101,12 @@
* Test user root.
* </p>
*/
- public void testSSO() throws Exception
+ /* public void testSSO() throws Exception
{
// TODO: FIXME: test fails on HSQL Oracle
}
- public void XXXtestSSO() throws Exception
+ */
+ public void testSSO() throws Exception
{
// Create a user
try
@@ -143,9 +146,37 @@
System.out.println("SSO Credential found for user:" +
TEST_USER+ " site: " + TEST_URL);
}
+ // Add another remote principal for the same user
+ if ( ssoBroker.hasSSOCredentials(subject, TEST_URL2) == false)
+ {
+ System.out.println("No SSO Credential for user:" + TEST_USER+ "
site: " + TEST_URL2);
+
+ // Add credential
+ try
+ {
+ ssoBroker.addCredentialsForSite(subject, REMOTE_USER2,
TEST_URL2,REMOTE_PWD_1);
+ System.out.println("SSO Credential added for user:" +
TEST_USER+ " site: " + TEST_URL2);
+ }
+ catch(SSOException ssoex)
+ {
+ System.out.println("SSO Credential add FAILED for
user:" + TEST_USER+ " site: " + TEST_URL2);
+ ssoex.printStackTrace();
+ throw new Exception(ssoex.getMessage());
+ }
+ }
+ else
+ {
+ System.out.println("SSO Credential found for user:" +
TEST_USER+ " site: " + TEST_URL2);
+ }
+
+ // Test if the credential where persisted
+
// Test credential update
SSOContext ssocontext = ssoBroker.getCredentials(subject, TEST_URL);
- System.out.println("SSO Credential: User:" + ssocontext.getUserName() +
" Password: " + ssocontext.getPassword());
+ System.out.println("SSO Credential: User:" + ssocontext.getUserName() +
" Password: " + ssocontext.getPassword()+ " for site: " + TEST_URL);
+
+ SSOContext ssocontext2 = ssoBroker.getCredentials(subject, TEST_URL2);
+ System.out.println("SSO Credential: User:" + ssocontext.getUserName() +
" Password: " + ssocontext.getPassword() + " for site: " + TEST_URL2);
try
{
1.5 +14 -0
jakarta-jetspeed-2/components/sso/src/java/META-INF/sso_repository.xml
Index: sso_repository.xml
===================================================================
RCS file:
/home/cvs/jakarta-jetspeed-2/components/sso/src/java/META-INF/sso_repository.xml,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- sso_repository.xml 3 Dec 2004 21:59:15 -0000 1.4
+++ sso_repository.xml 4 Dec 2004 22:28:19 -0000 1.5
@@ -157,6 +157,20 @@
<fk-pointing-to-this-class column="SITE_ID"/>
<fk-pointing-to-element-class column="PRINCIPAL_ID"/>
</collection-descriptor>
+ <collection-descriptor
+ name="remotePrincipals"
+
element-class-ref="org.apache.jetspeed.security.om.impl.InternalUserPrincipalImpl"
+ proxy="true"
+ refresh="true"
+ auto-retrieve="true"
+ auto-update="object"
+ auto-delete="object"
+ indirection-table="SSO_SITE_TO_REMOTE"
+ >
+ <documentation>This is the reference to
principals.</documentation>
+ <fk-pointing-to-this-class column="SITE_ID"/>
+ <fk-pointing-to-element-class column="PRINCIPAL_ID"/>
+ </collection-descriptor>
</class-descriptor>
</descriptor-repository>
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]