The SP includes a plugin for storing persistent information, including user sessions, in a database using an ODBC driver. It's very challenging to get even a simple ODBC "client" application to work across databases, even on Windows. For Linux/Unix, it's approaching the impossible.
Before trying to use this pluginextension, strongly consider whether it's really necessary. Most applications worth clustering are not going to be able to rely on the SP's built-in session functionality. It's there primarily for simple web sites and smaller applications.
Even if you do need clustered sessions, a better option may be to run a single shibd
instance and share it using a private network between the machines. It's a single point of failure, but so is a database in most cases.
However, if you insist on trying this, here Included below are the basic steps for getting a database session storage system setup. (If you have experience with a specific database, please provide any information down below.) The thing to remember is that the plugin is written to work with a fully ACID database that is providing 100% serializable transactions. This means taking locks on reads to prevent another transaction from updating the record until the plugin is done with it. To my knowledge, only a few databases do that (and Oracle isn't one of them). The result will be a lot of trial and error to adjust other settings to compensate, so expect problems.
Database Setup
The first thing you have to do is get a database ready. The plugin odbc-store.so extension requires a database to store the shared sessions. The odbc-store.so extension does not automatically create any tables for itself, so you have to prepare it. The rough SQL DDL for the database is the following:
...
You may need to adjust data types when moving between database systems, but this has to be done carefully to maintain compatibility. The SQL itself is not yet pulled out of the plugin code, so you can't change it without changing the code.
...
The default configuration file comes with some comments to help set this up. You'll need to uncomment the <OutOfProcess>
/<Extensions>
element containing the odbc-store.so
extension. Then you'll need to comment out the four elements grouped together that manage in-memory storage and uncomment the four below them that are labeled with the ODBC comment.
Code Block | ||||
---|---|---|---|---|
| ||||
<OutOfProcess logger="shibd.logger">
<Extensions>
<Library path="odbc-store.so" fatal="true"/>
</Extensions>
</OutOfProcess> |
Database Notes
Finally, apart from adjusting any of the timeout controls, you'll have to put the right connection string into the <ConnectionString>
element.
...
Microsoft SQL Server
This is the primary test platform, and has been tested under only light load on both Windows and CentOS 5 (x86_64). On Linux, the freetds FreeTDS client and ODBC driver from the OS were used.
The simplest way to set this up is to use the SQL Server or freetds FreeTDS client and define a server alias so you can give the server a logical name. A typical connection string would then be:
...
Tested under light load on CentOS 5 (x86_64) using TCP to connect to a database on the same box. The latest ODBC driver from MySQL was used (although the installation of the RPM wasn't perfect).
The connection string looked may look like as simple as this:
Code Block |
---|
DRIVER=MySql;OPTION=65536 |
The cryptic OPTION argument above tells ODBC to look for MySql configuration files for connection data. Hence you should create a MySql config file (ie. /etc/mysql/conf.d/odbc.cnf
) accordingly, and make it readable by the user running shibd (eg. _shibd
) only.
Code Block |
---|
[odbc]
host = dbhost
user = shibboleth
password = secret
database = shibboleth |
Alternatively, you can also specify the DSN in the main config file, though it's insecure:
Code Block |
---|
DRIVER=MySQL;SERVER=sp.example.org;DATABASE=shibboleth;USER=root;PASSWORD=password |
...
Code Block | ||||
---|---|---|---|---|
| ||||
<SessionInitiator type="Chaining" Location="/Login" isDefault="true" id="Default" relayState="ss:db" forceAuthn="true" entityID=""> <SessionInitiator type="SAML2" acsIndex="1" template="bindingTemplate.html"/> </SessionInitiator> <LogoutInitiator type="Chaining" Location="/Logout" relayState="ss:db"> <LogoutInitiator type="SAML2" template="bindingTemplate.html"/> <LogoutInitiator type="Local"/> </LogoutInitiator> |
...