14

My application is a stand-alone Swing client invoking EJB Stateless Session beans thanks to classical JNDI lookup and RMI-IIOP method calls. It is started as a Java WebStart application. My aim is to retrieve the client user's identity from EJBContext with getCallerPrincipal method thanks to Kerberos SSO between the Windows workstation, ActiveDirectory and WebSphere server running on Linux.

I have already successfully configured my WebSphere cell in network deployment mode to support Kerberos authentication thanks to the infocenter documentation.

Both krb5.conf and krb5.keytab files are OK and tested with both Linux kinit, klist and wsadmin, $AdminTask validateKrbConfig answers true.

The client setup does only refer to a JAAS login.config file to enable with command system property. My intuition tells me it is probably not enough.

But now, I find no more information to finalize the test case:

  • how the JNDI initial context environment must be setup to trigger Kerberos negotiation ?
  • if there are other requirements on server-side like protect my EJB with a role (JBoss does not require it for instance) ?

Update

As not running JavaEE client container with ./launchClient, I have set in my JNLP the required properties to read sas.client.props and JAAS login configuration:

<property name="java.security.auth.login.config" value="C:\temp\wsjaas_client.config"/>
<property name="com.ibm.CORBA.ConfigURL" value="C:\temp\sas.client.props"/>

My wsjaas_client.config is for Oracle Java so it contains:

WSKRB5Login{
    com.sun.security.auth.module.Krb5LoginModule required
       debug=true useTicketCache=true doNotPrompt=true;
};

My sas.client.props contains:

com.ibm.CORBA.securityEnabled=true
com.ibm.CORBA.authenticationTarget=KRB5
com.ibm.CORBA.loginSource=krb5Ccache
com.ibm.CORBA.loginUserid=
com.ibm.CORBA.loginPassword=
com.ibm.CORBA.krb5CcacheFile=
com.ibm.CORBA.krb5ConfigFile=C:\\temp\\krb5.conf

At the moment, no Kerberos authentication is triggered: there is no TGS for the SPN WAS/myserver.mydomain.com in my kerberos cache (either from Windows or Linux workstations) and JNDI connection is still established anonymously.

No error message, no warning and finally no principal. How do I diagnose what's wrong or lacking?

Update 2012/06/20

Here are some steps forward. In my application JNLP running with Oracle Java, I have set the following properties to use IBM ORB and enable full trace and debug information:

<property name="org.omg.CORBA.ORBSingletonClass" value="com.ibm.rmi.corba.ORBSingleton"/>
<property name="org.omg.CORBA.ORBClass" value="com.ibm.CORBA.iiop.ORB"/>
<property name="traceSettingsFile" value="C:\temp\TraceSettings.properties"/>

The file TraceSettings.properties contains

traceFileName=c:\\temp\\traces.log
ORBRas=all=enabled
SASRas=all=enabled
com.ibm.*=all=enabled

Even after reading large parts of WebSphere 7 Security IBM RedBook I still fail to get CSIv2 trigger Kerberos authentication from client-side.

slm
  • 15,396
  • 12
  • 109
  • 124
Yves Martin
  • 10,217
  • 2
  • 38
  • 77

3 Answers3

6

According to the GSS-API/Kerberos v5 Authentication guide you must authenticate to Kerberos before making your call to the JNDI context. Once you have performed the Kerberos configuration you configure the intial context as follows:

  • When creating the initial context, set the Context.SECURITY_AUTHENTICATION(in the API reference documentation) environment property to the string "GSSAPI".

I have dealt with getting a Java Client to use Kerberos in the past (although not with JNDI). Here is my approach to remove the need for JVM options and local configuration files on the client side (invoke this code before the client attempts to authenticate):

public static void initKerberosConfig() 
{                 
        System.setProperty("javax.security.auth.useSubjectCredsOnly", "false"); 
        System.setProperty("java.security.krb5.kdc", "host.name:88"); 
        System.setProperty("java.security.krb5.realm", "REALM"); 
        System.setProperty("sun.security.krb5.debug", "false");                                 
        Configuration progConfig = getProgramaticLoginConfig(); 
        Configuration.setConfiguration(progConfig); 
} 

private static Configuration getProgramaticLoginConfig() 
{ 
        HashMap<String, String> options = new HashMap<String, String>(); 
        options.put("useTicketCache", "true"); 
        options.put("doNotPrompt", "true");                                                 
        AppConfigurationEntry krb5LoginModule = new AppConfigurationEntry("com.sun.security.auth.module.Krb5LoginModule", LoginModuleControlFlag.REQUIRED, options); 
        final AppConfigurationEntry[] aces = new AppConfigurationEntry[]{krb5LoginModule}; 
        Configuration progConfig = new Configuration() 
        { 
                @Override 
                public AppConfigurationEntry[] getAppConfigurationEntry(String arg0) 
                {                                 
                        return aces; 
                } 

        }; 
        return progConfig; 
} 

You will probably need to tweak this for your context (java.security.krb5.kdc and java.security.krb5.realm will not be correct) - but I hope it helps. Turn sun.security.krb5.debug true for voluminous quantities of logging.

Malcolm Smith
  • 3,540
  • 25
  • 29
  • Thanks but you describe a "low level" Kerberos usage. In my case, I should have no code to write as Kerberos support is included in IBM CORBA ORB implementation and it should be configurable (definitely not easy at all...) – Yves Martin May 22 '12 at 07:48
  • Ok - I don't have experience of using IBM CORBA ORB, but bear in mind - this is not code, it is configuration. This code is simply a programatic replacement for the required JVM options and Krb5LoginModule configuration file. – Malcolm Smith May 22 '12 at 08:56
  • I understand it replaces the java.security.auth.login.config option and following stuff... – Yves Martin May 22 '12 at 09:21
  • updated answer with info on JNDI authentication - the getProgramaticLoginConfig is still required in this secanario - but may need to be modified to fit your configuration requirements – Malcolm Smith May 22 '12 at 10:07
  • I have to test GSSAPI value for Context.SECURITY_AUTHENTICATION if if reference is not IBM-JDK or WebSphere specific. Good tip ! – Yves Martin May 22 '12 at 15:06
  • WebSphere InitialContext only accepts values "none", "simple" or "strong" (not supported yet) for Context.SECURITY_AUTHENTICATION. I had to decompile classes to learn that... – Yves Martin Jun 21 '12 at 14:14
  • But are you not creating the JNDI context on your client? In the Sun/Oracle JVM? – Malcolm Smith Jun 28 '12 at 16:27
  • Yes, I create a JNDI Context in Oracle JavaSE 6 with IBM orb in ClassPath and with factory `com.ibm.websphere.naming.WsnInitialContextFactory` and documented CORBA properties to get everything work (and it is. Only Kerberos auth does not). To understand why, since WebSphere 6, it can run on Oracle JavaSE 6 to target Solaris platform too. In fact, IBM JVM is only available for Windows and Linux. – Yves Martin Jun 29 '12 at 06:12
4

Since you didn't specifically mentioned in steps you followed, have you configured your sas.client.props as in the client setup link you have provided?

You may check RedBook Implementing Kerberos in a WebSphere Application Server Environment for examples on how to make this configuration, as well as remaining configuration for Application Client.

Section 13.5 (13.5 Configuring the Java EE application client) gives examples for setting up your thick client runtime, including sas.client.props file.

Arjan Tijms
  • 37,782
  • 12
  • 108
  • 140
Kurtcebe Eroglu
  • 1,934
  • 11
  • 15
  • 1
    I have already all that references. The sas.client.props is definitely not enough... there is no kerberos authentication triggered yet. So the two questions I ask. – Yves Martin May 18 '12 at 12:24
  • The sas.client.props has been modified on the WebSphere server itself according the infocenter documentation... I agree the PDF is easier to follow. But I run my EJB client as standalone JVM - I do not use JavaEE client container with launchClient. – Yves Martin May 18 '12 at 12:39
  • My application is a Java WebStart application. I have added properties for wsjaas_client.config file and properties from sas.client.properties : com.ibm.CORBA.authenticationTarget=KRB5 and com.ibm.CORBA.loginSource=krb5Ccache but it changes nothing. JNDI connection remains un-authenticated. – Yves Martin May 21 '12 at 15:10
3

To sum up the context: our deployment is in production since years with IBM WebSphere running on Linux and application deployed thanks to Java WebStart running on Sun JavaSE 6 with IBM ORB included and configured to connect without any authentication. Now we want to enable Kerberos authentication and single-sign-on over RMI-IIOP, supported since WebSphere 6 (I think).

Here are now pieces of answer.

Since WebSphere 7, a new concept has been introduced to configure security aspects on a per server basis: security domain. Theoretically any option that has not been changed in a security domain inherits from the global security section.

When testing Kerberos setup, we have created a dedicated security domain for our test server, to avoid troubles with other servers running in the cell.

BUT even if Kerberos is enabled in global security, it is not inherited/enabled for a server configured with its own security domain.

As soon as we run our test server with the default global security where Kerberos options are visible and enabled, then Kerberos authentication has began to work with IBM JavaSE 6 executed from a cmd bat script with usual ClassPath and all properties declared in documentation.

To note: the JNDI Context.SECURITY_AUTHENTICATION option is never set. After decompilation, the only available values for IBM ORB are none, simple and strong but strong has no implementation yet.

Another point: according to generated log, IBM ORB is not able to work with file:/C:/temp/sas.client.config as value for com.ibm.CORBA.ConfigURL. It MUST be an URI and not a file path. We even got DNS lookup failure to resolve C hostname ! Arff. All documentation examples are Unix based with file:/path/to/sas.client.config so we made many trials before delivering that file from an HTTP server.

Now the Java WebStart part of the deployment:

  • the same original JNLP without any security and no Kerberos settings works perfectly with both Oracle JavaSE 6 and IBM Java 6

  • with WebSphere security enabled and Kerberos in JNLP (and only that change set), IBM ORB running on IBM Java 6 complains with NoClassDefFoundError about ffdc log manager implementation that is (still/always) available in ClassPath. It really sounds like a code incompatibility with Java WebStart secured ClassLoader hierarchy.

  • with Kerberos JNLP, IBM ORB running on Oracle JavaSE 6 seems to simply ignore security settings and connects anonymously as usual.

So a first step is now working: IBM Java 6 started from command-line but investigations are not over to reach our goal: Kerberos with Oracle JavaSE 6 in Java WebStart context.

Yves Martin
  • 10,217
  • 2
  • 38
  • 77
  • According to IBM, at the moment IBM JavaSE 6 is required at both ends to get Kerberos authentication working over IIOP. So it may mean it does not work at all for WebSphere running over Oracle JavaSE on Solaris but I have doubt about it. Probably the same JVM is required at each side - but this is not my current configuration. – Yves Martin Aug 25 '12 at 21:48