shibboleth-dev - Re: JNDI data connector and DN-based searches
Subject: Shibboleth Developers
List archive
- From: Brent Putman <>
- To:
- Subject: Re: JNDI data connector and DN-based searches
- Date: Mon, 26 Sep 2005 10:34:22 -0400
In case anyone was actually interested enough to look at this... I
realized later that I had a bone-headed error with the provider URL
stuff. A fixed version of the full patch is attached. It also now
allows both the %PRINCIPAL% and %DN% macros to appear in both the
search filter and JNDI provider URL, and also cleans up the way some of
the errors and exceptions are reported. Comments welcome. Thanks, Brent Brent Putman wrote: This question over on shib-users brought up again something that I have encountered in the past: the general need within the resolver to use the value of a user's DN (obtained in an initial LDAP search) in a second search that has the first as a dependency. I saw that in 1.3 in the JNDIDirectoryDataConnector, the DN value is now nicely being placed in the resolved attribute set (when using Sun's LDAP provider), but it still seems like you would have to write a custom connector to actually make use of it. If I'm missing something there let me know... |
===================================================================
RCS file:
/home/cvs/shibboleth/shibboleth/java/src/edu/internet2/middleware/shibboleth/aa/attrresolv/provider/JNDIDirectoryDataConnector.java,v
retrieving revision 1.18
diff -u -r1.18 JNDIDirectoryDataConnector.java
--- JNDIDirectoryDataConnector.java 21 Aug 2005 11:42:03 -0000 1.18
+++ JNDIDirectoryDataConnector.java 26 Sep 2005 07:35:18 -0000
@@ -70,6 +70,7 @@
private static Logger log =
Logger.getLogger(JNDIDirectoryDataConnector.class.getName());
protected String searchFilter;
+ protected String providerURL;
protected Properties properties;
protected SearchControls controls;
protected boolean mergeMultiResults = false;
@@ -140,6 +141,8 @@
throw new ResolutionPlugInException("Property
is malformed.");
} else {
properties.setProperty(propName, propValue);
+ if
(propName.equals("java.naming.provider.url"))
+ providerURL = propValue;
}
}
@@ -148,8 +151,12 @@
try {
if (!startTls) {
try {
- log.debug("Attempting to connect to
JNDI directory source as a sanity check.");
- context = initConnection();
+ if ( !
providerURL.contains("%PRINCIPAL%") && ! providerURL.contains("%DN%")) {
+ log.debug("Attempting to
connect to JNDI directory source as a sanity check.");
+ context = initConnection();
+ } else {
+ log.debug("Bypassing JNDI
fail-fast test because provider URL contains a '%PRINCIPAL%' or '%DN%'
macro");
+ }
} catch (IOException ioe) {
log.error("Failed to startup
directory context: " + ioe);
throw new
ResolutionPlugInException("Failed to startup directory context.");
@@ -185,8 +192,12 @@
sslc.init(new
KeyManager[]{keyManager}, null, new SecureRandom());
sslsf = sslc.getSocketFactory();
- log.debug("Attempting to connect to
JNDI directory source as a sanity check.");
- initConnection();
+ if ( !
providerURL.contains("%PRINCIPAL%") && ! providerURL.contains("%DN%")) {
+ log.debug("Attempting to
connect to JNDI directory source as a sanity check.");
+ initConnection();
+ } else {
+ log.debug("Bypassing JNDI
fail-fast test because provider URL contains a '%PRINCIPAL%' or '%DN%'
macro");
+ }
} catch (GeneralSecurityException gse) {
log.error("Failed to startup
directory context. Error creating SSL socket: " + gse);
throw new
ResolutionPlugInException("Failed to startup directory context.");
@@ -299,6 +310,74 @@
InitialDirContext context = null;
NamingEnumeration nEnumeration = null;
String populatedSearch =
searchFilter.replaceAll("%PRINCIPAL%", principal.getName());
+
+ String populatedProviderURL = null;
+ if (providerURL.contains("%PRINCIPAL%")) {
+ populatedProviderURL =
providerURL.replaceAll("%PRINCIPAL%", principal.getName());
+ // TODO may need to encode/escape this string
further, if it has spaces, etc
+ properties.setProperty("java.naming.provider.url",
populatedProviderURL);
+ log.debug("JNDI provider URL macro substitution on
'%PRINCIPAL%' for principal ("
+ + principal.getName() + ") resulted
in '" + populatedProviderURL + "'");
+ } else {
+ populatedProviderURL = providerURL;
+ }
+
+ if (populatedSearch.contains("%DN%") ||
populatedProviderURL.contains("%DN%") ) {
+ Iterator connectorDependIt =
connectorDependencyIds.iterator();
+ Attribute attr = null;
+ boolean foundDN = false;
+ while (connectorDependIt.hasNext()) {
+ Attributes attrs =
depends.getConnectorResolution((String) connectorDependIt.next());
+ if (attrs != null) {
+ attr = attrs.get("dn");
+ // TODO: Break out when find the
first dn attribute - there can be only one...
+ // or maybe should loop over
them all.. or throw an error if multi ???
+ if (attr != null) {
+ foundDN = true;
+ break;
+ }
+ }
+ }
+
+ if (!foundDN) {
+ log.error("Unable to resolve a 'dn' attribute
value from data connector dependencies " +
+ "for '%DN%' for principal ("
+ principal.getName() + ")" );
+ throw new ResolutionPlugInException("Unable
to resolve a 'dn' value for '%DN%'.");
+ }
+
+ if (attr != null) {
+ // There should only be one value for dn
+ String dn = null;
+ try {
+ dn = (String) attr.get();
+ }
+ catch (NamingException e) {
+ log.error("An error occurred while
obtaining 'dn' attribute dependency data for principal ("
+ + principal.getName()
+ ") :" + e.getMessage());
+ throw new
ResolutionPlugInException("Problem obtaining 'dn' attribute value from
resolved data connector dependency");
+ }
+ if (!dn.equals("")) {
+ populatedSearch =
populatedSearch.replaceAll("%DN%", dn);
+ if
(populatedProviderURL.contains("%DN%")) {
+ populatedProviderURL =
populatedProviderURL.replaceAll("%DN%", dn);
+ // TODO may need to
encode/escape this string further, if it has spaces, etc
+
properties.setProperty("java.naming.provider.url", populatedProviderURL);
+ log.debug("JNDI provider URL
macro substitution on '%DN%' for principal ("
+ + principal.getName()
+ ") resulted in '" + populatedProviderURL + "'");
+ }
+ } else {
+ log.error("Found an empty 'dn'
attribute value for '%DN%' for principal ("
+ + principal.getName()
+ ")");
+ throw new
ResolutionPlugInException("Found an empty 'dn' value for '%DN%'");
+ }
+ } else {
+ log.error("Found a null 'dn' attribute value
for '%DN%' for principal ("
+ + principal.getName() + ")" );
+ throw new ResolutionPlugInException("Found a
null 'dn' value for '%DN%'.");
+ }
+ }
+
+
try {
try {
context = initConnection();
- JNDI data connector and DN-based searches (was: 2 interesting questions), Brent Putman, 09/23/2005
- Re: JNDI data connector and DN-based searches, Brent Putman, 09/26/2005
Archive powered by MHonArc 2.6.16.