Implementing a Security Authorization Handler

An AuthRequest object represents the instantiation of an authorization request. An array of AuthRequest objects is instantiated when an authorization request message is processed by the PeopleTools security authorization service.

An authorization request message has many standard elements such as, SERVICEID, SERVICE_TYPE, PORTAL, NODE, CREFID, and so on. In addition, an authorization request message will have one or more KEYVAL elements. Typically, you as the implementer of the GetAuthorization method should determine the structure of the corresponding authorization request message, and specifically, the number and type of KEYVAL elements. You will use the value of these KEYVAL elements along with other data in the authorization request to determine whether a specific request is authorized.

Example Scenario

In this example, employee details are available in Application A while employee performance and appraisal data resides in Application B. The user Rodrigo is the manager of a team. Rodrigo makes a request to view employee performance information for two employees: Callahan and Daniel. Rodrigo is Callahan’s manager while Daniel is a higher level manager in a different part of the organization.

The PeopleTools security authorization service can be used to determine whether these requests are authorized.

Authorization Request Message

Application A will send the following authorization request as a SOAP message to Application B requesting that user Rodrigo be given access to the performance data for employees Callahan and Daniel. The authorization request message is contained between the <PARAMARRAY> </PARAMARRAY> delimiters.

<?xml version="1.0"?>
<soapenv:Envelope xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsa="http://schemas.xmlsoap.org/ws/2003/03/addressing/" xmlns:xsd="http://www.w3.org/2001/XMLSchema/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance/">
  <soapenv:Header xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
    <wsse:Security soap:mustUnderstand="1" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
      <wsse:UsernameToken>
        <wsse:Username>RODRIGO</wsse:Username>
      </wsse:UsernameToken>
    </wsse:Security>
  </soapenv:Header>
  <soapenv:Body xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
    <FindAccess xmlns="http://xmlns.oracle.com/Enterprise/Tools/schemas/PTCSSecurityReq.v1">

    <PARAMARRAY>
      <PARAMS>
        <SERVICEID>1</ SERVICEID >
        <SERVICE_TYPE>UPGE</SERVICE_TYPE>
        <NODE>APP_B_NODE</NODE>
        <MENU>PERFORMANCE_MENU</MENU>
        <COMPONENT>PERFORMANCE_DTL_COMP</COMPONENT>
        <MARKET>GBL</MARKET>
        <COMP_ITEM_NAME>PERFORMANCE_DTL</COMP_ITEM_NAME>
        <KEYVAL>EMPLID=CALLAHAN</KEYVAL>
      </PARAMS>

      <PARAMS>
        <SERVICEID>2</SERVICEID >
        <SERVICE_TYPE>UPGE</SERVICE_TYPE>
        <NODE>APP_B_NODE</NODE>
        <MENU>PERFORMANCE_MENU</MENU>
        <COMPONENT>PERFORMANCE_DTL_COMP</COMPONENT>
        <MARKET>GBL</MARKET>
        <COMP_ITEM_NAME>PERFORMANCE_DTL</COMP_ITEM_NAME>
        <KEYVAL>EMPLID=DANIEL</KEYVAL>
      </PARAMS>
    </PARAMARRAY>

    </FindAccess>
  </soapenv:Body>
</soapenv:Envelope>

Example Security Handler

The PeopleTools security authorization service receives the message and first performs basic PeopleTools security authorization (user-role-permission list). If basic PeopleTools security authorization is valid for the requested object (a component, for example), the PeopleTools security authorization service will pass the request on to the security handler defined for this object. The PeopleTools security authorization service will encapsulate all the message elements such as user ID, node, component, and, key values into an AuthRequest object.

The following code provides an example security handler class that evaluates whether a user is authorized to see the performance details for a given employee ID. If the employee is a subordinate of the invoking user, then access granted; access is denied in all other instances such as a peer requesting performance data for a peer, an employee requesting access to his or her supervisor’s performance data, or an employee requesting performance data from another department in the organization.

import PTCS_SECURITY:Security:*;

class SampleSecurityHandler extends PTCS_SECURITY:Security:SecurityHandler
   /*method AuthRequestHandler(&arrAuthReq As array of PTCS_SECURITY:Security:AuthRequest);*/
   method GetAuthorization(&arrAuthReq As array of PTCS_SECURITY:Security:AuthRequest);
   method isEmpSubordinate(&userid As string, &emplid As string) Returns boolean;
end-class;

/*method AuthRequestHandler*/
method GetAuthorization
   /+ &arrAuthReq as Array of PTCS_SECURITY:Security:AuthRequest +/
   /+ Extends/implements PTCS_SECURITY:Security:SecurityHandler.GetAuthorization +/
   
   
   Local string &emplid;
   Local string &userid;
   Local integer &i;
   
   For &i = 1 To &arrAuthReq.Len
      
      &emplid = &arrAuthReq [&i].GetParameterValue("EMPLID");
      &userid = &arrAuthReq [&i].UserId;
      /* If the employee ID to which access is requested is a subordinate of the    */ 
      /* invoking uer, grant access; otherwise, deny access for all other requests. */ 
      If %This.isEmpSubordinate(&userid, &emplid) Then
         &arrAuthReq [&i].Access = "T";
      Else
         &arrAuthReq [&i].Access = "F";
      End-If;
      
   End-For;
   
end-method;


method isEmpSubordinate
   /+ &userid as String, +/
   /+ &emplid as String +/
   /+ Returns Boolean +/

   /* Use the organizational hierarchy to determine whether employee ID is a      */ 
   /* subordinate of the invoking user.                                           */
   /* The following example uses a simplified expression to make this             */
   /* determination. In most organizations, this would not be a valid test.       */
   
   If &userid > &emplid Then
      Return True
   Else
      Return False
   End-If;
end-method

Response Message

The preceding security handler class sets the Access property of the AuthRequest object to T when access is granted. It sets the Access property to F for requests that are not authorized. Then, the security handler class returns the AuthRequest object array to the PeopleTools security authorization service. The PeopleTools security authorization service returns a SOAP message similar to the following to the invoking application (Application A). The authorization request response is contained between the <PARAMARRAY> </PARAMARRAY> delimiters.

<?xml version="1.0"?>
<soapenv:Envelope xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsa="http://schemas.xmlsoap.org/ws/2003/03/addressing/" xmlns:xsd="http://www.w3.org/2001/XMLSchema/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance/">
  <soapenv:Header xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
    <wsse:Security soap:mustUnderstand="1" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
     <wsse:UsernameToken>
        <wsse:Username>RODRIGO</wsse:Username>
      </wsse:UsernameToken>
    </wsse:Security>
  </soapenv:Header>
  <soapenv:Body xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
    <FindAccess xmlns="http://xmlns.oracle.com/Enterprise/Tools/schemas/PTCSSecurityReq.v1">

    <PARAMARRAY>
      <PARAMS>
         <SERVICEID>1</SERVICEID>
         <ACCESS>T</ACCESS>
      </PARAMS>

      <PARAMS>
         <SERVICEID>2</SERVICEID>
         <ACCESS>F</ACCESS>
      </PARAMS>
    </PARAMARRAY>

    </FindAccess>
  </soapenv:Body>
</soapenv:Envelope>