Unblu SSO Setup

1. Introduction

The unblu enterprise Single Sign On (SSO) distribution is the recommended package to use, when unblu co-browsing must be integrated into existing authentication systems. This document explains what that means in detail.

2. Single Sign On in unblu

Single Sign On is a concept of authentication, which allows users to access a number of different protected web applications by only having to login ("sign on") once. Usually, this can be achieved by delegating the users's authentication action for all web applications that should be accessible with only a single sign on to a central authentication instance. In enterprise environments, such central authentication instances usually already exist. If not (or if they are not suitable to be integrated with unblu for some reason), there's still a number of options using e.g. Servlet Container provided authentication means (see http://tomcat.apache.org/tomcat-7.0-doc/realm-howto.html for instance) or even ways of providing authentication informations completely independant of Servlet Containers (by using request headers described further below).
It is important to understand, that unblu SSO distribution was designed in such a way, that it does not depend to particular Servlet Containers or their functionality. Instead, a number of ways exist to provide authentication information to unblu. As such, unblu SSO distribution integration can be more powerful than for example the SSO concept of Tomcat, since it is not bound to a particular implementation. On the other hand, it is sometimes considered more complex, because it is not always obvious on how to approach the integration.

3. Authentication with the unblu SSO distribution

The unblu SSO distribution does not include any functionality to do the authentication itself. Even more, it does not include functionality to store or manage users. Instead it expects authentication to be done by a surrounding party, be it the Servlet Container (including specific authentication filters) or a reverse proxy which is used for traffic to and from the unblu server.

The unblu SSO distribution can be configured to either use user information provided via

  1. JEE HttpServletRequest.getUserPrincipal()
  2. trusted (request) headers, or request attributes.

Although the configuration triggers for JEE or trusted headers are both boolean values, they're mutually exclusive: It is only possible to enable one of them at a time. Unblu will complain in the logs during start time, when both values are set to true.

3.1. JEE based authentication

To enable JEE based authentication, use com.unblu.authentication.idpropagation.jee.enabled:

# enable jee based authentication (using HttpServletRequest.getUserPrincipal() internally)
com.unblu.authentication.idpropagation.jee.enabled=true

Once JEE based authentication is enabled unblu will retrieve HttpServletRequest.getUserPrincipal() for each request and if non-null assume this to be the properly authenticated user. Setting the principal is possible e.g. by using a filter in the same Servlet Container. See this oracle document for an introduction on servlet filters.

3.2. trusted header based authentication

To enable request header (or request attribute) based authentication, use com.unblu.authentication.idpropagation.trustedheader.useRequestHeaders :

# enable trusted header based authentication
com.unblu.authentication.idpropagation.trustedheader.useRequestHeaders=true

When trusted header based authentication is enabled, it is possible to choose between particular http request headers to be used as the authentication information, or request attributes. Request attributes can be set by filters running in the same servlet container. See this oracle document   for an introduction on servlet filters including some details about request attributes.

4. Access control

Unblu currently defines three separate access groups:

  • public (untrusted) access
  • internal (trusted) access
  • system access

The access type is identified by a path element of a request. By default, public access is mapped to /unblu, internal access is mapped to /co-unblu and system access is mapped to /sys-unblu. All of those defaults can be changed by configuration (and not within the application's web.xml, so no re-deployment is required for such changes).

Please consult the security entry path concept page for more details (including configuration details) about the access groups.

4.1. Access configuration by access group

For each access group, the way authorization is executed can be configured. First decision to make is, which access group must be accessible with authenticated users only.

4.1.1. JEE based authentication access configuration

When using JEE based authentication, the following properties configure access to the respective access group:

# access to public (untrusted) group requires authorization (default: true)
com.unblu.authentication.idpropagation.jee.forceAuthenticationUntrusted=true
 
# access to internal (trusted) group requires authorization (default: true)
com.unblu.authentication.idpropagation.jee.forceAuthenticationTrusted=true
 
# system access requires authorization (default: false)
com.unblu.authentication.idpropagation.jee.forceAuthenticationSystem=true

NOTE: since system access must be a protected access with other means (e.g. by using reverse proxies preventing access to system access group except from valid servers or reverse proxies), it does not require authorization by default. Turning it on may cause problems, when reverse proxies transmit resources to unblu, missing images or stylesheets in the agent view may be the consequence.

When authentication is required for a certain access group according to the above configuration settings (property is set to true), unblu's behaviour for a request to the given access group will be as following:

4.1.2. trusted header based authentication access configuration

When using trusted header based authentication, the following properties configure access to the respective access group:

# access to public (untrusted) group requires authorization (default: true)
com.unblu.authentication.idpropagation.trustedheader.forceAuthentication=true
 
# access to internal (trusted) group requires authorization (default: true)
com.unblu.authentication.idpropagation.trustedheader.forceAuthenticationTrusted=true
 
# system access (default: false)
com.unblu.authentication.idpropagation.trustedheader.forceAuthenticationSystem=true

The authentication information is read out of either http request headers or request attributes, depending on the following configuration:

# use http request headers (default: true -> yes)
com.unblu.authentication.idpropagation.trustedheader.useRequestHeaders=true
 
# use request attributes (default: true -> yes)
com.unblu.authentication.idpropagation.trustedheader.useRequestAttributes=true

If authentication information is available in both, request attribute as well as http request header, and both are enabled, request attribute will take precedence.

The names of the headers and request attributes can be configured with the following properties for each access group separately:

# user id header name expected for public (untrusted) access group
com.unblu.authentication.idpropagation.trustedheader.headerUserId=x-unblu-trusted-user-id
 
# user id header name expected for internal (trusted) access group (default: falling back to untrusted user id header name)
com.unblu.authentication.idpropagation.trustedheader.headerUserIdTrusted=
 
# user id header name expected for system access group (default: falling back to untrusted user id header name)
com.unblu.authentication.idpropagation.trustedheader.headerUserIdSystem=

It is not required to configure header names for all access groups. Instead it's enough to just configure the header name for the public access group and leave the internal and system access groups with their defaults. internal and system access groups will pick the public access group header name in that case.

unblu's behaviour to retrieve authentication information for a request to the given access group is as following:

  1. Identify the access group for the current request (public, internal, system)
  2. For the identified access group retrieve the configured header name
  3. If request attribute usage is enabled, try to retrieve a request attribute with the same name as the configured header name. If existing, use this as authentication information (continue on point 7)
  4. If request attribute usage is not enabled, or no attribute was found for the given name, check if header usage is enabled. If not, use "no authentication information" (see point 6 to continue)
  5. If header usage is enabled, retrieve request header with the configured name from step 2 and use it as the authentication information
  6. If the authentication information is "not available" at this point, detect, whether or not the current access group requires authentication to continue. If it does, fail by responding 403 FORBIDDEN http code
  7. At this point, authentication information has been retrieved and will be used as the "authorized principal" for the rest of the request

4.1.2.1. Special case: root path requests

Agents sometimes request the "root path" directly and expect it to redirect to their agent desk workspace (usually at /co-unblu/desk/ ). This causes a problem: Root cannot be properly assigned to a particular access group. By default, unblu applies root requests to the public group. If the configuration says, for whatever reason, that public requires authentication but internal group does not, agents will not be able to access their workspace by just using the base url. In order to circumvent this problem, the following setting allows to not check authentication at all for root requests.

 

# let root request pass even without proper authentication
com.unblu.authentication.idpropagation.trustedheader.letRootRequestPass=true

5. Submitting additional information alongside authentication

Regardless of whether JEE based authentication or trusted header based authentication is used, unblu has the possibility to use additional informations to describe an authenticated user or even provide some co-browsing (session) specific informations, which can later be used in analytics or reporting. The information is always retrieved from additional request headers or request attributes with a configurable name for each access group.

5.1. User "display name"

Often authentication information provided by single sign on systems is some identifier, contract number or otherwise technical string, which is hardly usable by human beings in a co-browsing session. On the other hand, it is very important for agents and customers to know who they're connected to. It increases trust, if the mouse label of the co-browsing mouse contains a name and not just some technical contract number. To support this, unblu allows providing "display names" alongside the basic authentication informations.

Please be advised, that the following settings only specify, how the display name information can be retrieved from request information. Whether this information is going to be used e.g. for the mouse labels in co-browsing or whether some other information is to be used can be configured. Please see this document for more details.

NOTE: Although the display name can only be retrieved from request headers or attributes, the configuration of the respective header names is different for JEE based authentication versus trusted header based.

5.1.1. Display name with JEE based authentication

When JEE based authentication is used, use these settings:

# display name to extract for public (untrusted) access group
com.unblu.authentication.idpropagation.jee.headerDisplayName=
 
# display name to extract for internal (trusted) access group
com.unblu.authentication.idpropagation.jee.headerDisplayNameTrusted=
 
# display name to extract for system access group
com.unblu.authentication.idpropagation.jee.headerDisplayNameSystem=

Same as for the trusted header name configuration in general, it is not required to configure header names for all access groups. Instead it's enough to just configure the header name for the public access group and leave the internal and system access groups with their defaults. internal and system access groups will pick the public access group header name in that case.

5.1.2. Display name with trusted header based authentication

When trusted header based authentication is used, use these settings:

# display name to extract for public (untrusted) access group
com.unblu.authentication.idpropagation.trustedheader.headerDisplayName=x-unblu-trusted-user-name

# display name to extract for internal (trusted) access group
com.unblu.authentication.idpropagation.trustedheader.headerDisplayNameTrusted= 
 
# display name to extract for system access group
com.unblu.authentication.idpropagation.trustedheader.headerDisplayNameSystem=

Same as for the trusted header name configuration in general, it is not required to configure header names for all access groups. Instead it's enough to just configure the header name for the public access group and leave the internal and system access groups with their defaults. internal and system access groups will pick the public access group header name in that case.

5.2. Other additional informations

The unblu server is able to log co-browsing session informations. This data includes informations about the users involved in the co-browsing session. Sometimes it turns out, that the authentication data itself is not enough to analyze the session informations later on. Since - once unblu SSO distribution is setup properly - authentication information is already transmitted with the above described methods, it is also useful to have additional informations sent in a similar way and used by unblu when the session informations are written to the log. Similar to the way "display name" informations are transmitted, such additional information can be provided only by additional request headers or request attributes. Again, configuration property names differ for JEE and trusted header based authentication configuration.

5.2.1. Additional information with JEE based authentication

# additional information to extract for public (untrusted) access group
com.unblu.authentication.idpropagation.jee.headerAdditionalInfo=x-unblu-trusted-additional-information

# additional information to extract for internal (trusted) access group
com.unblu.authentication.idpropagation.jee.headerAdditionalInfoTrusted=

# additional information to extract for system access group
com.unblu.authentication.idpropagation.jee.headerAdditionalInfoSystem=

Same as for the trusted header name configuration in general, it is not required to configure header names for all access groups. Instead it's enough to just configure the header name for the public access group and leave the internal and system access groups with their defaults. internal and system access groups will pick the public access group header name in that case.

5.2.2. Additional information with trusted header based authentication

# additional information to extract for public (untrusted) access group
com.unblu.authentication.idpropagation.trustedheader.headerAdditionalInfo=x-unblu-trusted-additional-information
 
# additional information to extract for internal (trusted) access group
com.unblu.authentication.idpropagation.trustedheader.headerAdditionalInfoTrusted=
 
# additional information to extract for system access group
com.unblu.authentication.idpropagation.trustedheader.headerAdditionalInfoSystem=

Same as for the trusted header name configuration in general, it is not required to configure header names for all access groups. Instead it's enough to just configure the header name for the public access group and leave the internal and system access groups with their defaults. internal and system access groups will pick the public access group header name in that case.

6. Advanced Authorization Support

Apart from the simple access control authorization concept explained in this document, there's a more advanced authorization model available. At the core, this model is based on user roles which then assign permissions to certain access groups requests or actions as a whole.

Unblu SSO distribution package supports extracts roles regardless of JEE authentication or trusted header based authentication configuration from request header or attributes only.

Currently supported roles are:

  • WEBUSER: role representing users with a very low trust level (e.g. anonymous users)
  • REGISTERED_USER: role representing users "known to the system", thus having a certain trust level
  • SUPER_ADMIN: role representing (system) administration users

6.1. Default Role assignment

Requests not providing role informations have the following roles applied automatically:

  • public (untrusted) access group: WEBUSER role
  • internal (trusted) access group: REGISTERED_USER role
  • system access group: No role.

6.2. Roles with JEE based authentication

The following configuration properties define the request header or attribute names to be used to retrieve role informations for a user in a specific request:

# roles to extract for public (untrusted) access group
com.unblu.authentication.idpropagation.jee.headerRoles=x-unblu-trusted-roles
 
# roles to extract for internal (trusted) access group
com.unblu.authentication.idpropagation.jee.headerRolesTrusted=


# roles to extract for system access group
com.unblu.authentication.idpropagation.jee.headerRolesSystem=

Same as for the trusted header name configuration in general, it is  not required to configure header names for all access groups. Instead it's enough to just configure the header name for the public access group and leave the internal and system access groups with their defaults. internal and system access groups will pick the public access group header name in that case.

6.3. Roles with trusted header based authentication

The following configuration properties define the request header or attribute names to be used to retrieve role informations for a user in a specific request:

# roles to extract for public (untrusted) access group
com.unblu.authentication.idpropagation.trustedheader.headerRoles=x-unblu-trusted-roles

# roles to extract for internal (trusted) access group
com.unblu.authentication.idpropagation.trustedheader.headerRolesTrusted=

# roles to extract for system access group
com.unblu.authentication.idpropagation.trustedheader.headerRolesSystem=

Same as for the trusted header name configuration in general, it is  not required to configure header names for all access groups. Instead it's enough to just configure the header name for the public access group and leave the internal and system access groups with their defaults. internal and system access groups will pick the public access group header name in that case.