+

Search Tips   |   Advanced Search

Generation of SPNEGO tokens for outbound JAX-WS requests

The com.ibm.wsspi.security.auth.krb5. SpnegoTokenHelper class can be used to programmatically create a SPNEGO token.

There are 5 different variations for obtaining the Kerberos credentials used for the outbound SPNEGO token:

  1. A token requested using Windows Native credentials. When the WebSphere Java process is running on a Windows system with a userid, which has Kerberos credentials, the Windows OS maintains a Kerberos Ticket Granting Ticket (TGT) for that user. The SpnegoTokenHelper class uses that TGT to request a SPNEGO token that can be requested for a ServicePrincipalName (SPN) for the target service system.
  2. A token requested using cached Kerberos credentials. On a system where a user has logged in, typically using tools such as the Java kinit tool, the user's Kerberos credentials are stored in a cache file named krb5cc_<userid>. Alternatively, a keytab file containing a user's key can be created using a number of tools such as Microsoft's ktpass tool, or the Java ktab tool. These files contain a copy of the user's Kerberos key that can be used to get a Ticket Granting Ticket (TGT) for that userid. The SpnegoTokenHelper class uses that TGT to request a SPNEGO token that can be requested for a ServicePrincipalName (SPN) for the target service system. The WebSphere process must be configured to use either the krb5cc_<userid> or keytab file. The UserPrincipalName (UPN) for the cached credential within the file must also be provided.
  3. A token requested using a Kerberos credential that uses a userid and password. In this scenario, the WebSphere process uses the SpnegoTokenHelper class to connect to the Kerberos Key Distribution server with the supplied userid and password to get a Ticket Granting Ticket (TGT). The class then requests the SPNEGO token with that TGT. The SpnegoTokenHelper class requires the ServicePrincipalName (SPN) for the target service system, and the userid and password.
  4. A token requested using a Kerberos credential existing within a Java Subject. The Subject can obtain a Kerberos credential in one of the following ways:

    • The user logged in to a web application using inbound SPNEGO Web authentication. Only SPNEGO Web Authentication needs to be configured and enabled in the WAS for this option. The Kerberos userid associated with the inbound SPNEGO service must be enabled for full Kerberos delegation.
    • A JAX-WS web service request was received containing a WS-Security Kerberos token. The Kerberos userid associated with the inbound web service request must be enabled for full Kerberos delegation.

    • The user logged in with the userid and password, and the WAS was configured for LTPA and Kerberos authentication.
    • A JAX-WS web service request was received containing a user name token with a password, and the WAS was configured for LTPA and Kerberos authentication. The SpnegoTokenHelper class will use the credentials in the Subject to request a service ticket for the ServicePrincipalName (SPN) for the target service system. The methods associated with this approach require a Java Subject parameter, in addition to the SPN value.

    • Token requested using a Kerberos credential within the Java Subject of the current Caller identity. This approach is similar to the previous approach, and a convenience method is used within the SpnegoTokenHelper class to obtain the current Caller identity. The constraints on the Subject mentioned previously still apply. The methods associated with this approach require only the ServicePrincipalName (SPN).

All 5 approaches have two variations; in the first variation, the lifetime of the token can be specified and a Boolean flag indicating that a delegatable token must be requested. In the second variation, the token lifetime is infinite, and the token is not requested as delegatable.

All 5 approaches return a string (for example "Negotiate YIIFKwYG…."). It is the programmer's responsibility to use the string to inject the outbound Authorization header.

Notes for Native credentials

The Microsoft Kerberos Logon Session credentials cache (MSLSA) relies on the ability to extract the entire Kerberos ticket, including the session key from the Kerberos Logon Session credentials cache (LSA). In an attempt to increase security, Microsoft has implemented a feature by which they no longer export the session keys for Ticket Getting Tickets, which can cause them to be useless to the IBM JGSS when attempts are made to request more service tickets. This new feature has been seen in Windows 2003 Server and later systems. Microsoft has provided the following registry key to disable this new feature:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa\Kerberos\Parameters
AllowTGTSessionKey = 0x01 (DWORD)

Requirements in the Kerberos configuration file

The Kerberos configuration file must be correctly configured regardless of the approach.

  • How the WebSphere process reaches the Key Distribution Center (KDC) must be properly configured via the [realms] and [domain_realm] stanzas.

  • The encryption types to be used in the [libdefaults] stanza must specify the default_tkt_enctypes and default_tgs_enctypes values.

  • The [libdefaults] stanza must include the following:

    • forwardable = true
    • renewable = true
    • noaddresses = true

  • The [libdefaults] stanza must define a reasonable clockskew value.


Referencing a keytab

To use a created keytab, a JAAS configuration must reference the keytab. Since none of the JAAS configurations that are shipped with WebSphere know which keytab to use, we must copy an existing JAAS configuration, and add the reference to the keytab. As an example, the WAS uses the <profile>/properties/wsjaas.conf file for JAAS login configurations.

New JAAS login configuration referencing a keytab file called the cachKerbUser.keytab file.

JAASClientUsingKeytab {
  com.ibm.security.auth.module.Krb5LoginModule required  useKeytab="file:///C:\\WAS\\ND855\\profiles\\AppSrv01\\config\\cells\\testserver-vmCell01-855\\cachKerbUser.keytab" credsType=both 
tryFirstPass=true forwardable=true noAddress=true;
};

When a user performs a Kerberos login with the Java kinit tool, the user's Kerberos credentials are stored in a cache file named krb5cc_<userid>. To use this cache credential, define a JAAS configuration file that references the cached credential, similar to the previous example.


Examples of using the SPNEGOTokenHelper class

In the first example, a SPNEGO token is obtained for a user based on the Windows Native Credentials that the WebSphere process is running under.

String nativeToken = SpnegoTokenHelper.buildSpnegoAuthorizationStringFromNativeCreds(spn,  GSSCredential.INDEFINITE_LIFETIME, false); 

The parameters are:

The second example demonstrates using a keytab or cached credentials file. In this example, the simpler method is used (no lifetime is specified, and the token is not delegatable)

String token = SpnegoTokenHelper.buildSpnegoAuthorizationFromUpn(spn,upn, jaas);

New parameters introduced in the method are:

The third example shows using a userid and password to generate a Kerberos token.

String token = SpnegoTokenHelper.buildSpnegoAuthorizationFromUseridPassword(spn,userid,pwd,1000,true);

New parameters introduced are userid and password. The example also demonstrates requesting a non-infinite token - the token is generated for 1000 seconds, and it is delegatable (the service associated with this spn must be enabled for delegation).

The fourth example shows a rarely used mechanism where you begin with a Subject containing a Kerberos credential. This example is shown for completeness, but unless you programmatically control creation of the Subject, we will not likely use this method.

String token = buildSpnegoAuthorizationFromSubject(spn, subject);

The final example shows using the Kerberos credential from the Caller Subject. Internally, this method calls the previous method.

String token = SpnegoTokenHelper.buildSpnegoAuthorizationFromCallerSubject(spn);

For further details, see Generation of SPNEGO tokens for outbound JAX-WS requests using Client Policy Set Bindings.