White Papers
Abstract
This 2-part article series de-mystifies the work required to set up a WebSphere DataPower configuration that uses a Kerberos-secured backend server. The first article describes how to create these configurations in a static fashion that uses the DataPower Web Graphical User Interface. This second article describes how to dynamically generate Kerberos tokens by using the DataPower customer stylesheet dp:get-kerberos-apreq method so that all of the client requests are sent to the web application by using the end client Kerberos user ID.
Content
In this second of this 2-part series, you are again working with a solution that has a set of clients that need to connect to a web application on the backend server. This web application, the sample "snoop" application, is still secured by Kerberos authentication. Also, similar to the scenario in the first article, the incoming clients are not authenticated in DataPower via Kerberos. Instead, basic authentication and a Lightweight Directory Access Protocol (LDAP) server are used to authenticate to the DataPower appliance. For this new scenario, you set up a Multi-Protocol Gateway (MPGW) to accept incoming client requests as HTTP GET requests, authenticate and authorize the clients based on their incoming credentials, and then submit the client requests to the backend server by using a Kerberos token to authenticate with the backend server. This is similar to what was done in the first article. However, in you use a more dynamic approach to create the Kerberos ticket. A sample DataPower configuration and a sample custom stylesheet are provided in the Downloadable resources section of this article. Note that DataPower V6.0.0 supports constrained Kerberos delegation. This article does not describe that feature. The last article discussed the steps needed to set up a Kerberos configuration in DataPower in a static fashion by using the DataPower Web Graphical User Interface. We described how to create a Multi-Protocol Gateway (MPGW) configuration that allowed incoming clients to access a web application on a customer's backend server. The application on the backend server was secured via Kerberos authentication. In that static DataPower configuration, all of the client requests were first authenticated and authorized by DataPower by extracting the credentials from the incoming HTTP Basic Authentication Header and verifying them against a Lightweight Directory Access Protocol (LDAP) server. These client requests were then forwarded to the backend server application after DataPower injected a Kerberos ticket into the request. In this static configuration, the Kerberos ticket was generated by using the single DataPower ID registered on the KDC. The actual client user ID was not used to generate the Kerberos ticket in this scenario. As was mentioned in the first article, sending all user requests to the backend server under a single Kerberos user ID is perfectly fine if the backend web application does not need to obtain the originating client user ID from the Kerberos token. In the static configuration scenario, the client has passed the authentication and authorization screening and is, therefore, considered a legitimate user to access the web application. If the client user ID was required in this solution, it could have been passed into the backend server through other potential techniques, such as by using a HTTP request parameter or a SOAP element. However, there can be other solutions with a requirement for the client ID to be passed to the backend application via the Kerberos ticket. In this article, we address this scenario and demonstrate how to use custom stylesheets to dynamically create a Kerberos ticket with the client ID. The scenario that you work with in this second article has a set of clients that need to connect to a web application on the customer's backend server. This web application, the sample "snoop" application, is still secured by Kerberos authentication. Also, similar to the scenario in the first article, the incoming clients are not authenticated in DataPower via Kerberos. Instead, basic authentication and a Lightweight Directory Access Protocol (LDAP) are used to authenticate to our DataPower appliance. For this new scenario, we set up a Multi-Protocol Gateway (MPGW) to accept incoming client requests as HTTP GET requests, authenticate and authorize the clients based on their incoming credentials, and then submit the client requests to the backend server by using a Kerberos token to authenticate with the backend server. This is similar to what was done in the first article. However, in this second senerio you use a dynamic approach to create the Kerberos ticket. The DataPower MPGW in the first article was configured to use a static Client Keytab file that allowed DataPower to generate Kerberos tickets by using the Kerberos user ID defined in that keytab file. Because of this, all of the client requests were mapped to a single Kerberos ID, which used to be Kerberos Principal name for DataPower that is configured in the KDC. This required the authorization filtering steps to be performed in DataPower before allowing a client to access the web application. The backend server did not receive the actual client user ID. In the new scenario, you configure the DataPower MPGW to generate a Kerberos ticket by using the actual client ID as the Kerberos principal name. To do this, the MPGW extracts the client ID and password from the basic authentication credentials. The user ID and password are also stored in the domain's Active Directory (AD) database and the password serves as the secret key by the Key Distribution Center (KDC) when it generates Kerberos tokens. This is the same secret key that is stored in a keytab file when a keytab file is generated for a Service Principal Name (SPN). Therefore, DataPower communicates with the Key Distribution Center (KDC) and requests a service ticket from the KDC for a given client ID by using the extracted password. One key requirement for this new approach is the need for all the clients to have an ID (Principal) in the Kerberos KDC realm. This was not a requirement in the first article. An overview of this dynamic approach is shown in Figure 1. An advantage of this approach is that a Kerberos keytab file does not need to be imported into the DataPower MPGW configuration. Since access to the secret key is achieved dynamically by the extracting it from the incoming client request, it does not need to be extracted from a pre-imported, static keytab file. This helps to simplify the Kerberos keytab administration. A disadvantage to this approach is that it requires a more complicated, programmatic configuration. A DataPower extension function is needed to communicate with the KDC, pass in the required parameters, and request or receive a service ticket. The good news is that even though this MPGW configuration requires a programmatic approach, the custom XLST transform is not difficult to write or understand. There is a good reference manual that provides details on the various extension functions and example snippets showing how the extension functions are used. This reference was initially produced for version 3.8.1 of DataPower, but it is still a useful guide in understanding how to write XSLT stylesheets. Another notable disadvantage to this approach, as we inferred earlier, is the need to ensure that every client has an ID in the KDC realm. In a Windows You do not need to create a client Service Principal Name (SPN), as required in the first article. You instead, use the User Principal Names (UPN) that are associated with all of the Active Directory (AD) user accounts. These same userids are then used for both LDAP authentication and for identity in the Kerberos tickets. For our sample scenario, you create two client IDs in the AD repository. Typically, you either expect that these IDs exist in the directory, or you have to create user IDs for all the clients that is accessing the web application through DataPower. Now run a Windows OS based utility command on the Domain Controller server to view the attributes related to the newly created user IDs to verify the value of the UPN stored in the AD. The command exports the objects from the AD repository and writes them to a specified file. The only other task that you perform on the Domain Controller is to verify that the SPN for the backend server application that exists in the KDC. On WebSphere Application Server, where the snoop application is hosted, the administrator has already set up a user ID and an SPN to be used as the Server SPN. The administrator also created a keytab file for that server SPN account. This keytab file is uploaded to Application Server to allow the decryption of service tickets that are sent to it. As was the case in the first article, you need to obtain this SPN value ( You see the following type of output from this command. In our example, the account name for the server SPN, HTTP/oc4102831681.csupport.com, is "waskerb". You can create a Multi-Protocol Gateway (MPGW) configuration that allows your clients to connect to your backend web application (the snoop application) by using a Kerberos ticket associated with the client's UPN. In this configuration, clients submit HTTP GET requests to DataPower with a basic authentication string that contains the client user ID and password. DataPower accepts a client request, authenticate the user in LDAP, and creates a Kerberos ticket based on the client's UPN. This Kerberos ticket authenticates the backend server and provides access to the snoop application. The response from the snoop application is passed back to the client. Since the client user ID is passed in the Kerberos ticket, the snoop application can generate information that identifies the name of the actual end client. This is a key difference from the first article where the principal name displayed in the snoop output was always the name associated with the single client keytab file that is statically configured in DataPower. Define a front side handler to accept a HTTP GET requests on port "50008" (this is an arbitrary port we have selected for incoming requests), and ignore all requests except those targeted for the "snoop" application. Similar to the first article, you now define the MPGW Policy. The policy authenticates the incoming clients against the LDAP server by using the client provided basic authentication credentials. As part of this policy, however, you are writing and by using a custom XSLT stylesheet transform object that is invoked each time a client request is processed. This stylesheet uses one of the DataPower provided XSLT functions to make a call to the KDC server and creates a Kerberos ticket, by using the client's user ID and password credentials that were passed in with the client's basic authentication string. This allows DataPower to propagate the actual client's user ID to the backend server in the Kerberos ticket. Now create your security action where you are writing your custom XSLT transform code. You first step through the preliminary panels that are a part of the AAA action to configure the authentication and authorization behavior for the incoming client requests. On the final panel of the AAA Access Control Policy, you configure the policy to use a custom XSLT processing stylesheet. In this stylesheet, you write code to programmatically perform the following processing steps: Note: In this example, we are also setting an optional parameter for the dp:get-kerberos-apreq() method to turn on the "generateGssChecksum" option. This forces a checksum to be generated for the Kerberos token. This checksum is required if interacting with more current versions of WebSphere Application Server. When the client request is sent to the backend server, it contains a Kerberos token associated with the actual client user ID. This allows the backend server to authenticate the Kerberos token and identifies the user who made the request. As mentioned before, this is different from the first article of the series, where all the requests are sent to the backend server with one common or shared user ID (user ID associated with the Client keytab file imported into DataPower). Like the demo scenario in the first article of this series, this step is required. If not already done, you need to configure a KDC server for communication with DataPower. Note: The Kerberos realm name must match the realm name used in the client and server SPN values defined earlier in your AAA Post Processing action, such as "CSUPPORT.COM". Case sensitivity is important. You are now at the stage where you can test the MGP configuration and ensure that the client making the request through DataPower can connect to the backend server with the dynamically generated Kerberos service ticket. As in the first article, you again use the "curl" utility to submit the test requests to DataPower. You use the exact same command used in the first article, but you use the port number associated with this new MPGW configuration instead. You also issue the command by using the two user IDs that were set up in the Create Active Directory Client Accounts section. If this HTML content from the response is opened with a browser, it appears similar to Figure 27. As you can see in this response data, the "Remote user" value is set to value of the client who made the request. This is a key difference from the scenario in the first article, where the "Remote user" value was always the user ID associated with the client keytab file that was imported into DataPower. To help clarify what is going on in the custom stylesheet logic, you can enable the DataPower Probe for this MPGW configuration as was discussed in the previous article. After you do this and run a test, you can review the probe output and click the AAA icon. You see something similar to Figure 28. If you click the (show nodeset) link on this panel, you can view the full Finally, if you go back to the Probe panel and click the magnifying glass icon that is located after the AAA action icon, and then click the Headers tab of the resulting panel, you see the "Authorization" header is one of the headers included in the HTTP request. This is the header that was inserted by your custom stylesheet. Also notice the value of this header contains "Negotiate", followed by a string from the "<spnego-apreq-base64>" sub-element. This matches the logic in the stylesheet. See Figure 30. Hopefully, this review helps to reinforce your understanding of the logic in your custom stylesheet. In addition to the troubleshooting tips from the first article, there are a few additional problems that you can encounter when developing this solution that uses a custom XSLT stylesheet. This article demonstrated how to set up a Multi-Protocol Gateway configuration and how to generate Kerberos tokens in a more programmatic fashion by using the DataPower custom stylesheet dp:get-kerberos-apreq method. In other words, you learned how to authenticate by using a client user ID and password, and then submitted requests to the backend server by using the dynamically generated Kerberos principal name. Though the dynamic approach required more upfront configuration and programming, the advantage of this custom stylesheet approach was that a Kerberos keytab file no longer needed to be imported into the DataPower MPGW configuration. Since access to the secret key was achieved dynamically by the extracting it from the incoming client request, it did not have to be extracted from a pre-imported, static keytab file, which helped to simplify the Kerberos keytab administration. Since the client user ID was propagated in the Kerberos ticket, the snoop application-generated information that identified the name of the actual end client. This was the main difference from the first article, where the principal name displayed in the snoop output was always the name associated with the client keytab file. You also learned how to generate the necessary Kerberos artifacts, where those artifacts are used and their purpose. Finally, you looked at a convenient way to test your MPGW configuration by using the "curl" utility and reviewed how to troubleshoot your configuration. If you need further assistance, collect the following MustGather information and contact IBM Support:Introduction
Scenario from the previous article
Dynamic solution scenario
Kerberos interaction in this dynamic scenario

Kerberos and domain controller tasks
Create Active Directory client accounts
democlient1 in the "Full name" field and in the "User logon name" field. Click the Next button, as shown in Figure 2. 

democlient2 for the "Full name" field and "User logon name" field. "DC=support,DC=com" for the one shown below. See Figure 4. ldifde -f c:\temp\ldapData.txt -d "DC=csupport,DC=com" -l *,msDS-KeyVersionNumber -r "(displayName=*)"


HTTP/oc4102831681.csupport.com is the SPN for the demo solution) that was set up for Application Server. Once you find out what the user ID account name is associated with the server SPN, you can issue the following command to verify that this account is still active: setspn -l <userid associated with the server application SPN>
Registered ServicePrincipalNames for CN=waskerb,CN=Users,DC=csupport,DC=com:HTTP/oc4102831681.csupport.com
kerbDemo2MPG by typing this into the "Multi-Protocol Gateway Name" field. Leave the "Type" field set to static-backend.Define the front side handler settings

kerbDemo2FSH in the "Name" field, type 50008 for the "Port Number" field, and check the GET method checkbox below, as shown in Figure 7. Leave all the other fields alone and click the Apply button. 
Define the back side settings
http://9.42.90.238:11000/snoop.
Define the Multi-Protocol Gateway policy
kerbDemo2MPGPolicy for the "Policy Name" field.
kerbDemo2SnoopMatch for the Name field, as shown in Figure 10. 
/snoop for the "URL Match" value, as shown in Figure 11. 

Define an AAA action



kerbDemo2AAAPolicy and click the Create button.

LDAP Load Balancer Group: <load balancer group of LDAP servers; default is "none"> Host: <ip address or host name of LDAP server> Port: <LDAP port; default value is "389"> SSL Proxy Profile: <name of ssl proxy profile; default is "none"> LDAP Bind DN: <bind Distinguished Name (DN) that has permission to search LDAP directory> LDAP Bind Password: <bind DN password> LDAP Search Attribute: <default is "dn"> LDAP Version: <default is "v2"> LDAP Search for DN: <default is "off"> LDAP Prefix: <String prepended to username to form a DN to search for, default is "cn="> LDAP Suffix: <default is blank field> Use Auxiliary LDAP Attributes: <default is none>



<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:dp="http://www.datapower.com/extensions" extension-element-prefixes="dp"> <xsl:output method="xml"/> <xsl:template match="/"> <!-- ********** Get the userid and password from the basic authentication parameters. Typically this authenticates user id. You will get it from the AU output. But since that will be a DN, it makes sense, in this case, to get it from the request directly as the id is already authenticated. ********** --> <xsl:variable name="userid"> <xsl:value-of select="dp:auth-info('basic-auth-name')"/> </xsl:variable> <xsl:variable name="pwd"> <xsl:value-of select="dp:auth-info('basic-auth-password')"/> </xsl:variable> <!-- ********** Create the Kerberos Client SPN by using the user ID as SPN value. Also create the Kerberos Service SPN by using a hard coded value. This SPN is the backend Web Application. ********** --> <xsl:variable name="kerb_client_spn" select="concat($userid,'@CSUPPORT.COM')" /> <xsl:variable name="kerb_server_spn" select="'HTTP/oc4102831681.csupport.com@CSUPPORT.COM'" /> <!-- ********** Set up an option parameter to generate a checksum as part of this ticket. ********** --> <xsl:variable name="options"> <options GenerateGssChecksum="on" GssChecksumFlags="REPLAY+SEQUENCE+CONF+INTEG" RequestForwardableTicket="on"/> </xsl:variable> <!-- ********** Then generate the Kerberos ticket for the Client SPN (to talk with the Server SPN) ********** --> <xsl:variable name="kerb_apreq" select="dp:kerberos-get-apreq($kerb_client_spn,concat ('password:', $pwd), $kerb_server_spn, $options)"/> <!-- ********** Extract the "spnego-apreq-base64" element from the generated Kerberos ticket. ********** --> <xsl:variable name="kerb_apreq_base64"> <xsl:value-of select="concat('Negotiate ',$kerb_apreq/apreq/spnego-apreq-base64)"/> </xsl:variable> <!-- ********** Add the kerberos token as an HTTP "Authorization" header to the outgoing HTTP request. ********** --> <dp:set-http-request-header name="'Authorization'" value="$kerb_apreq_base64"/> </xsl:template> </xsl:stylesheet> 





curl -v --basic -u "democlient1:d3m0Passw0rd" http://9.42.125.176:50008/snoop
curl -v --basic -u "democlient1:d3m0Passw0rd" http://9.42.125.176:50008/snoop * About to connect() to 9.42.125.176 port 50008 (#0) * Trying 9.42.125.176... connected * Connected to 9.42.125.176 (9.42.125.176) port 50008 (#0) * Server auth by using Basic with user 'democlient1' > GET /snoop HTTP/1.1 > Authorization: Basic ZGVtb2NsaWVudDE6ZDNtMFBhc3N3MHJk > User-Agent: curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.14.3.0 zlib/1.2.3 libidn/1.18 libssh2/1.4.2 > Host: 9.42.125.176:50008 > Accept: */* > < HTTP/1.1 200 OK < X-Backside-Transport: OK OK < Connection: Keep-Alive < Transfer-Encoding: chunked < WWW-Authenticate: Negotiate oT0wO6ADCgEAoQsGCSqGSIb3EgECAqMnBCVgIwYJKoZIhvcSAQICAQERAP///// VzFR7ke/rP5A/+RIL7+bo ... ... ... <tr><td>Server name</td><td>9.42.90.238</td></tr> <tr><td>Server port</td><td>11000</td></tr> <tr><td>Remote user</td><td>CN=democlient1,CN=Users,DC=csupport,DC=com</td></tr> <tr><td>Remote address</td><td>9.42.125.176</td></tr> <tr><td>Remote host</td><td>DPL2XG1.rtp.raleigh.ibm.com</td></tr> <tr><td>Remote port</td><td>48559</td></tr> <tr><td>Local address</td><td>9.42.90.238</td></tr> <tr><td>Local host</td><td>oc4102831681.csupport.com</td></tr> … … … <tr><td>com.ibm.websphere.servlet.application.host</td><td>server1</td> </tr><tr><td>com.ibm.websphere.servlet.application.name</td><td>Default Web Application</td></tr> <tr><td>com.ibm.ws.webcontainer.config.WelcomeFileList</td><td>[index.html]</td> </tr> <tr><td>com.ibm.websphere.servlet.enterprise.application.name</td><td>DefaultApplication </td></tr> <tr><td>javax.servlet.context.tempdir</td><td>/opt/ibm/SDP/runtimes/base_v7/profiles/ WTE_APPSRV71/temp/localhostNode01/server1/DefaultApplication/DefaultWebApplication.war</td></tr> <tr><td>com.ibm.websphere.servlet.event.ServletContextEventSource</td><td> com.ibm.ws.webcontainer.webapp.WebAppEventSource@66646664</td></tr> <tr><td>com.ibm.wsspi.portletcontainer</td><td>com.ibm.ws.portletcontainer.pcinvoker. PortletContainerImpl@6a5c6a5c</td></tr> </table><BR><BR> </body></html> * Connection #0 to host 9.42.125.176 left intact * Closing connection #0


<apreq> element that is generated by dp:get-kerberos-apreq function that you called in your custom stylesheet. Observe that the <spnego-apreq-base64> sub-element within this token. This is the information that your custom stylesheet extracts from the token and places into a temporary variable. See Figure 29.

Troubleshooting tips
Problem Symptom Resolution Invalid user ID is used by the client in the Basic Authentication string when submitting requests to DataPower. Debug the level messages seen in the DataPower error log:
mpgw (kerbDemo2MPG): anyauthenticated authorization failed with credential 'SPECIAL-FORMAT-NOT-PRINTED' for resource '/snoop'
mpgw (kerbDemo2MPG): Client principal 'democlient3@CSUPPORT.COM' not found in Kerberos KDC databaseVerify that the user ID is a valid user in the Active Directory. If not, use a valid user ID. Make sure that principals for all the client users of the web application are created in the KDC. Invalid user ID password is used by the client in the Basic Authentication string when submitting requests to DataPower. Debug the level message seen in the DataPower error log:
mpgw (kerbDemo2MPG): request kerbDemo2MPGPolicy_rule_0 #1 aaa: 'INPUT kerbDemo2AAAPolicy stored in OUTPUT' failed: Rejected by policy.Use the correct password for the given user ID. Syntax error in the custom XSLT stylesheet. Debug the level message seen in the DataPower error log:
mpgw (kerbDemo2MPG): dp:transform(): local:///kerbDemo2Custom.xsl: illegal character ' ' at line 13 of local:///kerbDemo2Custom.xslReview the XSL file that was uploaded to DataPower and correct the code line or lines specified in the error message. Conclusion
Was this topic helpful?
Document Information
Modified date:
08 June 2021
UID
ibm11109643