loading table of contents...

8.3. Single Sign On Integration

The default CoreMedia Studio authentication process is implemented based on Spring Security. Due to this open standard it is easy to replace the standard authentication mechanism with a common redirect based SSO system like Atlassian Crowd or CAS. While the authentication process can be replaced, the CoreMedia Content Server still needs to have a matching user provider configured in order to perform a fine grained authorization. Please refer to the [CoreMedia Content Server Manual] for further details about user providers.

This documentation does not replace the SSO manufacturers manual about how to integrate with Spring Security. This section only covers CoreMedia Studio specific adjustments that need to be made to a generic integration.

[Warning]Warning

Do not modify the authentication process and the Spring Security filter chain unless you know what you are doing. An improperly configured security context can cause severe security issues.

Custom Component

The first step to integrate with a single sign on system is to create a custom component as replacement for the editing-rest-security-component. The editing-rest-security-component contains the configuration for the default built-in authentication process. It is not required anymore once there is a SSO integration in place. To replace the component simply replace the editing-rest-security-component dependency in the pom.xml of the studio-webapp with a dependency on the new component.

For further details about component artifacts and how to create them, please refer to the section Application Architecture in the [CoreMedia Digital Experience Platform 8 Developer Manual].

Generic Spring Security Context

The new component has to provide a Spring Security context that holds all the required configuration to authenticate users against your SSO system. Simply create a file /META-INF/coremedia/component-XYZ.xml in the new component and include the following import statement.

    
<import resource="classpath:
/com/coremedia/rest/cap/authentication/editing-rest-security-base.xml"/>

  

Example 8.1. Import base context


Next, create a generic Spring Security context based on the SSO manufacturer's documentation.

Studio Spring Security Context

The core elements of a Spring Security context are the http and the authentication-manager element. The http element is the parent of all functionality related to the web, the authentication-manager holds the configured authentication-provider elements.

Your generic Spring security context for a redirect based SSO solution could look something like:

    
<security:http entry-point-ref="YOUR_ENTRY_POINT" auto-config="false">
  <security:custom-filter position="FORM_LOGIN_FILTER" ref='YOUR_LOGIN_FILTER'/>
  <security:custom-filter position="LOGOUT_FILTER" ref='YOUR_LOGOUT_FILTER'/>

  <security:intercept-url pattern="/api/**" access="YOUR_AUTHORITY"/>
  <security:intercept-url pattern="/index.html" access="YOUR_AUTHORITY"/>
  <security:custom-filter .../>

  <security:session-management session-fixation-protection="newSession"/>
  <security:csrf request-matcher-ref="YOUR_CSRF_REQUEST_MATCHER"/>
</security:http>

<security:authentication-manager alias="authenticationManager">
  <security:authentication-provider ref='YOUR_AUTHENTICATION_PROVIDER'/>
</security:authentication-manager>
  

Example 8.2. Spring Security context


Login

CoreMedia Studio only imposes very minimal constraints to the login process.

Depending on the chosen SSO system the login itself is either performed by a Spring Security filter (internal login page) or an external system (external login page). The only requirement for this part of the login is that at least one recognizable authority is granted to the authenticated user (typically ROLE_XYZ). This authority needs to match the one in the intercept-url elements of the Spring Security http configuration.

The second requirement for the login procedure involves the authentication entry point referenced in the http configuration element. The entry point implementation for a redirect based SSO system usually does some sort of redirect to a login page. While this is sensible behavior for a 'normal' request, it is not expected for Studio REST calls which are XmlHttpRequests to a dedicated /api path. The Studio REST client can not handle redirects to pages reasonably. Unauthenticated REST calls should trigger a 403 response instead which is then handled by Studio with a pop-up message. A separate handling of REST calls and non REST calls can be achieved with a delegating entry point like the following.

    
<bean id="delegatingEntryPoint"
      class="org.springframework.security.web.authentication.DelegatingAuthenticationEntryPoint">
  <constructor-arg>
    <map>
      <entry key-ref="apiMatcher" value-ref="forbiddenAEP"/>
    </map>
  </constructor-arg>
  <property name="defaultEntryPoint" ref="SSO_SPECIFIC_ENTRY_POINT"/>
</bean>

<bean id="forbiddenAEP"
      class="org.springframework.security.web.authentication.Http403ForbiddenEntryPoint"/>

<bean id="apiMatcher"
      class="org.springframework.security.web.util.matcher.AntPathRequestMatcher">
  <constructor-arg value="/api/**"/>
</bean>

  

Example 8.3. Delegating entry point


Authorization

In addition to the authorization happening in the Content Server Spring Security is used to perform a pre-authorization at HTTP level. For a redirect based SSO system, it is best practice to pre-authenticate all requests to the REST API (/api path) and to the index.html. A set of intercept-url elements in the http configuration checks for the granted authority that the SSO system assigns to authenticated users.

Logout

CoreMedia Studio expects a logout listener to listen to POST requests the context relative path /logout. It has to trigger at least the default Spring Security SecurityContextLogoutHandler and the predefined capLogoutHandler bean. While the SecurityContextLogoutHandler resets the security context, the capLogoutHandler ensures that all CapConnections for the current user are closed and released.

The logout listener must not listen to GET requests as this might result in a CSRF vulnerability. For simplicity reasons you can use the logoutRequestMatcher bean from the base security context.

A simple logout filter might look similar to this:

    
<bean id="logoutFilter" class="org.springframework.security.web.authentication.logout.LogoutFilter">
  <constructor-arg value="LOGOUT_SUCCESS_TARGET"/>
  <constructor-arg>
    <list>
      <ref bean="capLogoutHandler"/>
      <ref bean="SSO_SPECIFIC_LOGOUT_HANDLER_IF_NEEDED"/>
      <bean class="org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler"/>
    </list>
  </constructor-arg>
  <property name="logoutRequestMatcher" ref="logoutRequestMatcher"/>
</bean>
  

Example 8.4. Logout filter


Depending on the chosen SSO system it might be required to add another SSO specific logout handler or define additional single sign out filters in the Spring Security filter chain.

Other Configuration

While not required for the core functionality it is still highly recommended including a csrf and session-management configuration in your http settings.

The csrf configuration is used to enable the Spring Security CSRF protection. It must be enabled for all vulnerable HTTP verbs like POST, PUT, DELETE, the Studio client ensures that a valid token is included in the affected requests.

The session-management configuration together with the session-fixation-protection attribute is used to explicitly enable the Spring Security session fixation protection. The attribute value can safely be set to newSession.

User Finder

After finishing the configuration of the Spring Security context, there is one last Studio specific step to do.

So far you have set up a Spring Security context that is using the default Spring Security authentication providers and user detail services for your SSO system to authenticate users and load user details. These user details are usually represented by a SSO specific details object linked to the Spring Security Authentication object.

While keeping the default implementations in the authentication process hugely simplifies the SSO configuration, CoreMedia Studio still needs to know the matching com.coremedia.cap.user.User for the current SSO specific user details. Each individual Unified API operation has to be performed in the name of the currently authenticated User in order to be able to perform a fine grained authorization in the CoreMedia Content Server. To do this mapping between SSO specific user details and a User for the chosen SSO system, you have to implement a SpringSecurityUserFinder.

The SpringSecurityCapUserFinder interface consists of only one method that finds a User for a given Authentication object. In order to write a finder for the chosen SSO system you can simply extend the AbstractSpringSecurityCapUserFinder that already has a CapConnection available.

      
public class XYZSpringSecurityCapUserFinder
        extends AbstractSpringSecurityCapUserFinder
        implements SpringSecurityCapUserFinder {

  @Override
  public User findCapUser(Authentication authentication) {
    Object principal = authentication.getPrincipal();
    if (principal instanceof XYZ) {
      String username = GET_USER_NAME_FROM_USER_DETAILS;
      return getCapConnection().getUserRepository()
             .getUserByName(username, DOMAIN);
    }
    return null;
  }
}

    

Example 8.5. User finder


The custom user finder is enabled by replacing the Spring bean springSecurityCapUserFinder in the Spring context.

      
<customize:replace id="customSpringSecurityCapUserFinder"
                   bean="springSecurityCapUserFinder">
  <bean class="XYZSpringSecurityCapUserFinder"
        parent="abstractSpringSecurityCapUserFinder"/>
</customize:replace>

    

Example 8.6. Enable user finder


Session Tracking Mode

In order to prevent the JSESSIONID from appearing as an URL parameter it is recommended to add the following configuration to your web.xml:

<session-config>
  <tracking-mode>COOKIE</tracking-mode>
</session-config>