Persistent Federation Data Store
In Federation SSO operations, users are identified by a unique identifier in the SSO message that is then mapped into a local user’s profile by the SP.
Sometimes the unique identifier is an attribute part of the existing LDAP user record, such as the email address or the username, while other times, the identifier only exists for the Federation SSO operation between the SP and IdP for a specific user. In the later case, the identifier and the user it is attached to need to be stored as account linking information in a Federation Data Store.
This article shows how to configure OAM to use an RDBMS as the Federation Data Store.
Important note: A persistent Federation Data Store is only required for cases where the identifiers used in the SSO responses (persistent NameID in SAML 2.0 for example) are used. It is best not to use a persistent Federation Data Store when not needed.
Identifiers in Federation Message
Each Federation protocol uses an identifier to reference the user in the SSO message, though there are variations and differences.
SAML 2.0
SAML 2.0 uses three kinds of identifiers:
-
User attributes:
-
These identifiers are user attributes that are typically know by both SP and IdP and stored in the LDAP user account
-
SAML 2.0 defines the following formats, though in OAM you can use any formats:
-
urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified
-
urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress
-
urn:oasis:names:tc:SAML:1.1:nameid-format:X509SubjectName
-
urn:oasis:names:tc:SAML:1.1:nameid-format:WindowsDomainQualiCedName
-
urn:oasis:names:tc:SAML:2.0:nameid-format:Kerberos
-
-
Typically, using those identifiers does not require a persistent Federation Store, as the values are stored in the LDAP user entry
-
One time identifier
- This is a specific identifier defined in the SAML 2.0 specifications where the IdP creates a random and onetime identifier when creating the assertion. This means that the next time the same user does a Federation SSO operation with the same SP
-
Another random and one-time-use identifier will be used The name of that identifier is transient and defined by
urn:oasis:names:tc:SAML:2.0:nameid-format:transient
Since this is a onetime identifier, this will never be stored in a persistent Federation Store -
Random persistent identifier
-
This identifier is a random string, unique to the triplet IdP/SP/User
-
This identifier will always be the same one sent by the IdP in a SAML 2.0 Assertion for that SP and for that user
-
It needs to be stored in a persistent Federation Store at the IdP, but it is optional for the SP, if the SP is mapping the Assertion to an LDAP user record using SAML Attributes contained in the SAML Assertion
-
Note: With OAM as an IdP, it is possible to use the Persistent
NameID
format and to populate the value based on expressions, the same way otherNameID
formats are used. If theNameID
value field is filled for the PersistentNameID
format in the SP Partner screen, then IdP will use that expression to set theNameID
value.
An example of an Assertion issued by an IdP with an Email Address NameID is:
<samlp:Response ...>
<saml:Issuer ...>https://idp.com/oam/fed</saml:Issuer>
<samlp:Status>
<samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success"/>
</samlp:Status>
<saml:Assertion ...>
<saml:Issuer ...>https://idp.com/oam/fed</saml:Issuer>
<dsig:Signature>
...
</dsig:Signature>
<saml:Subject>
<saml:NameID Format="urn:oasis:names:tc:SAML:1.1:nameidformat:emailAddress">bob@oracle.com</saml:NameID> <saml:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
<saml:SubjectConfirmationData .../>
</saml:SubjectConfirmation> </saml:Subject>
<saml:Conditions ...>
<saml:AudienceRestriction>
<saml:Audience>https://acme.com/sp</saml:Audience>
</saml:AudienceRestriction>
</saml:Conditions>
<saml:AuthnStatement AuthnInstant="2014-03-21T20:53:55Z" SessionIndex="id6i-Dm0yB-HekG6cejktwcKIFMzYE8Yrmqwfd0azz"
SessionNotOnOrAfter="2014-03-21T21:53:55Z">
<saml:AuthnContext>
<saml:AuthnContextClassRef>
urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport
</saml:AuthnContextClassRef>
</saml:AuthnContext>
</saml:AuthnStatement> </saml:Assertion> </samlp:Response>
An example of an Assertion issued by an IdP with a persistent NameID is:
<samlp:Response ...>
<saml:Issuer ...>https://idp.com/oam/fed</saml:Issuer>
<samlp:Status>
<samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success"/>
</samlp:Status>
<saml:Assertion ...>
<saml:Issuer ...>https://idp.com/oam/fed</saml:Issuer>
<dsig:Signature>
...
</dsig:Signature>
<saml:Subject>
<saml:NameID NameQualifier="https://idp.com/oam/fed SPNameQualifier="https://acme.com/sp" Format="urn:oasis:names:tc:SAML:2.0:nameidformat:persistent">id-424129fa23490ded8eab00cc</saml:NameID>
<saml:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
<saml:SubjectConfirmationData .../>
</saml:SubjectConfirmation>
</saml:Subject>
<saml:Conditions ...>
<saml:AudienceRestriction>
<saml:Audience>https://acme.com/sp</saml:Audience>
</saml:AudienceRestriction>
</saml:Conditions>
<saml:AuthnStatement AuthnInstant="2014-03-21T20:53:55Z"
SessionIndex="id-6i-Dm0yB-HekG6cejktwcKIFMzYE8Yrmqwfd0azz"
SessionNotOnOrAfter="2014-03-21T21:53:55Z">
<saml:AuthnContext>
<saml:AuthnContextClassRef>
urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport
</saml:AuthnContextClassRef>
</saml:AuthnContext>
</saml:AuthnStatement>
</saml:Assertion>
</samlp:Response>
SAML 1.1
SAML 1.1 only uses user attributes as NameIDs
:
-
These identifiers are user attributes that are typically know by both SP and IdP and stored in the LDAP user account
-
SAML 1.1 defines the following formats, though in OAM you can use any formats:
-
urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified
-
urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress
-
urn:oasis:names:tc:SAML:1.1:nameid-format:X509SubjectName
-
urn:oasis:names:tc:SAML:1.1:nameid-format:WindowsDomainQualiCedName
There is no need to use a persistent Federation Data Store for SAML 1.1
An example of an Assertion issued by an IdP with an Email Address NameID is:
<samlp:Response>
<samlp:Status>
<samlp:StatusCode Value="samlp:Success"/>
</samlp:Status>
<saml:Assertion Issuer="https://idp.com/oam/fed" ...>
<saml:Conditions ...>
<saml:AudienceRestriction>
<saml:Audience>https://acme.com/sp/ssov11</saml:Audience>
</saml:AudienceRestriction>
</saml:Conditions>
<saml:AuthnStatement AuthenticationInstant="2014-03-21T20:53:55Z"
AuthenticationMethod="urn:oasis:names:tc:SAML:1.0:am:password">
<saml:Subject>
<saml:NameIdentifier Format="urn:oasis:names:tc:SAML:1.1:nameidformat:emailAddress">bob@oracle.com</saml:NameIdentifier>
<saml:SubjectConfirmation>
<saml:ConfirmationMethod>
urn:oasis:names:tc:SAML:1.0:cm:bearer
</saml:ConfirmationMethod>
</saml:SubjectConfirmation>
</saml:Subject>
</saml:AuthnStatement>
<dsig:Signature>
...
</dsig:Signature> </saml:Assertion>
</samlp:Response>
OpenID 2.0
OpenID 2.0 only uses random persistent identifiers as NameIDs
:
-
This identifier is a random string, unique to the triplet IdP/SP/User
-
This identifier will always be the same one sent by the IdP in a OpenID 2.0 SSO
-
Response for that SP and for that user
-
It needs to be stored in a persistent Federation Store at the IdP, but it is optional for the SP, if the SP is mapping the SSO Response to an LDAP user record using OpenID Attributes contained in the OpenID SSO Response
An example of an OpenID SSO Response issued by an IdP is:
https://acme.com/openid?reCd=id-9PKVXZmRxAeDYcgLqPm36ClzOMA-&openid.ns=http%3A%2F%2Fspecs.openid.net%2Fauth%2F2.0&openid.mode=id_res&openid.op_endpoint=https%3A%2F%2Fidp.com%2Fopenid&openid.claimed_id=https%3A%2F%2Fidp.com%2Fopenid%3Fid%3Did-38iCmmlAVEXPsFjnFVKArfn5RIiF75D5doorhEgqqPM%3D&openid.identity=https%3A%2F%2Fidp.com%2Fopenid%3Fid%3Did-38iCmmlAVEXPsFjnFVKArfn5RIiF75D5doorhEgqqPM%3D&openid.return_to=https%3A%2F%2Facme.com%2Fopenid%3FreCd%3Did9PKVXZmRxAeDYcgLqPm36ClzOMA-&openid.response_nonce=2014-03-24T19%3A20%3A06ZidYPa2kTNNFftZkgBb460jxJGblk2g--iNwPpDI7M1&openid.assoc_handle=id6a5S6zhAKaRwQNUnjTKROREdAGSjWodG1el4xyz3&openid.ns.ax=http%3A%2F%2Fopenid.net%2Fsrv%2Fax%2F1.0&openid.ax.mode=fetch_response&openid.ax.type.attr0=http%3A%2F%2Fsession%2Fcount&openid.ax.value.attr0=1&openid.ax.type.attr1=http%3A%2F%2Fopenid.net%2Fschema%2FnamePerson%2Ffriendly&openid.ax.value.attr1=My+name+is+Bobby+Smith&openid.ax.type.attr2=http%3A%2F%2Fschemas.openid.net%2Fax%2Fapi%2Fuser_id&openid.ax.value.attr2=bob&openid.ax.type.attr3=http%3A%2F%2Faxschema.org%2Fcontact%2Femail&openid.ax.value.attr3=bob%40oracle.com&openid.ax.type.attr4=http%3A%2F%2Fsession%2Fipaddress&openid.ax.value.attr4=10.145.120.253&openid.ns.pape=http%3A%2F%2Fspecs.openid.net%2Fextensions%2Fpape%2F1.0&openid.pape.auth_time=2014-03-24T19%3A20%3A05Z&openid.pape.auth_policies=http%3A%2F%2Fschemas.openid.net%2Fpape%2Fpolicies%2F2007%2F06%2Fphishing-resistant&openid.signed=op_endpoint%2Cclaimed_id%2Cidentity%2Creturn_to%2Cresponse_nonce%2Cassoc_handle%2Cns.ax%2Cax.mode%2Cax.type.attr0%2Cax.value.attr0%2Cax.type.attr1%2Cax.value.attr1%2Cax.type.attr2%2Cax.value.attr2%openid.sig=mYMgbGYSs22l8e%2FDom9NRPw15u8%3D
Federation Data Store
As seen earlier, a Federation Data Store is required for the following use cases:
-
IdP
-
SAML 2.0 when using Persistent NameID format
-
OpenID 2.0
-
SP
-
SAML 2.0 when using Persistent NameID format and not mapping the user via
-
SAML Attributes
-
OpenID 2.0 and not mapping the user via OpenID SSO Attributes
A Federation Data Store is used to store Account Linking Information which is made of:
-
The user ID
-
The opaque identifier used
-
The
ProviderID
of the remote partner for which the opaque identifier was created
IdP
As an IdP, the Federation Data Store is required in order to send the same unique opaque identifier that was randomly generated the first time the user performed a Federation SSO operation between the IdP and the SP.
OAM is capable of sending a unique opaque identifier for SAML 2.0 Persistent NameID format and OpenID 2.0 which will be the SHA-256 hash of the:
-
Canonical User ID
(OAM ID Store Name + User's DN + UserID)
-
SP ProviderID
This feature allows the use of SAML 2.0 Persistent NameID format and OpenID 2.0 without having to enable a Federation Data Store (see later on how to configure OAM)
SP
As an SP, the Federation Data Store is required if the incoming SSO response is not mapped via SSO Response/user attributes. In this case, the Account Linking Information needs to be present in the Federation Data Store in order for the SP to be able to successfully complete the operation. If the Account Linking Information does not exist, the SP must challenge and authenticate locally the user to determine its identity and create an Account Linking Information in the Federation Data Store (User + Opaque Identifier + IdP ProviderID
).
The flow at the SP would then be:
-
IdP redirects user to SP with SSO response and opaque identifier
-
SP attempts to locate the Account Linking Information entry in the Federation Data Store by performing a query based on the opaque identifier and the IdP’s
ProviderID
-
If the query returns an Account Linking Information entry, the SP extracts the user ID from the entry and create a session for that user
-
If the query does not return an Account Linking Information entry
-
The SP initiates a local login operation to authenticate the user
-
Once the user is locally authenticated, the SP creates an Account Linking Information entry with
-
UserID
-
Opaque Identifier
-
IdP’s
ProviderID
-
Configuring OAM to use a Federation Data Store
Out of the box, OAM is not configured to use a persistent Federation Data Store. So an error is thrown if
-
OpenID 2.0 SSO is used
-
SAML 2.0 Persistent NameID format not based on expressions (that is, the NameID value field in the SP Partner screen is empty) is used
Note: As mentioned earlier, IdP can be configured to populate the OpenID 2.0 and SAML 2.0 Persistent NameID with an opaque value based on the SHA-256 hash of the
userID
and SP’sProviderID
, thus not requiring a Federation Data Store. More on this in the next section.
RDBMS
The only supported Federation Data Store is an RDBMS, where the OAM schema exists, and the RDBMS needs to be defined as a JDBC datasource in the WLS server where
OAM is running
-
Either use the jdbc/oamds JDBC datasource created during installation and referencing the OAM database used to store policy and session data
-
Or
-
Install a new DB, create the OAM schema via RCU
-
Define a new JDBC datasource in WLS for the WLS managed servers where OAM is running
The ORAFEDPROVIDERFED database table contains the Account Linking Information entries:
-
idpProvidedNameIDValue
is the identifier value -
providerID
is the ProviderID of the remote partner -
userID
is the canonical User ID (OAM ID Store Name + User’s DN + UserID) -
federationType
is the type of Federation -
1: OAM acts as an IdP and the remote partner is an SP
-
3: OAM acts as an SP and the remote partner is an IdP
-
idpProvidedNameIDVersionString
is the protocol version (SAML2.0 or OpenID2.0) -
userDescription is the
userID
-
fedID
is a unique identifier for this Account Linking Information entry
Note: Only OpenID 2.0 and SAML 2.0 Persistent NameID values must be stored in the Federation Data Store
Configuration
To configure OAM to use a Federation Data Store, perform the following steps:
-
Enter the WLST environment by executing:
$IAM_ORACLE_HOME/common/bin/wlst.s
-
Connect to the WLS Admin server:
connect()
-
Navigate to the Domain Runtime branch:
domainRuntime()
-
Execute the
setFederationStore
WLST command:setFederationStore(enable, jndiname="jdbc/oamds")
-
To enable the Federation Data Store:
-
Set enable to true
-
Set the optional
jndiname
parameter referencing the JDBC Datasource to use. If missing, the OAM JDBC Datasource is used.
-
-
To disable the Federation Data Store:
-
Set enable to true
An example is:
setFederationStore("false")
-
-
Exit the WLST environment:
exit()
An example is: setFederationStore("true")
Testing with OAM as an IdP
In this test, OAM acts as an IdP with a SAML 2.0 SP partner.
To configure IdP to generate random persistent identifiers that must be stored in the Federation Data Store instead of using LDAP user attributes to populate the NameID value, perform the following steps:
-
Enter the WLST environment by executing:
$IAM_ORACLE_HOME/common/bin/wlst.sh
-
Connect to the WLS Admin server:
connect()
-
Navigate to the Domain Runtime branch:
domainRuntime()
-
Execute the
setSPSAMLPartnerNameID
WLST command:setSPSAMLPartnerNameID(partnerName, nameIDFormat, nameIDValue="", customFormat="", nameIDValueComputed="false")
-
partnerName
will be the SP Partner Name -
nameIDFormat
will be set to orafed-persistent -
nameIDValue
will be left empty. If not empty, then IdP uses the expression to populate the NameID value instead of generating a random persistent identifier
-
- Exit the WLST environment:
exit()
An example is: setSPSAMLPartnerNameID("acmeSP", "orafed-persistent")
Executing the following SQL query in an empty ORAFEDPROVIDERFED
table would not return any data:
SQL> select idpProvidedNameIDValue, providerID, userID, federationType, idpProvidedNameIDVersionString, userDescription, fedID from ORAFEDPROVIDERFED
IDPPROVIDE PROVIDERID USERID FEDERATIONTYPE IDPPROVID USERDESC FEDID
After performing Federation SSO with the remote partner SP, executing the query once again shows the new entry:
SQL> select idpProvidedNameIDValue, providerID, userID, federationType, idpProvidedNameIDVersionString, userDescription, fedID from ORAFEDPROVIDERFED
IDPPROVIDE PROVIDERID | USERID | FEDERATIONTYPE | IDPPROVID | USERDESC FEDID |
---|---|---|---|---|
id-s-l3991 | http://acme.c oud-e2e:USER: | 1 SAML2.0 | alice | id-KKqR2Cl |
Ut7JEyggvf | om/sp | cn=alice,ou=u | GnUAGhRLA | |
IoPavO7Huj | sers,dc=us,dc | MzXZMx3UGj | ||
6H0UvFvEec | =oracle,dc=co | cMSQge9Nhh | ||
Wwq | m:alice | Nme |
Testing with OAM as an SP
In this test, OAM acts as an SP with a SAML 2.0 IdP partner.
To configure OAM/SP to use the Federation Data Store when mapping the incoming SAML 2.0/OpenID 2.0 SSO Response, perform the following steps:
-
Enter the WLST environment by executing:
$IAM_ORACLE_HOME/common/bin/wlst.sh
-
Connect to the WLS Admin server:
connect()
-
Navigate to the Domain Runtime branch:
domainRuntime()
-
Execute the
setPartnerIDStoreAndBaseDN
WLST command:setPartnerIDStoreAndBaseDN(partnerName, partnerType, storeName="", searchBaseDN="", delete="false")
-
partnerName
will be the IdP Partner Name -
partnerType
will be set to idp -
storeName
will be set toFederationStore
-
searchBaseDN
and delete will not be setAn example is:
-
- Exit the WLST environment:
exit()
setPartnerIDStoreAndBaseDN("acmeIdP", "idp", "FederationStore")
Important: When OAM/SP performs a Federation SSO with an IdP partner using the SAML 2.0 Persistent NameID or OpenID 2.0 with the Federation Data Store, if the account linking information for the user and that IdP does not exist yet, OAM/SP will need to challenge and authenticate locally the user to be able to create that account linking information entry. The subsequent times, that user won’t be challenged anymore since the account linking information entry will already exists.
Executing the following SQL query in an empty ORAFEDPROVIDERFED table would not return any data:
SQL> select idpProvidedNameIDValue, providerID, userID, federationType, idpProvidedNameIDVersionString, userDescription, fedID from ORAFEDPROVIDERFED
IDPPROVIDE PROVIDERID USERID FEDERATIONTYPE IDPPROVID USERDESC FEDID
After performing Federation SSO with the remote partner IdP and after the user authenticates locally in order to be able to create the account linking information entry, executing the query once again shows the new entry:
SQL> select idpProvidedNameIDValue, providerID, userID, federationType, idpProvidedNameIDVersionString, userDescription, fedID from ORAFEDPROVIDERFED
IDPPROVIDE | PROVIDERID | USERID | FEDERATIONTYPE | IDPPROVID | USERDESC | FEDID |
---|---|---|---|---|---|---|
id-2eCUlO4 | http://acme.c | oud-e2e:USER: | 3 SAML2.0 | alice | id-VVSIks6 | |
gekO2rgZfe | om/idp | cn=alice,ou=u | hzG2szNPyI | |||
YoZkof8YUM | sers,dc=us,dc | T5ccRf8dzy | ||||
=oracle,dc=co | NL0DZjDbGg | |||||
m:alice | c-0 |
Configuring IdP to use a Hash as Name
In case OAM acts as an IdP using SAML 2.0 Persistent NameID and/or OpenID 2.0 based on opaque identifiers and not LDAP user attributes, the server can be configured to populate the NameID based on the SHA-256 hash of the following data:
-
Canonical User ID (OAM ID Store Name + User’s DN + UserID)
-
SP
ProviderID
-
Protocol version used
To configure IdP to use SHA-256 hash of the above data to populate the NameID, perform the following steps:
-
Enter the WLST environment by executing:
$IAM_ORACLE_HOME/common/bin/wlst.sh
-
Connect to the WLS Admin server:
connect()
-
Navigate to the Domain Runtime branch:
domainRuntime()
-
Execute the
setSPSAMLPartnerNameID
WLST command:setSPSAMLPartnerNameID(partnerName, nameIDFormat, nameIDValue="", customFormat="", nameIDValueComputed="false")
-
partnerName
will be the SP Partner Name -
nameIDFormat
will be set to orafed-persistent -
nameIDValue
will be left empty. If not empty, then IdP will use the expression to populate the NameID value instead of generating a random persistent identifier -
nameIDValueComputed
will be set to trueAn example is:
setSPSAMLPartnerNameID("acmeSP", "orafed-persistent", nameIDValueComputed="true")
-
-
Exit the WLST environment:
exit()
That way, IdP is not required to be configured to use a Federation Data Store (no need to execute setFederationStore("true")
to enable DB as the Federation Data Store), in order to perform Federation SSO with:
-
SAML 2.0 with opaque Persistent NameID
-
OpenID 2.0
More Learning Resources
Explore other labs on docs.oracle.com/learn or access more free learning content on the Oracle Learning YouTube channel. Additionally, visit education.oracle.com/learning-explorer to become an Oracle Learning Explorer.
For product documentation, visit Oracle Help Center.
Persistent Federation Data Store
F61375-01
September 2022
Copyright © 2022, Oracle and/or its affiliates.