Overview
The JDBCStorageService is a database-level compatible replacement for the JPAStorageService and provides a Storage Service on top of an RDBMS. It communicates directly with the database rather than using Hibernate ORM which has issues with reliability and the lack of provenance of its software artifacts.
It is possible to swap between the JPA and JDBC storage service, and indeed to have different versions running on different nodes.
The JPA Storage Service will be removed in V5 of the IdP, due in 2023. Please migrate prior to that point.
Plugin Installation
Starting with IdP 4.2 you can the install the latest plugin version supported on your IdP version with.\plugin.sh -I net.shibboleth.plugin.storage.jdbc
Plugin ID | Module(s) | Latest Version | Bug Reporting |
---|---|---|---|
net.shibboleth.plugin.storage.jdbc | None | 2.0.0; download |
For a detailed guide on how to install plugins, see here.
In summary, use the plugin
command that ships with the IdP to install the plugin from either a local file pre-downloaded, from a URL or by pluginId 4.2
Installation
C:>\opt\shibboleth-idp\bin\plugin.bat -I net.shibboleth.plugin.storage.jdbc
or
$ /opt/shibboleth-idp/bin/plugin.sh -i http://shibboleth.net/downloads/identity-provider/plugins/pluginName/version/URL
Switching from JPAStorageService
If you are currently running with the JPAStorageService you can reconfigure to use the JDBCStorageService relatively easily
Locate the configuration (search for the class name
org.opensaml.storage.impl.JPAStorageService
Remove the EntityManagerFactory bean, taking note of the
dataSource
property.Remove also the VendorAdapter bean if present.
Change the StorageService bean
Replace
class="org.opensaml.storage.impl.JPAStorageService"
withparent="shibboleth.JDBCStorageService"
Remove the constructor parameter and instead add a pointer to the dataSource you noted above
p:dataSource-ref="...."
At this stage you should be able to test the configuration.
Once it works you can change bean names appropriately and add any extra configuration as detailed below.
Database Preparation
If you are not upgrading from a JPAStorageService configuration you need to:
Create the database table for the plugin to use.
Download the appropriate JDBC driver.
(Optionally, but recommended) Download a Connection Pooling implementation.
If you are moving from the JPAStorageService you do not need to make any changes to your database and you can use the same configuration for the DataSource as you did for the JPAStorageService.
Creating the Database
Example Schemas are shown below
Whatever you do, you MUST ensure the context and id columns are case-sensitively handled and compared. That is a requirement of the API that will be using the database. This is frequently NOT the default behavior of databases such as MySQL.
The specific examples that follow should NOT be assumed to be functional, as they likely are the product of different sources, varying amounts of testing (including none), and may not be current. Drivers get updated frequently and JDBC and database bugs appear and disappear with regularity. When in doubt, always grab new ones when problems appear.
The value column must be arbitrarily wide to allow the JDBC storage service to back IdP Sessions
JDBC Driver
You need to locate, download and verify the JDBC driver for your database and place it in edit-webapp/WEB-INF/lib. After populating edit-webapp/WEB-INF/lib you should execute bin/build.sh or bin/build.bat as appropriate for your environment.
Connection Pooling
We recommend the use of a DataSource that provides connection pooling, which may require installing an additional library as well.
The following libraries provide connection pooling functionality:
Having located, downloaded and verified the connection pooling jar you should place it in edit-webapp/WEB-INF/lib. After populating edit-webapp/WEB-INF/lib you should execute bin/build.sh or bin/build.bat as appropriate for your environment
Configuration
You need to add the definition of a bean derived from shibboleth.JDBCStorageService
into an appropriate configuration file (usually global.xml). The options you can provide to the bear are detailed below.
Examples
In the example below use of Commons DBCP is demonstrated (class="org.apache.commons.dbcp.BasicDataSource", p:url="..."
in the DataSource bean). When using other Connection Pool implementations change the class and properties appropriately, e.g.:
Tomcat DBCP2:
class="org.apache.tomcat.dbcp.dbcp2.BasicDataSource", p:url="..."
Tomcat JDBC Pool:
class="org.apache.tomcat.jdbc.pool.DataSource", p:url="..."
HikariCP:
class="com.zaxxer.hikari.HikariDataSource", p:jdbcUrl="..."
<bean id="my.dataSource" class="org.apache.commons.dbcp2.BasicDataSource" destroy-method="close" lazy-init="true" p:driverClassName="......" p:url="jdbc:hsqldb:mem:StorageService" p:username="shibboleth" p:retryableErrors="4001, 4002" p:password="%{JDBCPassword}" /> <bean id="JDBCStorageService" parent="shibboleth.JDBCStorageService" p:dataSource-ref="dataSource" p:transactionIsolation="4" p:retryableErrors="40001" />