...
Dynamic - Individual Metadata files that are checked every 5 minutes for changes and are individually loaded into memory. This is a new option that was added as part of the 1Q15 general Shibboleth code update and reorganization. However, at this time the files designated to be dynamic are initially empty after each release. There is a new Yale Jenkins type of Install operation that changes only these files. Because Shibboleth examines Metadata sources in the order in which they are configured, and it stops when it finds Metadata for the entity for which it is searching, these dynamic Metadata files are distinguished by their position in the search order.
...
- A database query can return exactly one row. Then you can think of the row as a user object, and the column names become the properties of the object. All these properties are Strings (Shibboleth does not have a concept of other data types). NOTE: Oracle always returns column names in UPPERCASE and it is a really, really good idea to always capitalize these names in the configuration file whenever they appear. If you fail to use all caps in one of the later configuration elements, it will fail to match and then you get a null instead of a value.
- A database query can return more than one row but only one column. Then you have a "multivalued" property.
- An LDAP query returns the
- A database query can return more than one row but only one column. Then you have a "multivalued" property for one user.
- An LDAP query returns the User object from the directory. LDAP User objects have properties some of which are single valued and some of which are multivalued.
One other point. The database query can return no rows, or it can return a row where some of the columns have the value NULL. An LDAP query can return no object, or it can return an object that does not have the property name you are interested in, or the property can exist but have no value. For the most part this doesn't matter unless you have to reference the value of the property in JavaScript. If you write JavaScript, remember to test for the property being "undefined", or null, or empty, which are distinct conditions with distinct tests.
Returning no rows or objects is a normal response to a query. A query fails if it generates an ORAxxxx SQLException or a NamingException. Typically this happens if the database server or directory is down, but it can also happen if the userid and password you are using to login to the server is no longer valid or if permissions have been revoked or were never granted to that user.
Shibboleth regards any query failure as catastrophic, unless there is a "failover" DataConnector. The Failover can be a different query to a different database, or it can be a Static default value.
A Static DataConnector defines one or more properties and values. It is not necessary to define a default value for every property that you could have obtained from the correct execution of the real query, provided that a null or undefined value is acceptable for the other properties. Typically Static default values are -1, 0, "", "undefined" but that is up to you. Because query failure is catastrophic without a Fallback
Every Query must have a Static Fallback DataConnector. It is not important what default values, if any, are provided.
Subsequent configuration elements define one or more attributes based on the results of the queries. They specify the name of the query and the name of the database column or LDAP object property from which the value or values are obtained.
Note: Oracle queries return column names that are all UPPERCASE. It is a best practice to use uppercase names in the query and in all subsequent references to the column. If you specify an Oracle column name in lower or mixed case in subsequent XML, then the Java code will fail to match the UPPERCASE name in the Oracle result set and a null or missing value will be returned.
When designing this file, you need to consider certain possibilities:
- The database query can return no rows.
- The database query can return a SQL NULL value for a column (unless you use NVL in Oracle or ISNULL in SQL Server to replace the NULL with a default value).
- An LDAP query can return no User object
- An LDAP query can return a User object, but in that object the property you are looking for may not be present.
- An LDAP query can return a User object, and the property may be present, but it may have no values in the list of values.
First, any value that might be used as a SAML Subject for any Yale person in any login cannot be missing or null for any person at Yale. That makes sense for SAML, but Yale has a few partners who request a particular value be presented as Subject. If the partner only provides data for Employees and it makes no sense for a Student to ever try to login to that partner, you might imagine that this is OK. However, Shibboleth will generate a null pointer exception if any query return NULL for any attribute marked as a possible Subject for any login even if it isn't going to be the Subject in this particular login. So use NVL or ISNULL to replace possibly NULL values with 0 or -1 or "undefined" in such cases.
Then in JavaScript, variables generated from queries with no rows, or no objects, or no property, or NULL can end up being a "undefined" JavaScript variable (a variable that has never been declared with any value) or a defined variable with a value of JavaScript null, or a variable whose value is an object that has no values in its collection of values. Generally speaking, you should always write your JavaScript code to check for all possible bad results, because if you try to test if a variable has the value null when it is really "undefined" you are going to throw an exception. See the Yale code for examples of appropriately paranoid variable testing.
Returning no rows or objects is a normal response to a query. A query fails if it generates an ORAxxxx SQLException or a NamingException. Typically this happens if the database server or directory is down, but it can also happen if the userid and password you are using to login to the server is no longer valid or if permissions have been revoked or were never granted to that user.
The Shibboleth code that executes a query runs in a Java "try-catch" clause. If any exception is thrown during the query, then the Shibboleth code will attempt to execute a secondary query specified in the "failover" attribute of the DataConnector. The failover can point to a different query to a different database that might return the same value. Or it can be a Static element.
A Static DataConnector defines one or more property names and values. It is not necessary to define a default value for every property that you could have obtained from the correct execution of the real query, provided that a null or undefined value is acceptable for the other properties.Given the previous warning about NULL and undefined and empty, you should think twice before leaving column/property names without an explicit default value (0, 1, -1, "", "undefined", etc.). However, it is not an error to omit them if you choose. The Static DataConnector cannot throw an exception.
Every Query must have a Static Fallback DataConnector. Otherwise, if the database is down vanilla Shibboleth throws an exception and the login completely fails, even if this particular user did not need the results of that query to login to the current service.
Yale reorganized its attribute-resolver.xml file to emphasize the importance of a Static Failover for every query.
In vanilla Shibboleth there is no "try-catch" when evaluating attributes except for the special case of SQLExceptions thrown by a database query or NamingExceptions thrown by an LDAP query.
In the new release, the attribute-resolver file has been reorganized to emphasize the Failover relationship, and as part of the testing of the new release we will verify that Shibboleth survives the loss of access to each data source. However, it becomes an ongoing process to ensure that every time a new query is defined, a static Failover is also created and Shib is tested for that failure.
...