REST Service Authentication using the SmartFramework IHybridRealm implementation

The SmartFramework REST Interface supports authentication and authorization based on the Spring Security Framework integrated into the Tomcat REST Adapter Implementation provided with OpenEdge.

Authentication using the IHybridRealm 

The SmartFramework IHybridRealm implementation supports both the basic http/https and form based authentication models. The authentication model is defined by referencing one of the PSC provided authentication templates from the REST services WEB-INF\web.xml file.

In this example the appSecurity-form-oerealm.xml is the only reference that is not commented out and therefor the effective authentication definition (by default the appSecurity-anonymous.xml is active).

The sample configuration files are attached:

web.xml, excerpt
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
            <!-- USER EDIT: Select which application security model to employ
            /WEB-INF/appSecurity-basic-local.xml
            /WEB-INF/appSecurity-anonymous.xml
            /WEB-INF/appSecurity-form-local.xml
            /WEB-INF/appSecurity-container.xml
            /WEB-INF/appSecurity-basic-ldap.xml
            /WEB-INF/appSecurity-form-ldap.xml
            /WEB-INF/appSecurity-basic-oerealm.xml
            /WEB-INF/appSecurity-form-oerealm.xml
            /WEB-INF/appSecurity-form-saml.xml
            /WEB-INF/appSecurity-basic-saml.xml
            -->
            /WEB-INF/appSecurity-form-oerealm.xml
        </param-value>
    </context-param>

For the Pacific AppServers (PASOE) the file names are slightly different (starting with oeablSecurity- instead of appSecurity-).

Within the selected security model definition file a few settings need to be made. Please refer to the Progress documentation for more details on the settings in those files:

OEClientPrincipalFilter

OEClientPrincipalFilter
    <!-- The security filter that turns a Spring token into an OpenEdge
         ClientPrincipal object -->
    <b:bean id="OEClientPrincipalFilter"
             class="com.progress.rest.security.OEClientPrincipalFilter">
             <b:property name="enablecp" value="true" />
             <b:property name="ccid" value="true" />
             <b:property name="domain" value="consultingwerk" />
             <b:property name="key" value="abc123"/>   
    </b:bean>

This section defines properties of the client principal object maintained by the REST Adapter and passed to the OpenEdge AppServer with each request.

The client principal is important as it can provide authentication and session information to the AppServer

Setting

Description

enablecp

Should a client principal be generated

ccid

Should the client principal contain a session id that allows to reference session context in a persistent storage

domain

The domain name referenced in the client principal. The domain name will be matched with the Domain Name of the SmartFramework Login Company

key

The seal used to sign the client principal

OERealmAuthProvider

OERealmAuthProvider
    <b:bean id="OERealmAuthProvider"
            class="com.progress.rest.security.OERealmAuthProvider" >
            <b:property name="userDetailsService">
                        <b:ref bean="OERealmUserDetails"/>
            </b:property>
            <b:property name="userDomain" value="consultingwerk" />
            <b:property name="createCPAuthn" value="false" />
    </b:bean>

This section defines the domain appended to the user name for authentication. Typically this domain should match the domain name specified in the OEClientPrincipalFilter section.

OERealmUserDetails

OERealmUserDetails
    <b:bean id="OERealmUserDetails"
            class="com.progress.rest.security.OERealmUserDetailsImpl" >
            <b:property name="realmURL" value="AppServer://localhost:5162/restbroker1" />
            <b:property name="realmClass" value="Consultingwerk.Web2.SmartFramework.Authentication.SmartHybridRealm" />
            <b:property name="grantedAuthorities" value="ROLE_PSCUser" />
            <b:property name="rolePrefix" value="ROLE_" />
            <b:property name="roleAttrName" value="ATTR_ROLES" />
            <b:property name="enabledAttrName" value="ATTR_ENABLED" />
            <b:property name="lockedAttrName" value="ATTR_LOCKED" />
            <b:property name="expiredAttrName" value="ATTR_EXPIRED" />
            <b:property name="realmPwdAlg" value="0" />
            <!--
            <b:property name="realmTokenFile" value="" />
            -->
            <!-- For SSL connection to the oeRealm appserver provide the complete
                 path of psccerts.jar as the value of 'certLocation' property
             -->
            <b:property name="certLocation" value="" />
            <!-- set appendRealmError = true in order to append the Realm 
            class thrown error in the error details send to the REST Client -->
            <b:property name="appendRealmError" value="false" /> 
    </b:bean>

 This section defines the authentication service and enables the AppServer to call into the IHybridRealm implementation. 

Setting

Description

realmURL

The URL of the AppServer used for authentication. It’s not required that this is the same AppServer that will execute the actual request.

realmClass

The name of the IHybridRealm implementation, for instance “Consultingwerk.Web2.SmartFramework.Authentication.SmartHybridRealm”

Authentication in the SmartHybridRealm class

The SmartHybridRealm class is the reference SmartFramework IHybridRealm implementation. This class authenticate users against the SmartLoginCompany and SmartUser tables.

The Password is stored in encoded form in the SmartUser table.

The Login Company is located based on the Tenand Domain Name information.

Once the user name is verified the IHybridRealm implementation refers to the user based on an integer user id. This user id must be provided in the user maintenance. The user id is unique.

Request Activation using the RestServerSessionActivator

AppServer Startup Procedure

As the user context is passed differently from a GUI for .NET Client (context dataset exchanged between client and AppServer) and REST clients (client principal provided by the REST Adapter) a different method for activating the server session is required.

In our reference implementation the AppServer startup procedure Consultingwerk/Framework/Server/rest_startup.p should be used for all AppServers that should serve REST calls.

This startup procedure loads services from these two xml files: 

  • Consultingwerk/Framework/Server/rest_services.xml
  •  Consultingwerk/SmartFramework/services_server.xml

The rest_services.xml file loads the RestServerSessionActivator instead of the ServerSessionActivator class.

The rest_start.p does also initialize the IConfigurationManager based on the .restapplicationsettings file allowing specialized settings for REST AppServers. 

RestServerSessionActivator

The server session activator is invoked from the ServiceInterface’s Activate and Deactivate events. In general the server session activator is responsible for populating the AppServer’s session with information received with the current request.

The RestServerSessionActivator especially extracts information form the provided client principal object and assigns the user and company specific properties of the SessionManager class – thus providing the foundation for authorization and localization.

The RestServerSessionActivator verifies the seal of the client principal using the key provided in the .restapplicationsettings property clientPrincipalSeal.

The class further locates the SmartUser and SmartLoginCompany record based on the USER-ID and DOMAIN-NAME properties of the client principal.

The process further locates the default user’s language and then assigns the following session manager properties.

The following SessionManager properties will be assigned:

 

  • LoginCompanyKey
  • LoginCompanyName
  • LoginCompanyReferenceChar
  • LoginCompanyReferenceDecimal
  • LoginCompanyReferenceInteger
  • LoginCompanyShortName
  • UserName
  • LanguageDisplayName
  • LanguageIsoCode
  • LanguageKey
  • UserGroupKeys
  • UserGroupNames