Back Office and Engage SSO

Back Office and Engage SSO

FullCount utilizes the OpenId Connect (ODIC) protocol to authenticate users from external identity providers (IDP) into the Back Office. Documentation we can provide to the customer about the process can be found in T:\TechServices\Projects\Integration\SSO\FullCount SSO.pdf

Information for any new SSO provider needs to be added to the identity_providers table.

  • provider_name - The name of the customer or identity provider. No spaces allowed.
  • client_id - Provided by the customer. Id that uniquely identifies FullCount's application to the customer's IDP.
  • client_secret - Provided by the customer. Secret to authenticate FullCount to the customer's IDP.
  • registered_redirect_url - FullCount URL that processes the auth code returned by the customer's IDP. Should always be formatted like the following: https://portal.fullcount.net/backoffice/auth/{lower(provider_name)}/redirect
  • access_token_url - Provided by the customer. Endpoint of the customer's IDP that provides the JWT token.
  • authorization_url - Provided by the customer. Endpoint of the customer's IDP that provides the auth code to FullCount's redirect URL.
  • user_info_url - Provided by the customer only if there is no id_token on the access token response. Endpoint of the customer's IDP to fetch info about the user.
  • token_info_url - ???
  • security_group_name - Provided by the customer. We can validate that the JWT from the customer's IDP contains a specific security group. But they should just be able to check that on their side before even returning the JWT. So this shouldn't really be used.
  • scope - Set to BO for Back Office SSO
  • jwt_issuer - Provided by the customer. The 'iss' attribute of the JWT so we can verify. Optional.
  • custom_flow - Set to 'N' if this SSO uses our generic code for SSO. Set to 'Y' if we need to write classes specific to the SSO implementation.
  • oauth_scopes - Provided by the customer. List of comma delimited scopes to include in the authorization request to the customer's IDP (ex: email,openid).

Generic SSO

When a customer's identity provider conforms to the OIDC protocol, we should be able to create an SSO flow with minimal effort. Create a new record in the identity_providers table with the information above. This information is loaded into properties in the Back Office application at startup, so a restart is needed for the new record to be included.

When the record is created in our test database, test backoffice has been restarted, and the customer is ready to test, the login URL they should use will be https://test.portal.fullcount.net/backoffice/auth/sso/login?provider={lower(provider_name)}. The production login URL will be the same without the "test.".

Details

Each record from the identity_providers table is split and loaded as properties in the BackofficeProperties class. For example for the record with a provider_name of Masonic, properties are created for Masonic.clientId, Masonic.clientSecret, Masonic.registeredRedirectUrl, etc. A separate property called GenericSSOProviders stores a comma delimited list of each provider where custom_flow is set to 'N'.

The BackofficeSecurityContext class creates a Filter for each provider in GenericSSOProviders, using our custom OAuthSSOFilterBuilder class. This class may need to be adjusted occassionally to accomodate small differences in IDP's OIDC implementations, but needs to remain generic to continue to support existing generic flows. If an IDP requires significant accomodation, a custom flow should be used instead.

Custom SSO

Before an effort in 2025 to genericize Back Office SSO, FullCount started out by making custom SSO flows for each identity provider. We still might need to do so for cases that don't fit the OIDC flow or for other reasons we cannot predict. Information is still entered as normal into the identity_providers table, with custom_flow set to 'Y'.

A FullCount developer will then need to write custom code to accomodate the flow which will depend on case. At a minimum, a new Filter will have to be created in the BackofficeSecurityContext class and added to the ssoFilter() method. When creating a custom Filter for a new IDP, try to extend the OAuthSSOFilterBuilder class and reuse as much as possible.

Testing

The systems team has set up an Azure app registration in our own Azure environment to simulate a vendor identity provider. The registration is called Test Back Office SSO. If the client secret gets lost or expires, just have systems generate a new one. For the full SSO process to work, the user must have a unique email in our user_profile table.

When possible, FullCount tries to utilize the OpenId Connect (ODIC) protocol to authenticate users from external identity providers (IDP) into Engage. Documentation we can provide to the customer about the process can be found in T:\TechServices\Projects\Integration\SSO\FullCount SSO.pdf

Information for any new SSO provider needs to be added to the identity_providers table.

  • provider_name - The name of the customer or identity provider. No spaces allowed.
  • client_id - Provided by the customer. Id that uniquely identifies FullCount's application to the customer's IDP.
  • client_secret - Provided by the customer. Secret to authenticate FullCount to the customer's IDP.
  • registered_redirect_url - FullCount URL that processes the auth code returned by the customer's IDP. Should always be formatted like the following: https://portal.fullcount.net/authorization/customers/auth/{lower(provider_name)}
  • access_token_url - Provided by the customer. Endpoint of the customer's IDP that provides the JWT token.
  • authorization_url - Provided by the customer. Endpoint of the customer's IDP that provides the auth code to FullCount's redirect URL.
  • user_info_url - Provided by the customer only if there is no id_token on the access token response. Endpoint of the customer's IDP to fetch info about the user.
  • token_info_url - ???
  • security_group_name - Provided by the customer. We can validate that the JWT from the customer's IDP contains a specific security group. But they should just be able to check that on their side before even returning the JWT. So this shouldn't really be used.
  • scope - Set to RP for Engage SSO (stands for resident portal)
  • jwt_issuer - Provided by the customer. The 'iss' attribute of the JWT so we can verify. Optional.
  • custom_flow - Set to 'N' if this SSO uses our generic code for SSO. Set to 'Y' if we need to write classes specific to the SSO implementation.
  • oauth_scopes - Provided by the customer. List of comma delimited scopes to include in the authorization request to the customer's IDP (ex: email,openid).

Generic SSO

When a customer's identity provider conforms to the OIDC protocol, we should be able to create an SSO flow with minimal effort. Create a new record in the identity_providers table with the information above. This information is loaded into properties in the Back Office application at startup, so a restart is needed for the new record to be included.

When the record is created in our test database, test backoffice has been restarted, and the customer is ready to test, the login URL they should use will be https://test.portal.fullcount.net/authorization/customers/auth/sso/{lower(provider_name)}. The production login URL will be the same without the "test.".

IDP Token Field Mappings

Often times, FullCount cannot rely on email address to match residents between third party resident engagement platforms and our resident records. To support multiple matching strategies, there exists the idp_token_field_mappings table in our database to tie data fields in our database to data fields in the identity provider's JWT token. It has the following columns:

  • identity_provider_id - The identity provider the mapping is associated with
  • resident_field_lable - The name of a column in FullCount's residents table that we want to use to match customers
  • idp_token_field_label - The name of an attribute in the identity provider's authorization token that we want to use to match customers
  • priority - The order to perform a match in the case there are multiple records for this identity provider

Take the following idp_token_field_mapping records as an example. In this case, our SSO process will first try to match the 'email' field in the identity provider's JWT token to the email field in our residents table. If it does not find a unique match, it will then try to match the 'first_name', 'last_name', and 'apartment_no' fields in the identity provider's JWT token to the first_name, last_name, and apartment fields in our residents table respectively. If it does not find a match for all three of those pieces of data, then it will return an error. If there is one unique match at any priority level, the SSO process will log that resident in.

identity_provider_id

resident_field_lable

idp_token_field_label

priority

362

EMAIL

email

1

362

FIRST_NAME

first_name

2

362

LAST_NAME

last_name

2

362

APARTMENT

apartment_no

2

Details

Each record from the identity_providers table is split and loaded as properties in the AuthorizationProperties class. For example for the record with a provider_name of Catie, properties are created for Catie.clientId, Catie.clientSecret, Catie.registeredRedirectUrl, etc. A separate property called GenericSSOProviders stores a comma delimited list of each provider where custom_flow is set to 'N'.

The SecurityConfiguration class creates a Filter for each provider in GenericSSOProviders, using our custom OAuthSSOFilterBuilder class. This class may need to be adjusted occassionally to accomodate small differences in IDP's OIDC implementations, but needs to remain generic to continue to support existing generic flows. If an IDP requires significant accomodation, a custom flow should be used instead.

Custom SSO

Before an effort in 2025 to genericize Engage SSO, FullCount started out by making custom SSO flows for each identity provider. We still might need to do so for cases that don't fit the OIDC flow or for other reasons we cannot predict. Information is still entered as normal into the identity_providers table, with custom_flow set to 'Y'.

A FullCount developer will then need to write custom code to accomodate the flow which will depend on case. At a minimum, a new Filter will have to be created in the SecurityConfiguration class and added to the ssoFilter() method. When creating a custom Filter for a new IDP, try to extend the OAuthSSOFilterBuilder class and reuse as much as possible.

Testing

The systems team has set up an Azure app registration in our own Azure environment to simulate a vendor identity provider. The registration is called Test Generic Engage SSO. If the client secret gets lost or expires, just have systems generate a new one.

 



    • Related Articles

    • HTML code to adjust text fields in the Back Office for FullCount Engage

      HTML code to adjust text fields in the Back Office for FullCount Engage HTML Code Use Case <p style="font-size:desired font sizepx">desired text here</p> Adjust font size <strong>desired text here</strong> Bold text <u>desired text here</u> Underline ...
    • Wellzesta SSO

      Wellzesta SSO Single Sign On is now available for Wellzesta customers to utilize. Customer Mapping The mapping process is done with the combination of email, first name, last name, and phone number. FullCount Requirements Customers will have the ...
    • API Connect/Customer Portal SSO Email Template

      API Connect/Customer Portal SSO Email Template Email Template: Subject: <Community Name> - FullCount <> <Partner> integration Body: Hi <Community Contact>/<Partner> team, We have enabled the <API Connect AND/OR Single-Sign-On> integration between ...
    • FullCount Back Office integration with Trinity Health

      FullCount Back Office integration with Trinity Health Documentation created by Trinity Health (Lori McMichael) and distributed to Trinity Health users. This has been provided to FullCount for reference purposes: Document 1: On Monday, Sept 16, 2019, ...
    • Office Etiquette

      Below are some guidelines for office etiquette. Put your dirty dishes in the dishwasher and do not leave them in the sink. Rinse off your dishes before placing them in the dishwasher. Throw out food in the refrigerator that you do not plan to eat. ...