SAML Authentication: Part 2, Adapter Design Pattern Use Case: Data-SAMLAssertion Attribute Mapping
Security Assertion Markup Language (SAML, pronounced SAM-el) is an open standard for exchanging authentication and authorization data between parties, in particular, between an identity provider and a service provider. SAML is an XML-based markup language for security assertions (statements that service providers use to make access-control decisions). SAML is also:
- A set of XML-based protocol messages
- A set of protocol message bindings
- A set of profiles (utilizing all of the above)
An important use case that SAML addresses is web-browser single sign-on (SSO).
SAML does not specify the method of authentication at the identity provider. The IdP may use a username and password, or some other form of authentication, including multi-factor authentication. A directory service such as RADIUS, LDAP or Active Directory that allows users to log in with a user name and password is a typical source of authentication tokens at an identity provider.
As part of the SAML exchange the IdP can return data that the directory service holds for the authenticating user. This information is exchanged via the SAML AttributeStatement element. In Pega this complex element is logically mapped to the Data-SAMLAssertion-AssertionType.AttributeStatement property as part of the authentication process. This property is accessible via the requestor-scoped D_SAMLAssertionDataPage.
Scenario
Platform: Pega Cloud 8.4.2, Pega Customer Service 8.4.2
A CS solution was delivered which allowed client's employees (referred to as case requestors) to create multiple types of cases via an employee portal. All cases requested required details about the employee that existed in the client's directory service provider (Microsoft ADFS). These additional details were returned in the SAML response from SSO authentication. The name and number of attributes being returned from the AD in the SAML response could change throughout the planned MLP deliveries. Any AD attributes that did not map to a corresponding OOTB Pega Operator ID property were required only for UI display and Work- level persistence, i.e., these details did not need to be persisted with the corresponding Pega Operator ID for the case requestor.
Solution
Since there was no requirement to persist the additional attributes in the SAML response to the operator id at the time of authentication, it was decided to leverage the requestor-scoped D_SAMLAssertionDataPage which contains all the required attributes.
Figure 1: Data-SAMLAssertion-AssertionType clipboard structure
Figure 1 shows the structure for the D_SAMLAssertionDataPage which would be cumbersome to use directly for any UI display. Furthermore, direct use would violate basic MVC design patterns and would directly couple the UI to the SAML implementation of obtaining additional operator profile details. If later on there is a different SOR for these operator details all UI sections would need refactoring.
Therefore, a business model data layer was created using the business layer class, Org-Data-OperatorProfile, which holds all the required additional requestor details. The D_OperatorProfile data page in Fig. 2 wraps this class acting as the model for any views in the application requiring these details. It calls the getOperatorProfile data transform which has a SOR (system of record) parameter that allows for the decoupling of the business data model from the actual implementation. Decision logic on the getOperatorProfile data transform can determine dynamically which SOR, i.e, implementation, to use. Here we will discuss the SAML SSO here, but later the SOR could be a Rest API or any other valid SOR. This Adapter Design approach can be utilized for any new SOR that is required to retrieve the properties of the Org-Data-OperatorProfile without any refactoring of rules that reference D_OperatorProfile.
Figure 2: Business layer data page for operator profile details.
The SAML SSO response provided an additional challenge because of the complex class structure of Data-SAMLAssertion-AssertionType. To get to any desired attribute name/value pair requires looping through the AttributeStatement.Attribute page list, checking what the name of the property is and then using a When condition to determine which OperatorProfile attribute the value should be mapped to. Recall that the number and/or names of the attributes from the AD provider could change so this approach of conditionally checking the name could quickly get out of control! To minimize the pain and avoid any such conditional logic in the mapping data transform the SetPropertyValue function was used.
Figure 3: MapSAMLAssertion data transform
Figure 3 shows the data transform that maps the Attribute Statement in D_SAMLAssertionDataPage to an integration layer data object, namely Org-Int-SAMLOperatorProfile. This data object has one property per expected attribute being returned from the SAML response with the exact case-sensitive name as the property. The MapSAMLAssertion data transform has two input page parameters
SAMLAssertionType: Page of type Data-SAMLAssertion-AssertionType
OperatorProfile: Page of type Org-Int-SAMLOperatorProfile
It uses the SAMLAssertionType page as the source and maps each name/value pair to a corresponding property on the target OperatorProfile if it exists. If the property does not exist on the OperatorProfile page it simply does not get mapped and the loop at 2.2 continues to the next name/value pair. Step 2.2.1 uses the dummy target Param.SetOutcomeValue so that it can apply the following logic:
@RuleManagement.setPropertyValue(OperatorProfile,.Name,.pyAttributeValueList(1).pyAttributeValue)
Tying it all together the getOperatorProfile data transform implementation in Fig. 4 is for the SAML SOR and is called by D_OperatorProfile in Fig.2. The results MapSAMLAssertion are mapped to an instance of Org-Data-OperatorProfile
Figure 4: getOperatorProfile data transform in class Org-Data-OperatorProfile.