OKTA SAML integration
Contents
- Creating your application in OKTA.
- Configuring your application in OKTA.
- Generating IDP metadata in OKTA.
- Generating your JKS key.
- Groovy file configuration.
- Generating SP.xml.
- Instances behind a load balancer
Creating application within OKTA
On the Admin page select the Applications, then select “Create App Integration”
Within the Integration window please select SAML 2.0 and click next.
Configuring your application within OKTA.
Name your application and click next
This should bring you to the “SAML settings” window, please see the below example for how this should be configured, the only requirement here is your IriusRisk domain needs to be changed to what you currently have configured, unless your entity ID is custom, In which case you will need to modify the “Single sign on URL” & Audience URI to reflect this by removing “iriusrisk-sp” and replacing it with your custom entry.
*Case Sensitive
https://youririusriskdomain.com/saml/SSO/alias/iriusrisk-sp
iriusrisk-sp
**Note - For here you want the left side and right side to match - Example "user.firstName → user.firstName" (Keeping case sensitive in mind)**
User/group assignment
Next, please ensure that your required groups are assigned to app within OKTA, you will need to map the group names to the relevant roles within the IriusRisk groovy file to ensure accurate access is assigned to the end user.
Generating IDP metadata in OKTA.
Next, under the "Sign On" tab, click the "copy" button to copy the `Metadata URL` and paste this into a new browser tab. You will need to copy all of the provided information into a file named `idp.xml` and place this file in the same directory as your `docker-compose.yml` file. (You can even use vi, vim, nano, etc... to write this directly in the correct directory)
Generating the JKS file
From the CLI of your IriusRisk instance enter the tomcat docker container
docker exec -it iriusrisk-tomcat sh
Execute key generation procedure. The default password for the keystore is "changeit". There is no need to fill the information about the name/country etc, but providing a password is mandatory. We will also use “iriusrisk-sp” as key password.
keytool -genkey -alias "iriusrisk-sp" -validity 1825 -keyalg RSA -keystore /etc/ssl/certs/java/cacerts
Check that the key is properly generated and is present in the keystore:
keytool -list -keystore /etc/ssl/certs/java/cacerts | grep iriusrisk-sp -A 1
Enter keystore password: changeit
iriusrisk-sp, Feb 4, 2021, PrivateKeyEntry,
Certificate fingerprint (SHA1): 92:E9:7A:34:BD:B5:97:47:80:22:DA:60:6B:ED:A6:B0:FC:BE:5B:E1
Exit the container and copy the keystore outside:
exit
docker cp iriusrisk-tomcat:/etc/ssl/certs/java/cacerts iriusrisk-sp.jks
If you have a requirement to import custom CA certificates please follow the below, if not please proceed to the next steps.
Import CA signed certificates (optional)
When you get your certificates form the CA, you will have 2 important files (names are just an example):
- pem - the public certificate with signed CA certification chain
- key - private key for the certificate
TIP: in order to inspect the contents of the PEM certificate, execute:
openssl x509 -in 4c62d535c32f5d28.pem -text -noout
First, let's create a PKCS12 file that combines the both mentioned files:
openssl pkcs12 -export -in 4c62d535c32f5d28.pem -inkey customer_iriusrisk_com.key -out iriusrisk-sp.p12 -name iriusrisk-sp
After, import the resultant into a new Java Key Store:
keytool -importkeystore -deststorepass iriusrisk-sp -destkeystore iriusrisk-sp.jks -srckeystore iriusrisk-sp.p12 -srcstoretype PKCS12 -alias iriusrisk-sp
In order to inspect the contents of the JKS file, execute:
keytool -list -v -keystore iriusrisk-sp.jks
Docker compose configuration
docker-compose.yml (temporary version)
Create or make changes to your `docker-compose.yml` file to mirror the below content. Remember to configure `NG_SERVERNAME`, `IRIUS_DB_URL/Password`, and `IRIUS_EXT_URL` with the correct values of your instance endpoints as this is an example file:
services:
nginx:
ports:
- "80:80"
- "443:443"
environment:
- NG_SERVER_NAME=<your-instance>.iriusrisk.com
image: continuumsecurity/iriusrisk-prod:nginx
container_name: iriusrisk-nginx
networks:
- iriusrisk-frontend
mem_reservation: 50M
mem_limit: 200M
cpu_shares: 128
restart: unless-stopped
volumes:
- "./cert.pem:/etc/nginx/ssl/star_iriusrisk_com.crt:ro"
- "./key.pem:/etc/nginx/ssl/star_iriusrisk_com.key:ro"
logging:
driver: awslogs
tomcat:
environment:
- IRIUS_DB_URL=jdbc\:postgresql\://<your-db-url>\:5432/iriusprod?user\=iriusprod&password\=<db-password>
- IRIUS_EDITION=saas
- IRIUS_EXT_URL=http\://<your-instance>.iriusrisk.com
- grails_env=production
- CATALINA_OPTS="-Dsaml.config.path=/etc/irius/SAMLv2-config.groovy"
- STARTLEFT_URL=http://startleft:8081
- IRIUS_JWT_PRIVATE_KEY_PATH=/etc/irius/ec_private.pem
*Note - In this step, you are adding
- CATALINA_OPTS="-Dsaml.config.path=/etc/irius/SAMLv2-config.groovy"
to your `docker-compose.yml` file under the `tomcat → environment` section. This is not a complete yml file to use.
Groovy file configuration
Then create the groovy file in the same directory called SAMLv2-config.groovy please ensure to make the modifications mentioned below to avoid any complications, it is important that the naming conventions of the userGroupToRoleMapping mirror exactly as you have within OKTA.
*Feel free to set `active = false` until you are ready to activate the SAML login option.
*You can also set this to false, if you are having any trouble through the setup process, and use the default login with username/password.
grails { plugin { springsecurity { saml { // Activate SAML integration with IriusRisk active = true
// Base to generate URLs for this server. For example: https://my-server:443/app. The public address your server will be accessed from should be used here.
entityBaseUrl = 'https://your-instance.iriusrisk.com'
// Custom entity id for the instance. If it doesn't exist it is set to iriusrisk-sp by default
// entityId = "iriusrisk-sp"
// Mapping User fields to SAML fields, e.g: [firstName: givenName], firstName is the user field in IriusRisk (do not change), givenName is SAML field userAttributeMappings = [ 'username' : 'user.email',
'firstName': 'user.firstName',
'lastName' : 'user.lastName',
'email' : 'user.email' ]
// SAML assertion attribute that holds returned group membership data
userGroupAttribute = 'memberOf'
// Custom Values, mapping Okta Groups GUIDs (used as keys in the configuration map userGroupToRoleMapping) to Irius RoleGroup names (used as values in the configuration map userGroupToRoleMapping) userGroupToRoleMapping = [ 'Your_okta_group':'ROLE_TEST_ONLY', 'Your_okta_group':'ROLE_ADMIN', 'Your_okta_group':'ROLE_PORTFOLIO_VIEW', 'Your_okta_group':'ROLE_DEVELOPER', 'Your_okta_group':'ROLE_FULL_ACCESS_USER', 'Your_okta_group':'ROLE_MANAGE_USERS_BU', 'Your_okta_group':'ROLE_RISK_MANAGER', 'Your_okta_group':'ROLE_RULES_EDITOR', 'Your_okta_group':'ROLE_TEMPLATE_EDITOR', 'Your_okta_group':'ROLE_REQUIREMENTS_MANAGE', 'Your_okta_group':'ROLE_TESTER', 'Your_okta_group':'ROLE_QUESTIONNAIRE_ONLY', 'Your_okta_group':'ROLE_LIBRARY_EDITOR' ] // If there is no information about roles in the SAML Response, IriusRisk will use this property to assign a default role to the User defaultRole = 'ROLE_DEVELOPER'
// SAML assertion attribute that holds returned business unit data
// businessUnitsAttribute = 'department'
// Custom Values, mapping group names with (used as keys in the configuration map businessUnitsMapping) to Irius business units refs (used as values in the configuration map businessUnitsMapping)
// businessUnitsMapping = [
// 'Your_okta_group': 'testers',
// 'Your_okta_group': 'managers',
// 'Your_okta_group': 'developers'
// ]
// If there is no information about business units in the SAML Response, IriusRisk will use this property to assign a default business unit to the User
// defaultBusinessUnit = 'testers'
// Custom entity id for the instance if it doesn't exist it is set to iriusrisk-sp by default
// entityId = "custom-entity-id"
metadata { // Relative URL in IriusRisk to download sp.xml metadata url = '/saml/metadata' // Provider to be used from the configuration map providers defaultIdp = 'idp' // Configuration map providers, using the name of the provider as key and the file system path to the xml descriptor file from Azure providers = [ idp :'/etc/irius/idp.xml'] idp { title = 'OKTA login caption' } sp { file = '/etc/irius/sp.xml' defaults = [
// alias should correspond to your entity id alias: 'iriusrisk-sp', signingKey: 'iriusrisk-sp', encryptionKey: 'iriusrisk-sp', tlsKey: 'iriusrisk-sp', ] } } keyManager { storeFile = 'file:/etc/irius/iriusrisk-sp.jks' storePass = 'changeit' passwords = [ 'iriusrisk-sp':'changeit' ] defaultKey = 'iriusrisk-sp' } } } } }
Remember to change some parameters:
- entityBaseUrl - public URL endpoint of your IriusRisk instance
- entityId - custom entity ID set to identify IriusRisk application in OKTA (Note: if setting custom entity this must be reflected in the "alias:" definition under the sp configuration)
- userGroupToRoleMapping - map your OKTA groups to IriusRisk roles
The default IriusRisk roles can be extracted directly from the database with this command:
sudo -u postgres psql --dbname=iriusprod --command="SELECT name FROM role_group";
- userGroupAttribute - the mapping for the attribute that holds returned group membership data
- defaultRole - If a user is not a member of a group in OKTA this is what role will they be granted.
- providers - map your Federation Metadata XML file downloaded from OKTA
- idp.title - sentence you want to appear on the login page as the hyperlink to the OKTA login page.
- keyManager - section with your generated certificate parameters
- businessUnitsAttribute - group attribute to map to IriusRisk business units
- businessUnitsMapping - map IdP groups to business units
SP metadata
sp.xml
Run the application and wait for UI to be available (it may take up to 10min):
docker-compose up -d
The log will show some errors indicating the missing `sp.xml` file. This is something expected. At this point IriusRisk isn't fully configured yet and the UI will not be accessible.
Once IriusRisk starts up, you will need to download the IriusRisk SAML metadata file with the following command (change your-iriusrisk.iriusrisk.com to your own IriusRisk endpoint):
curl https://your-iriusrisk.iriusrisk.com/saml/metadata --output sp.xml
Wrapping Things up
You should now have 4 files in the same directory as your `docker-compose.yml` file that will need to be added to your "volumes" section.
- SAMLv2-config.groovy
- idp.xml
- iriusrisk-sp.jks
- sp.xml
docker-compose.yml (final version)
You will need to include the following into your `docker-compose.yml` under `tomcat → volumes:` and be sure it matches as below:
volumes:
- "./ec_private.pem:/etc/irius/ec_private.pem"
- "./SAMLv2-config.groovy:/etc/irius/SAMLv2-config.groovy"
- "./idp.xml:/etc/irius/idp.xml"
- "./iriusrisk-sp.jks:/etc/irius/iriusrisk-sp.jks"
- "./sp.xml:/etc/irius/sp.xml"
Load Balancer Config
If your application is behind a load balancer you may need to add the following to your goovy file:
contextProvider{
providerClass = 'SAMLContextProviderLB'
scheme = 'https'
serverName = 'your external hostname'
serverPort = 443
includeServerPortInRequestURL = false
contextPath ='/MicroStrategyLibrary'
}
Errors relating to this issue should resemble this:
ERROR org.opensaml.common.binding.decoding.BaseSAMLMessageDecoder - SAML message intended destination endpoint 'https://host.com/saml/SSO/alias/iriusrisk-sp' did not match the recipient endpoint 'http://host.com/saml/SSO/alias/iriusrisk-sp'
Restart everything and your integration should be finished:
docker-compose down && docker-compose up -d
You can also check the logs and see that everything is running correctly:
docker logs -f iriusrisk-tomcat
Comments
0 comments
Article is closed for comments.