Single Sign-On (SSO) Configuration¶
The Analytics Platform (AP) implements a comprehensive authentication system based on OpenID Connect (OIDC), a protocol built on top of OAuth 2.0. The system features a dual-role architecture that allows AP to function both as an OpenID Connect client and as an authorization server.
OpenID Connect (OIDC)¶
AP leverages Spring Security's OAuth2/OpenID Connect (OIDC) support with the following key components.
Client implementation
- Supports multiple identity providers per client through a multi-tenant architecture.
- Handles standard OpenID Connect scopes:
openid
,profile
, andemail
.
Authorization Server implementation
- Provides OAuth2 authorization server capabilities through Spring Authorization Server
- Supports standard OAuth2 grant types:
- Authorization Code
- Refresh Token
- Client Credentials
- Implements OpenID Connect endpoints:
- Authorization endpoint:
/oauth2/authorize
- Token endpoint:
/oauth2/token
- UserInfo endpoint:
/oauth2/userinfo
- JWKS endpoint:
/.well-known/jwks.json
- Authorization endpoint:
- Supports dynamic client registration
AP as an OAuth2 client¶
In this role, AP authenticates users against external identity providers (e.g., Okta, Azure AD). This section explains how to set up an SSO configuration using Okta as the identity provider. Okta is a popular identity and access management platform which supports the OpenID Connect protocol. The following describes the steps to set up AP as an OAuth2 client.
Create Okta app integration¶
In this step we will create an Okta web app integration.
- Navigate to Applications > Applications.
- Click Create app integration.
- Under Sign-in Method, select OIDC - OpenID Connect.
- Under Application type, select Web application, and click Next.
- Under App integration name, enter a descriptive name like: BAO Analytics Platform Integration.
- Under Grant type > Client acting on behalf of itself, enable Client Credentials.
- Under Client acting on behalf of a user, make sure Authorization Code is enabled and other options are disabled.
- For Sign-in redirect URIs, enter
https://manager.baosystems.com/oauth2/code/OCC4TI2Fdwl/okta
. The pattern ishttps://{ap-base-url}/oauth2/code/{ap-client-id}/{provider-key}
. Theap-base-url
ismanager.baosystems.com
. Make sure to replaceap-client-id
with the id of your organization in the AP. Theprovider-key
is the provider name in lowercase, e.g.,okta
for Okta. - Leave Trusted Origins blank.
- For Assignments, select Allow everyone in your organization to access.
- Click Save.
- In the Assignments tab in the application overview, ensure that the relevant people are assigned.
Record Okta settings securely¶
In this step we will take note of the relevant Okta settings and credentials.
- Go to the General tab in the application overview screen.
- Take note of the following settings by clicking the Copy to clipboard buttons. These settings will be used to create an SSO configuration in AP. The settings should be considered secrets and stored in a secure way.
- Client ID
- Client secret
- Okta domain
- Log out of the Okta portal, to allow logging back in later.
Create AP user¶
An AP user must be created for every Okta user that needs to log in to AP. The AP user is mapped to the Okta identity via the AP user SSO Authentication ID field. User roles and user groups can be granted to the AP user as usual.
- Log in to AP using a regular user with authority to create users.
- Go to Users.
- Create a new AP user, or update an existing one.
- Check Enable SSO and enter your Okta username (email) in the Authentication ID field that is displayed.
- Select appropriate user roles.
- Click Save.
Configure SSO in AP¶
In this step we will configure AP to authenticate with Okta by creating an SSO provider configuration.
- Log in to AP as an admin user (with
MANAGE_CLIENT
andMANAGE_SSO_PROVIDER_CONFIG
authorities). - At the top-right of the screen, click on your username and select Clients from the dropdown.
- Click on your client name.
- Select Manage SSO Provider config
- Enter the OKTA credentials recorded previously:
- Provider - Select OKTA from the dropdown.
- SSO Client ID - Enter the OKTA Client ID.
- SSO Client Secret - Enter the OKTA Client Secret.
- SSO Client Domain - Enter the OKTA domain URL.
- Mapping Claim - Enter email.
- Click Save.
Nginx configuration¶
Update the nginx configuration as follows.
Add the following location block.
Restart nginx to make changes take effect.
AP as authorization server¶
In this role, AP provides authentication services to other applications. This section describes the process for configuring SSO clients for the AP Authorization Server service. The section covers:
- Adding SSO client configurations
- Configuring nginx for the authorization flow requests
- Example: Configuring DHIS2 as a client for SSO
- Example: Configuring Apache Superset as a client for SSO
Add SSO client configurations¶
The /api/ssoClientConfig
endpoint manages client configuration details for SSO clients. This requires the ROLE_MANAGE_SSO_CLIENT_CONFIG
role.
Create new SSO Client
Body
{
"clientName": "data.baosystems.com",
"redirectUris": [
"https://data.baosystems.com/oauth2/code/ap"
],
"scopes": [
"openid",
"email"
]
}
Response
{
"data": {
"clientId": "OfNwxFCVvNZN2QBFHuQv",
"clientSecret": "ZfC0UyTxLZmRwa5iDYM0IQDmC2spCWFu4i8aARM9oetKsnbzLfJORZFIkj2M2ncx",
"id": "EYwkcaMMZrg"
}
}
Note
The clientId
and clientSecret
values are generated by the AP server. The clientSecret
is only shown once when the configuration is first created.
Configure nginx for the authorization flow requests¶
Nginx needs to be configured to allow authorization flow requests. As a multi-tenant application, auth requests need to contain the tenant id in the request. For each tenant (AP client), an OpenID Provider Configuration Request will be:
where ap-client-id
is the AP tenant (AP client) id. Update the nginx configuration as follows to allow this and other oauth requests:
location ~ "^/([a-zA-Z]{1}[a-zA-Z0-9]{10})/(oauth2|\.well-known/openid-configuration)(.*)$" {
set $client_id $1;
set $sub_path1 $2;
set $sub_path2 $3;
proxy_pass http://identity/$client_id/$sub_path1$sub_path2$is_args$args;
}
Example: Configuring DHIS2 as SSO client¶
Setting up a DHIS2 instance for SSO is covered in detail in the DHIS2 documentation. In summary, the dhis.conf
file needs to be updated as follows:
oidc.oauth2.login.enabled = on
oidc.provider.ap.client_id = dkhY3Z6zO1qDkdL7dMBg
oidc.provider.ap.client_secret = bcSfmL8KjzvM1CTt2VmeUC1IEzxPiP0LPzGab1jr5J4rVtHtmZZ59piFBkweyi36
oidc.provider.ap.mapping_claim = email
oidc.provider.ap.authorization_uri = https://manager.baosystems.com/OCC4TI2Fdwl/oauth2/authorize
oidc.provider.ap.token_uri = https://manager.baosystems.com/OCC4TI2Fdwl/oauth2/token
oidc.provider.ap.user_info_uri = https://manager.baosystems.com/OCC4TI2Fdwl/oauth2/userinfo
oidc.provider.ap.jwk_uri = https://manager.baosystems.com/OCC4TI2Fdwl/oauth2/jwks
oidc.provider.ap.end_session_endpoint = https://manager.baosystems.com/OCC4TI2Fdwl/logout
oidc.provider.ap.scopes = openid
oidc.provider.ap.redirect_url = https://{dhis2-server-url}/oauth2/code/ap
oidc.provider.ap.display_alias = BAO Analytics Platform
oidc.logout.redirect_url = https://{dhis2-server-url}/
Note
- This change requires a tomcat restart. In addition, a DHIS2 user needs to be created so match the AP user. In particular, the OIDC mapping value field of the DHIS2 user must match the email of the user in AP. Find more details in Okta for DHIS2 guide.
- The
redirect_uri
should behttps://{dhis2-server-url}/oauth2/code/ap
and it must match the redirect URI used to create the SSO client config in AP.
Example: Configuring Apache Superset as SSO client¶
Setting up Apache Superset for SSO is described in the Apache Superset documentation.
Install Authlib
Install Authlib
pip package by adding an entry in the superset/docker/requirements-local.txt
file:
Configure superset_config.py
Edit the file superset/docker/pythonpath_dev/superset_config.py
and add the following lines:
from flask_appbuilder.security.manager import AUTH_OAUTH
from custom_sso_security_manager import CustomSsoSecurityManager
CUSTOM_SECURITY_MANAGER = CustomSsoSecurityManager
# Set the authentication type to OAuth
AUTH_TYPE = AUTH_OAUTH
OAUTH_PROVIDERS = [
{
'name': 'BAO-Analytics-Platform',
'token_key': 'access_token', # Name of the token in the response of access_token_url
'icon': 'fa-address-card',
'remote_app': {
'client_id': 'NHNy6W9ggLJbC89INtw6', # Created via /api/ssoClientConfig
'client_secret': 'l8mOLS8jPNxs4L0JQpsvWQVeqpPK5foBNK8MyFiKqobvgKr4DWavSyTkxVNwLCQL',
# Created via /api/ssoClientConfig
'client_kwargs': {
'scope': 'openid' # Scope for the Authorization
},
'jwks_uri': 'https://manager.baosystems.com/OCC4TI2Fdwl/oauth2/jwks', # Uri for token creation
'access_token_method': 'POST', # HTTP Method to call access_token_url
'access_token_params': { # Additional parameters for calls to access_token_url
'client_id': 'NHNy6W9ggLJbC89INtw6'
},
'access_token_headers': { # Additional headers for calls to access_token_url
'Authorization': 'Basic TkhOeTZXOWdnTEpiQzg5SU50dzY6bDhtT0xTOGpQTnhzNEwwSlFwc3ZXUVZlcXBQSzVmb0JOSzhNeUZpS3FvYnZnS3I0RFdhdlN5VGt4Vk53TENRTA==',
'Content-Type': 'application/x-www-form-urlencoded',
},
'api_base_url': 'https://manager.baosystems.com/OCC4TI2Fdwl/',
'access_token_url': 'https://manager.baosystems.com/OCC4TI2Fdwl/oauth2/token',
'authorize_url': 'https://manager.baosystems.com/OCC4TI2Fdwl/oauth2/authorize'
}
}
]
# Will allow user self registration, allowing to create Flask users from Authorized User
AUTH_USER_REGISTRATION = True
# The default user self registration role
AUTH_USER_REGISTRATION_ROLE = "Gamma"
Note
- The
remote_app.access_token_headers.Authorization
value is the base64 encoding of theclient_id:client_secret
. - The redirect URL will be
https://{superset-webserver}/oauth-authorized/{provider-name}
. For the BAO demo instance, that will be:https://analytics.demo.baosystems.com/oauth-authorized/BAO-Analytics-Platform
Configure custom_sso_security_manager.py
Create a superset/docker/pythonpath_dev/custom_sso_security_manager.py
file with the following content:
import logging
from superset.security import SupersetSecurityManager
class CustomSsoSecurityManager(SupersetSecurityManager):
def oauth_user_info(self, provider, response=None):
logging.debug("Oauth2 provider: {0}.".format(provider))
if provider == 'BAO-Analytics-Platform':
userinfo = self.appbuilder.sm.oauth_remotes[provider].get('oauth2/userinfo').json()
# check the values of user_name, mail and others values in me variable
return {
'name': userinfo.get('name', ''),
'email': userinfo.get('sub', ''),
'id': userinfo.get('id', ''),
'username': userinfo.get('sub', ''),
'first_name': '',
'last_name': ''
}
Troubleshooting¶
Common issues and solutions are found below.
Invalid Redirect URI
- Ensure the configured redirect URI exactly matches the callback URL.
- Check for trailing slashes and correct protocol (
http
vshttps
).
Token Validation Failures
- Check if tokens have expired.
- Validate signature keys are properly configured.
User Attribute Mapping Issues
- Check that the identity provider is sending the required claims.
- Verify attribute mapping configuration.
- Check scopes include necessary permissions.