Authorization Policy examples

This article presents example Authorization Policy configurations for some typical uses cases. For SSO Authorization Policy documentation, please refer to:

Manage authorization policies - SSO

Expression language API - SSO

These configuration examples have been tested with Ubisecure SSO 8.8.1.

Contents

User and method attributes

In a typical configuration, either user attributes (attributes from Ubisecure Directory, external LDAP directory or external SQL database) or method attributes (claims from external Identity Providers) are passed on to applications with the Authorization Policy configuration. Simple examples are shown below:

GroupNameValue
eIDMUsergiven_name${user['givenName']}
FTN Usersgiven_name${method['urn:oid:1.2.246.575.1.14']}
Azure Usersemail${method['http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress']}


When external identities are mapped to Ubisecure identities (see Management UI Directory User Mappings - SSO and User driven federation - SSO), both user attributes and method attributes may be available. In this case, the method attributes can be accessed by using a local user group, typically eIDMUser, instead of a group configured for the Identity Provider. For example, name is taken form the local user directory and job title from an Azure AD claim as follows:

GroupNameValue
eIDMUsergiven_name${user['givenName']}
eIDMUserfamily_name${user['sn']}
eIDMUserjob_title${method['http://schemas.xmlsoap.org/ws/2005/05/identity/claims/title']}

Single-value and multi-value attributes

By default, all attributes are processed as multi-value attributes. Attributes can be defined as single-value attributes on the main screen of the Authorization Policy configuration:

In JWT tokens, single-value attributes are passed as string values and multi-value attributes as string lists. Boolean and numeric values are converted to strings. Whenever an attribute is known to take only one value, it is recommended to define the attribute as a single-value attribute. Below, an example JWT is presented with a default configuration and with single-value attributes defined:

Default configuration
{
    "sub": "ubisecure.demo@example.com",
    "iss": "https://login.ubidemo.com:8443/uas",
    "amr": [
        "https://login.ubidemo.com:8443/uas/saml2/names/ac/password.2"
    ],
    "aud": [
        "0baaf7ce-8df8-4cb9-9ecc-de9a6e00a792"
    ],
    "azp": "0baaf7ce-8df8-4cb9-9ecc-de9a6e00a792",
    "auth_time": 1640871824,
    "iat": 1640871827,
    "exp": 1640875426,
    "session_index": "_208fb80205c891f3ec45cf4e5cd0379e403c211e",
    "email": [
        "ubisecure.demo@example.com"
    ],
    "family_name": [
        "Demo"
    ],
    "given_name": [
        "Ubisecure"
    ],
    "roles": [
        "services/RoleRequester",
        "eIDM/eIDMMainUser"
    ],
    "surname": "Demo"
}


Single-value attributes defined
{
    "sub": "ubisecure.demo@example.com",
    "iss": "https://login.ubidemo.com:8443/uas",
    "amr": [
        "https://login.ubidemo.com:8443/uas/saml2/names/ac/password.2"
    ],
    "aud": [
        "0baaf7ce-8df8-4cb9-9ecc-de9a6e00a792"
    ],
    "azp": "0baaf7ce-8df8-4cb9-9ecc-de9a6e00a792",
    "auth_time": 1640871518,
    "iat": 1640871524,
    "exp": 1640875124,
    "session_index": "_af24c0650721e4795ee796a2e567779ad846144a",
    "email": "ubisecure.demo@example.com",
    "given_name": "Ubisecure",
    "roles": [
        "services/RoleRequester",
        "eIDM/eIDMMainUser"
    ],
    "family_name": "Demo"
}

String value operations

String value attributes can be modified by using Java EL statements with Java String methods. Information on Java String methods can be found, for example, at https://www.w3schools.com/java/java_ref_string.asp. Some configuration examples are presented below:

NameValueExample DataExample Result
given_name${user['givenName'][0].toUpperCase()}givenName=Michael"MICHAEL"
full_name${user['givenName'][0].concat(' ').concat(user['sn'][0])}givenName=Michael, sn=Jones"Michael Jones"
is_employee${user['mail'][0].toLowerCase().endsWith('@ubisecure.com')}

mail=user.demo@customer.com

"false"
email_domain${user['mail'][0].substring(user['mail'][0].indexOf('@')+1)}mail=ubisecure.demo@example.com"example.com"
test_account${user['givenName'][0].toLowerCase().contains('application_test')}givenName=Application_Test"true"
birthdate${method['urn:oid:1.2.246.21'][0].contains('-') ? "19".concat(method['urn:oid:1.2.246.21'][0].substring(4, 6)).concat("-").concat(method['urn:oid:1.2.246.21'][0].substring(2, 4)).concat("-").concat(method['urn:oid:1.2.246.21'][0].substring(0, 2)) : "20".concat(method['urn:oid:1.2.246.21'][0].substring(4, 6)).concat("-").concat(method['urn:oid:1.2.246.21'][0].substring(2, 4)).concat("-").concat(method['urn:oid:1.2.246.21'][0].substring(0, 2))}

150990-304Y

100302A017X

1990-09-15

2002-03-10

mobile${user['mobile'][0].startsWith('0') ? '+358'.concat(user['mobile'][0].substring(1)) : user['mobile'][0]}

0401234567

+4422334456

+358401234567

+4422334456


String values can also be modified by using regular expressions with the re:replace function, for example as follows:

NameValueCommentExample DataExample Result
given_name

${re:replace(method['http://schemas.xmlsoap.org/ws/2005/05/identity/claims/displayname'], ".*, ", "")}

Replace all characters until the first comma followed by a space, by a null stringJones, Michael"Michael"
family_name

${re:replace(method['http://schemas.xmlsoap.org/ws/2005/05/identity/claims/displayname'], ", .*", "")}

Replace the comma and anything after that by a null stringJones, Michael"Jones"
employee_id${re:replace(method['employee_id'], ".*-", "")}Replace all characters until '-' by a null stringOperations-123456"123456"
email_domain${re:replace(user['mail'][0], ".*@", "")}Replace all characters until '@' by a null stringubisecure.demo@example.com"example.com"
given_name

${re:replace(method['name'], "^([^ ]+) (.+)$", "$1")}

Define anything until the first space as the 1st capturing group and the remaining characters as the 2nd group

Michael Jones

"Michael"
family_name${re:replace(method['name'], "^([^ ]+) (.+)$", "$2")}Define anything until the first space as the 1st capturing group and the remaining characters as the 2nd groupMichael Jones
Michael De Jong
"Jones"
"De Jong"
given_name${re:replace(method['name'], "^(.*) (.+)$", "$1")}Define anything until the last space as the 1st capturing group and the remaining characters as the 2nd groupMichael Jones
Michael M Jones
"Michael"
"Michael M"


List value matching and filtering

Note: Ubisecure CustomerID SSO Adapter can also be used for filtering the roles, see Authorization configuration - CustomerID.

Typical claims presented as lists are users' role and group assignments. If there are a limited number of known groups or roles, and there is a need to filter out any other groups/roles, it is straightforward to use the contains function for filtering. This way the generic group/role names can also be mapped to application specific names when needed. Some examples are given below.

NameValueCommentExample DataExample Result
groups

${user['memberOf'].contains('CN=SEAdmins,OU=abc,DC=example,DC=com') ? 'SEAdmins' : null}
${user['memberOf'].contains('CN=PrintUsers,OU=abc,DC=example,DC=com') ? 'PrintUsers' : null}

Use CN instead of the whole Distinguished NameCN=SEAdmins,OU=abc,DC=example,DC=com, CN=PrintUsers,OU=abc,DC=example,DC=com["SEAdmins", "PrintUsers"]
groups${user['memberOf'].contains('CN=SEAdmins,OU=abc,DC=example,DC=com') ? 'Admin_Group' : null}Map the group name to an application specific name, filter out all other groupsCN=SEAdmins,OU=abc,DC=example,DC=com, CN=PrintUsers,OU=abc,DC=example,DC=com["Admin_Group"]
roles

${eidm['roles'].contains('services/extranet/User') ? 'services/extranet/User' : null}
${eidm['roles'].contains('services/extranet/MainUser') ? 'services/extranet/MainUser' : null}

Filter out all but the application specific rolesSmartPlan/OrganizationMainUser, SmartPlan/OrganizationUser, services/extranet/Mainuser["services/extranet/Mainuser"]
roles${eidm['roles'].contains('services/extranet/User') ? 'ExtranetUser' : null}
${eidm['roles'].contains('services/extranet/MainUser') ? 'ExtranetMainUser' : null}
Map role names to application specific roles, filter out all but the application specific rolesSmartPlan/OrganizationMainUser, SmartPlan/OrganizationUser, services/extranet/Mainuser["ExtranetMainuser"]


If the groups or roles are not known (for example, defined by an external Identity Provider) or there can be a big or unlimited number of them (for example, roles with organization name as prefix), a more generic way for filtering is required. In this case, Java EL streams can be used for matching and filtering the string lists. For more detailed information, please refer to Java EL documentation: https://download.oracle.com/otndocs/jcp/el-3_0-fr-eval-spec/index.html. Some example configurations are presented below.

NameValueCommentExample DataExample Result
user_type${eidm['roles'].stream().anyMatch(r -> r.endsWith('OrganizationMainUser')).orElse(false) ? 'adminuser' : 'normaluser'}User is adminuser if they have OrganizationMainUser role in any organizationSmartPlan/OrganizationMainUser, SmartPlan/OrganizationUser"adminuser"
is_admin${eidm['roles'].stream().anyMatch(r -> r.contains('OrganizationMainUser')).get()}True / False based on OrganizationMainUser role in any organizationSmartPlan/OrganizationUser"false"
enduser_roles${eidm['roles'].stream().filter(r -> not r.contains('OrganizationMainUser')).toList()}All roles excluding OrganizationMainUser rolesSmartPlan/OrganizationMainUser, SmartPlan/OrganizationUser["SmartPlan/OrganizationUser"]
service_admin_roles${eidm['roles'].stream().filter(r -> r.toLowerCase().contains('mainuser')).filter(r -> not r.contains('OrganizationMainUser')).toList()}All roles containing "mainuser" regardless of case, excluding "OrganizationMainUser"SmartPlan/OrganizationMainUser, SmartPlan/OrganizationUser, extranet/Mainuser["extranet/Mainuser"]
roles${eidm['roles'].stream().filter(r -> not (r.startsWith('Users/') or r.startsWith('eIDM/'))).toList()}All roles excluding roles in organizations "Users" and "eIDM"SmartPlan/OrganizationMainUser, SmartPlan/OrganizationUser, eIDM/eIDMMainUser, Users/VerifiedUser["SmartPlan/OrganizationMainUser", "SmartPlan/OrganizationUser"]
nr_of_roles${eidm['roles'].stream().filter(r -> not (r.startsWith('Users/') or r.startsWith('eIDM/'))).toList().size()}Number of roles, excluding roles in organizations "Users" and "eIDM"SmartPlan/OrganizationMainUser, SmartPlan/OrganizationUser, eIDM/eIDMMainUser, Users/VerifiedUser"2"
roles${eidm['roles'].stream().sorted().toList()}All roles sorted alphabeticallySmartPlan/OrganizationMainUser, SmartPlan/OrganizationUser, extranet/Mainuser["SmartPlan/OrganizationMainUser", "SmartPlan/OrganizationUser", "extranet/Mainuser"]
roles${eidm['roles'].stream().sorted().substream(1).toList()}All roles sorted alphabetically, then excluding the first oneSmartPlan/OrganizationMainUser, SmartPlan/OrganizationUser, extranet/Mainuser["SmartPlan/OrganizationUser", "extranet/Mainuser"]

List value modifications

For modifying string values within the lists, a new list can be created with the Java split function. In the examples below, we use split("&") for converting a string to a list with one element. Here we assume that the data does not contain any '&' characters.

NameValueCommentExample DataExample Result
roles${eidm['roles'].stream().flatMap(r -> r.toLowerCase().split("&").stream()).toList()}Convert all role names to lower caseSmartPlan/OrganizationMainUser, SmartPlan/OrganizationUser["smartplan/organizationmainuser", "smartplan/organizationuser"]
roles${eidm['roles'].stream().flatMap(r -> r.substring(r.lastIndexOf('/')+1).split("&").stream()).toList()}Exclude the path of role namesSmartPlan/OrganizationMainUser, SmartPlan/OrganizationUser["OrganizationMainUser", "OrganizationUser"]
roles${eidm['roles'].stream().flatMap(r -> r.substring(r.lastIndexOf('/')+1).toLowerCase().split("&").stream()).sorted().distinct().toList()}Exclude the path of role names, convert to lower case, sort and remove duplicatesSmartPlan/OrganizationMainUser, SmartPlan/OrganizationUser, Citygroup/OrganizationUser["organizationmainuser", "organizationuser"]
groups

${user['memberOf'].stream().flatMap(r -> r.substring(3, r.indexOf(',')).split("&").stream()).toList()}

Extract CN from the DN strings: take the characters from the 4th position until the next commaCN=SEAdmins,OU=abc,DC=example,DC=com, CN=PrintUsers,OU=abc,DC=example,DC=com["SEAdmins", "PrintUsers"]
groups${user['ubiloginMemberOf'].stream().flatMap(r -> r.split(",").stream()).filter(r -> r.contains('CN=') and not r.contains('CN=Ubilogin')).toList()}Extract CN from the DN strings, exclude "CN=Ubilogin"CN=Test Group,OU=Test,CN=Ubilogin,DC=login,DC=smartplan,DC=com, CN=Test Group 2,OU=Test,CN=Ubilogin,DC=login,DC=smartplan,DC=com["CN=Test Group", "CN=Test Group 2"]

Hashing and encoding examples

The following examples show hashing and encoding. Note data type requirements for hashing and encoding functions.

NameValueCommentExample DataExample Result
email

${attribute.name("email").values(sha256.text('exampleAppString'.concat(user.telephoneNumber[0])).toString().concat('@example.com'))}

Generate a virtual email address formed by hashing user attributes.

Here a hash is a made of application specific string concatenated together a custom userId that is stored in user.telephoneNumber. The email domain is added to the resulting string.

123456794f037115472dd0831df46a01e300a970507b6632a493915c8e1e59fa1a0d47@example.com
uidbase64
${base64:encode(utf8:bytes(user['uid'][0]))}
Base64 encode user.uid. Because base64:encode() function requires a bytearray as input parameter, and user.uid is String, it needs to be converted to bytearray using utf8:bytes().jsmithanNtaXRo

Role Based Access Control

The Ubisecure SSO Authorization Policies can be used for implementing Role Based Access Control (RBAC). With RBAC, only users having application specific role(s) assigned, are allowed to access the application. Other users see an error message which is configurable for each application.

Note: RBAC can be enforced either by Ubisecure SSO or by the application user is trying to access. When access is denied, it may be more straightforward to configure the application to give user-friendly instructions for requesting access rights. 

To enforce RBAC in Ubisecure SSO, define a required attribute on the main screen of the Authorization Policy configuration, for example "extranet-access":

Then use the "Attributes" tab to define the required attribute, for example as follows:

NameValueExample DataExample Result
extranet-access${eidm['roles'].contains('services/extranet/User') ? 'true' : null}
${eidm['roles'].contains('services/extranet/MainUser') ? 'true' : null}

SmartPlan/OrganizationMainUser, SmartPlan/OrganizationUser, services/extranet/Mainuser

SmartPlan/OrganizationMainUser, SmartPlan/OrganizationUser

"true"

not set

For instructions on defining application specific error messages and other user interface properties, please refer to:

Login user interface customization files - SSO
Show different help text depending on the application used