SAML SSO
- 1 SAML SSO
- 2 Logging in with Local Accounts
- 3 Using SamlSso Authentication
- 4 Setup
- 5 Encrypted Assertions
- 6 Example: Configuring Okta SAML SSO with FIN
- 6.1 1. Configure HTTP/HTTPS Settings in FIN
- 6.2 2. Enable the SAML SSO Module in FIN
- 6.3 3. Gather FIN Metadata for Okta
- 6.4 4. Create the Okta SAML Application
- 6.4.1 SAML Settings
- 6.5 5. Assign Users and Groups in Okta
- 6.6 6. Configure Attribute Statements
- 6.6.1 Username Attribute
- 6.6.2 Groups Attribute
- 6.7 7. Collect Okta Metadata URL
- 6.8 8. Create User Groups in FIN
- 6.9 9. Import Okta Metadata into FIN
- 6.10 10. Configure Remaining SAML Settings in FIN
- 6.11 11. Restart FIN
- 6.12 12. Test Okta SSO
- 7 Video
SAML SSO
The SAML SSO AuthMod incorporates single sign-on functionality into the login process:
Enables single sign-on (SSO) functionality via SAML allowing users to skip the standard FIN username/password login page if they are already logged in to their SSO environment.
User record tags can be dynamically mapped or updated during SAML login with a user prototype.
FIN uses the HTTP Redirect Binding for logging in to the Identity Provider (IdP).
Currently, the SAML configuration must be performed manually because there is no UI available yet.
Logging in with Local Accounts
After setting up SAML, navigating to the FIN Uri will automatically attempt SAML login via single sign-on so the standard FIN login page will not be displayed. During initial setup or in the rare instance where the FIN host is having communication issues with the SAML server, it may be necessary to login with a local FIN user account. To login with local FIN accounts, such as the su account created during setup, access {FIN URL:port}/user/login directly, which will display the standard FIN user login page (bypassing single sign-on).
Using SamlSso Authentication
After configuring SamlSso, users will no longer see the standard login page when they navigate to the FIN Server Url (unless the Uri described in Local Account Login is accessed directly). The SamlSso AuthMod will verify SAML assertions sent by the IdP to authenticate the user and read configured attributes from the assertion to authorize the user.
FIN provides flexibility in how user records are managed when using SAML. User roles and access filters can be managed entirely in the FIN User app or users can be synthesized during login by mapping the user to a configured prototype in FIN and using the synthesized user to create a local user record. Therefore, users do not need to be setup prior to login, but FIN can be configured to require that a local user record exists. Review the details of the Login Update Mode setting for more information.
Setup
The following steps are required to configure SAML SSO authentication:
Enable the samlSso SysMod
Identify required user attributes (see SAML Attributes)
Enter the required SAML Settings (see SAML SSO Settings)
Configure one or more user prototypes for SAML (see User Group Mapping)
Configure IdP (see SAML IdP Configuration)
If using the
authOnlyLogin Update Mode, theuserAuthtag must be set toAuthMod - samlSso
IMPORTANT: If there are already local user records created in the FIN user database that will now use SAML, the userAuth tag must be manually changed to AuthMod - samlSso.
SAML Attributes
Two attributes must be included in an Assertion sent by the IdP:
The attribute (
samlResponseUsernameAttribute) that identifies the username of the user.The attribute (
userProtoAttr) that identifies what prototype to map the user to in FIN. If a default prototype is configured, this attribute is not required.
Record the names of these attributes as they must be configured in FIN.
IMPORTANT: When configuring the attributes, make sure the value of Name is used, not FriendlyName.
In the example below from a SAML attribute statement, this attribute has a FriendlyName of uid and a Name of urn:oid:0.9.2342.19200300.100.1.1. In FIN, the value that must be configured for the samlResponseUsernameAttribute is urn:oid:0.9.2342.19200300.100.1.1 assuming this is the attribute that will be used to identify the username.
<saml2:Attribute FriendlyName="uid"
Name="urn:oid:0.9.2342.19200300.100.1.1"
NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"
>
<saml2:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:type="xsd:string"
>samlusername</saml2:AttributeValue>
</saml2:Attribute>
SAML Settings
The easiest way to configure SAML, is by using the SAML IdP Metadata. FIN can import the IdP Metadata from a Uri.
In Folio > Launch run this query:
samlImportIdPMetadataUri({uri:`<metadata url goes here>`})FIN will read the XML document and automatically configure the host, port, tls, idpLoginPath, and idpEntityId settings. FIN will also automatically import the IdP Signing Certificate(s) to verify digitally signed assertions sent by the IdP. FIN requires all messages sent from the IdP to be digitally signed.
After the import, the samlResponseUsernameAttribute and userProtoAttr must be manually configured with the names identified in the SAML Attributes section. The userProtoPriority setting must also be manually configured. See the group example for guidance on how to configure the userProtoPriority setting.
autoUpdateIdPMetadataUri - Read Only setting configured via Import IdP Metadata Action. This setting is used to identify the Uri that will be used to check for and automatically update IdP Signing Certs. The IdP Metadata must be digitally signed to support the auto update workflow. If the IdP Metadata is not digitally signed or the IdP Metadata was imported via Text, no Uri will be displayed and auto updates will not occur.
host - Enter the hostname or IP address of the SAML server.
Example:
saml.acme.com
port - Enter the port of the SAML server
tls - Use TLS to connect to the SAML server
idpLoginPath - Path to the login HTTP REDIRECT binding on the IdP.
idpEntityId - Entity ID of the IdP, which will be verified by FIN in each message.
loginUpdateMode - See Login Update Mode for details.
samlResponseUsernameAttribute - Required The attribute in the SAML assertion to use for the synthesized user's username.
userProtoAttr - When using updateOnLogin loginUpdateMode, this setting is Required unless userProtoDefault is configured. This setting defines the attribute in the user's SAML assertion that is used to determine the user's prototype. See User Group Mapping for details.
userProtoPriority - When using updateOnLogin loginUpdateMode, this setting is Required unless userProtoDefault is configured. If a user maps to multiple user prototypes, this list specifies the priority of which one should be chosen. See User Group Mapping for details.
userProtoDefault - Optional setting. If a user cannot be mapped to a prototype via the
userProtoAttr, then use the prototype with this name as the default.applyTagsFunc - Optional setting. Axon callback function used to set/change tags on a user before a session is created. The function should take two parameters (user, attrs) where
useris the current User tags (with prototype already applied) andattrsis the SAML assertion attributes Dict for that user. Return the updated User Dict. See Example applyTagsFunc.supportText - Optional setting. Fandoc formatted text that will display on samlSso/authFailed page that can be used to help users troubleshoot login issues.
Login Update Mode
The SAML mod can be configured to interact with users in the user database in several, flexible ways. Choose the option that meets the project requirements:
authOnly: ( default ) SAML will only be used for authenticating the user. The user must exist in the user database in order to log in.updateOnLogin: Creates or updates the user database rec every time the user logs in by applying the configured prototype and invoking the 'applyTagsFunc' (if configured). The user rec is only updated if the prototype assignment changes, or tags are modified by the the 'applyTagsFunc'.
User Groups Mapping (user prototypes)
When a user successfully authenticates using SamlSso, the user is not prompted for a username or password so the SAML assertion is used to lookup a FIN User in the local user database. If a local user record cannot be found and Login Update Mode is configured to updateOnLogin then to construct a valid user, an authenticated user must be mapped to a User Group.
Create the user groups required for the host.
Configure the
samlSsoUserProtoAttrVal(string tag) for each group that will be used for SamlSso.The value of this tag is used to help the SamlExt determine which user prototypes a SamlSso user maps to. The SamlExt will check the values of the 'userProtoAttr' (as configured in the Saml SSO settings)
After a user is authenticated using SamlSso, the SamlExt looks up the user's attribute in the SAML assertion.
When reading the user's attributes SAML assertion, if one of them matches this tag's value, then this prototype is a potential match for the user attempting to log in.
Configure one or more user groups as a comma separated list (enter
shortName (userProtoName)of eachgrouprecord) for theuserProtoPrioritysetting.Optionally configure a default user prototype (enter
shortName (userProtoName)ofgrouprecord) so users can still login when they cannot be mapped to an existing prototype. As a best practice, this prototype should have an operator role and limited access.
Group Example
SAML SSO Settings:
userProtoAttr: "FINUserPrototype"
userProtoPriority:"engineering, si, default"Groups
id: @engineering
userProto
userProtoName: "engineering"
dis:"Engineering"
userRole:"admin"
samlSsoUserProtoAttrVal: "Engineering"
id: @si
userProto
userProtoName: "si"
dis:"System Integrator"
userRole:"op"
samlSsoUserProtoAttrVal: "SI"
appAccess: "energy"SAML assertion for user bob (represented as a Dict for clarity).
username: "bob"
email: "bob@company.com"
FINUserPrototype: "SI"
... other attributes ...User
bobauthenticates via SamlSso.The SamlExt will determine the username from the SAML assertion is
bob.The SamlExt now checks prototype priorities specified by the
userProtoPrioritysetting in order to try and find the best prototype match for bob:The first prototype in this list is
engineering. ThesamlSsoUserProtoAttrValfor this prototype isEngineering. This value is not in theFINUserPrototypelist specified in Bob's SAML assertion.The next prototype in the list is
si. ThesamlSsoUserProtoAttrValfor this prototype isSI. This value is in theFINUserPrototypelist for Bob.The
siprototype is used to create a synthetic user for Bob's session and Bob is successfully logged in. (Bob will be an operator with access only to the energy app).
NOTE: It is an error for a user to exist in the local user database with a username that matches the username of a user logging in via SamlSso. If this condition is detected, the user will not be allowed to log in. An error to this effect will be logged to the console.
Optional User Attributes
The following optional SAML attributes will be set while synthesizing the user if they exist:
Display Name (dis) - Assertion Attribute: displayName
Email Address (email) - Assertion Attribute: email
NOTE: The dis tag is set to the username if a displayName attribute does not exist.
Example applyTagsFunc
A simple example use case for the applyTagsFunc is to add the email address to the synthesized user. In this example, the user's email address is provided in the Assertion with the attribute name finEmailAddress.
NOTE: Every key in the attrs Dict is a List of values (a single value will be a List with one item). Additionally, each attribute returned from the identity provider is converted to a valid tag name using toTagName() so accessing the name of the attribute may differ from what is shown in the encoded SAML authentication response message. During initial configuration, echo(attrs) can be helpful to verify attribute names.
(user, attrs) => do
emailList: attrs["finEmailAddress"]
if (emailList != null and emailList.size == 1)
user = user.set("email", emailList.first)
return user
end
SAML IdP Configuration
In Folio > Launch, query for samlShowSkySparkMetadata() and then toggle to the Zinc view to display the FIN SAML Metadata. Some IdPs will support configuring the FIN Service Provider by copying and pasting the XML portion into the IdP SP configuration page. By default, the siteUri setting is used in the two locations specified below as {siteUri}.
The entityId does not include the port. The FIN siteUri is configured in the Host > Settings page under HTTP section. When configuring the IdP it is important to use the address that users will connect to FIN with as the IdP will likely reject a request for an unknown Entity ID. Additionally, FIN will check that the Audience lists the FIN Entity ID in the response.
<?xml version='1.0' encoding='UTF-8'?>
<md:EntityDescriptor xmlns:md='urn:oasis:names:tc:SAML:2.0:metadata' entityID='{siteUri without port}'>
<md:SPSSODescriptor WantAssertionsSigned='true' protocolSupportEnumeration='urn:oasis:names:tc:SAML:2.0:protocol'>
<md:NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:transient</md:NameIDFormat>
<md:AssertionConsumerService Binding='urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST' Location='{siteUri}/samlSso/assertionConsumerService' index='0' isDefault='true'/>
</md:SPSSODescriptor>
</md:EntityDescriptor>
For convenience when displaying the FIN SP Metadata, the SkySpark Entity ID and Assertion Consumer binding are called out below the XML. When copying the FIN Metadata to an IdP, do not include the lines shown below:
SkySpark Entity ID: {siteUri without port}
SkySpark Assertion Consumer HTTP-POST Binding: {siteUri}/samlSso/assertionConsumerService
FIN Entity Id
By default, the siteUri of the FIN server is used for the FIN Entity Id, excluding the port. This can be overridden by adding a tag to the samlSso entry in var/host/folio.trio called FINEntityId and specify a Str value.
Restart FIN after making the change.
FIN Assertion Consumer Service Uri
By default, the siteUri of the FIN server is used to build the Assertion Consumer Service Uri using this format: {siteUri}/samlSso/assertionConsumerService
Most of the time, it is recommended to use the siteUri, but when working across numerous dev and test environments it can simplify testing to use something other than the siteUri. To do that, add a tag to the samlSso entry in var/host/folio.trio called FINBaseUri and specify a Uri value. Remember to include the port if necessary. When adding this tag, the default Entity Id will also change. See FIN Entity Id section to change the FIN Entity Id.
Restart FIN after making the change.
Encrypted Assertions
Support for encrypted assertions is not enabled by default. Additional support pods are required.
Example: Configuring Okta SAML SSO with FIN
This guide provides a step‑by‑step process for configuring SAML‑based Single Sign-On (SSO) between FIN and Okta.
Prerequisites
Users and groups are already created in Okta.
1. Configure HTTP/HTTPS Settings in FIN
Depending on your deployment requirements, FIN can operate with HTTPS either enabled or disabled.
The commands below allow you to toggle HTTPS at the directory level. This setting is independent of the UI option found under Host → Settings → HTTP → HTTPS Enabled. Run the appropriate query based on the configuration you need.
Open Folio → Launch
Run the following command to enable HTTPS.
hostCommit({id:@h:http, mod:hostReadById(@h:http)->mod, httpsEnabled:true})Run the following command to disable HTTPS.
hostCommit({id:@h:http, mod:hostReadById(@h:http)->mod, httpsEnabled:false})
2. Enable the SAML SSO Module in FIN
Open Folio → Launch
Run this command to enable SAML:
sysModAdd(["samlSso"])
To disable: sysModRemove(["samlSso"])
To check status: sysMods().find(x => x->name.contains("samlSso"))->libStatus
3. Gather FIN Metadata for Okta
In Folio → Launch, run:
samlShowSkySparkMetadata()Switch to the Zinc view.
Record the following values:
SkySpark Entity ID
SkySpark Assertion Consumer Service (HTTP‑POST) URL
These will be used when creating the Okta app.
4. Create the Okta SAML Application
Sign into the Okta Admin Dashboard
Go to Applications → Applications
Click Create App Integration
Choose SAML 2.0
Name the application (add logo if desired)
SAML Settings
Single sign-on URL
Paste the SkySpark ACS URL
Example:https://{host}/samlSso/assertionConsumerServiceAudience URI (SP Entity ID)
Paste the SkySpark Entity ID
Example:https://{host}Default RelayState: leave blank
Name ID format: Transient
Application username: Okta username
Update application username: Create and update
Click Next → mark as internal app.
5. Assign Users and Groups in Okta
In the created Okta app, open the Assignments tab.
Assign individual users and Okta groups.
6. Configure Attribute Statements
In the Okta app, go to Sign On → Edit → Switch to legacy view
Add the following Attribute Statements:
Username Attribute
Field | Value |
|---|---|
Name |
|
Name format | Basic |
Value |
|
Groups Attribute
Field | Value |
|---|---|
Name |
|
Name format | Basic |
Filter |
|
7. Collect Okta Metadata URL
While still in Sign On, copy the Metadata URL.
You will import this into FIN.
8. Create User Groups in FIN
Create your FIN user groups.
For each group, click the “i” (info) icon and add:
samlSsoUserProtoAttrVal: "<name of Okta group>"This value must match exactly what Okta sends.
9. Import Okta Metadata into FIN
Open Folio → Launch
Run the following command using your Metadata URL:
samlImportIdPMetadataUri({uri:`https://trial-5917406.okta.com/app/exk10jrvdwd2K7EGA698/sso/saml/metadata`})This automatically populates fields such as:
autoUpdateIdPMetadataUri:``
host:"trial-5917406.okta.com"
idpEntityId:"http://www.okta.com/exk10jrvdwd2K7EGA698"
idpLoginPath:"/app/trial-5917406_fin_1/exk10jrvdwd2K7EGA698/sso/saml"
port:443
tls:trueCertificates are imported automatically.
10. Configure Remaining SAML Settings in FIN
In Folio → Launch, run the following query, updating the property values inside the double quotes as needed. Leave any unused properties as empty strings.
Refer to the related sections above for details on each property, including whether it is required or optional.
Query:
hostCommit({id:@h:samlSso,mod:hostReadById(@h:samlSso)->mod,
applyTagsFunc:"",
loginUpdateMode:"updateOnLogin",
samlResponseUsernameAttribute:"username",
supportText:"",
userProtoAttr:"groups",
userProtoDefault:"",
userProtoPriority:"admin"
}) Once this command is executed, the updated values will be written to the id:@samlSso section within the var/host/folio.trio file.
11. Restart FIN
After applying all the settings, restart the FIN service.
12. Test Okta SSO
Navigate to your FIN instance. If there is no active Okta session in the browser, the Okta login page should appear. Successful login should redirect back into FIN.
Video
Example video walkthrough for configuring SAML‑based Single Sign-On (SSO) between FIN and Okta.