0

I'm writing a test demo to test the client to server connection on Liberty 17.0.0.3.

On the WebSphere 8.5.5.11, the client test demo code is like below:

public class DSLoginConfiguration extends Configuration
{
    public AppConfigurationEntry[] getAppConfigurationEntry(java.lang.String applicationName)
    {
        Hashtable<String, String> h = new Hashtable<String, String>();
        h.put("delegate", "com.ibm.ws.security.common.auth.module.WSClientLoginModuleImpl");
        AppConfigurationEntry entry = new AppConfigurationEntry(
                "com.ibm.ws.security.common.auth.module.proxy.WSLoginModuleProxy",
                AppConfigurationEntry.LoginModuleControlFlag.REQUIRED, h);
        return new AppConfigurationEntry[] { entry };
    }

    public void refresh()
    {

    }
}


public class RMITest {

    private String hostName;
    private String password;
    private String userName;
    private InitialContext initialContext;

    public RMITest(String hostName, String userName, String password) {
        this.hostName = hostName;
        this.userName = userName;
        this.password = password;
    }

    protected LoginContext createLoginContext(String userName, String password) throws Exception {
        Configuration config = new DSLoginConfiguration();
        Configuration.setConfiguration(config);
        LoginContext loginContext = new LoginContext("ClientContainer",
            new WSCallbackHandlerImpl(userName, "customRealm", password));
        return loginContext;
    }

    private void loginRMIproxy() throws Exception {
        LoginContext lc = createLoginContext(userName, password);
        lc.login();
        Subject s = lc.getSubject();
        System.out.println("*****Subject*****" + s);
        System.out.println("*****Principals*****" + s.getPrincipals());
        System.out.println(s.getPrincipals().size());
        WSSubject.setRunAsSubject(s);
    }

    protected void runTest() {
        try {
            System.out.println("************** Begin RMI Test **************");
            loginRMIproxy();
            System.out.println("************** End RMI Test **************");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

public class HelloWorldClient {
    public static void main(String[] args) throws Exception {
        String hostName = "localhost";
        String userName = "quoc";
        String password = "April";

        RMITest rmiTest = new RMITest(hostName, userName, password);
        rmiTest.runTest();
    }
}

And it can connect successfully. But when I test this client demo code on Liberty, it throws Exception below:

javax.security.auth.login.LoginException: unable to find LoginModule class: com.ibm.ws.security.common.auth.module.proxy.WSLoginModuleProxy
at javax.security.auth.login.LoginContext.invoke(LoginContext.java:828)
at javax.security.auth.login.LoginContext.access$000(LoginContext.java:196)
at javax.security.auth.login.LoginContext$4.run(LoginContext.java:698)
at javax.security.auth.login.LoginContext$4.run(LoginContext.java:696)
at java.security.AccessController.doPrivileged(AccessController.java:650)
at javax.security.auth.login.LoginContext.invokePriv(LoginContext.java:696)
at javax.security.auth.login.LoginContext.login(LoginContext.java:597)
at com.client.RMITest.loginRMIproxy(RMITest.java:73)
at com.client.RMITest.runTest(RMITest.java:86)
at com.client.HelloWorldClient.main(HelloWorldClient.java:19)

I find the class WSLoginModuleProxy has different package on Liberty. so I Change the Class DSLoginConfiguration like below:

public class DSLoginConfiguration extends Configuration
{
    public AppConfigurationEntry[] getAppConfigurationEntry(java.lang.String applicationName)
    {
        Hashtable<String, String> h = new Hashtable<String, String>();
        h.put("delegate", "com.ibm.ws.security.client.jaas.modules.WSClientLoginModuleImpl");
        AppConfigurationEntry entry = new AppConfigurationEntry(
                "com.ibm.ws.security.jaas.common.modules.WSLoginModuleProxy",
                AppConfigurationEntry.LoginModuleControlFlag.REQUIRED, h);
        return new AppConfigurationEntry[] { entry };
    }

    public void refresh()
    {

    }
}

But it still throw a Exception

javax.security.auth.login.LoginException: java.lang.ClassCastException: java.lang.String incompatible with java.lang.Class
at com.ibm.ws.security.jaas.common.modules.WSLoginModuleProxy.initialize(WSLoginModuleProxy.java:83)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:90)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:55)
at java.lang.reflect.Method.invoke(Method.java:508)
at javax.security.auth.login.LoginContext.invoke(LoginContext.java:774)
at javax.security.auth.login.LoginContext.access$000(LoginContext.java:196)
at javax.security.auth.login.LoginContext$4.run(LoginContext.java:698)
at javax.security.auth.login.LoginContext$4.run(LoginContext.java:696)
at java.security.AccessController.doPrivileged(AccessController.java:650)
at javax.security.auth.login.LoginContext.invokePriv(LoginContext.java:696)
at javax.security.auth.login.LoginContext.login(LoginContext.java:597)
at com.client.RMITest.loginRMIproxy(RMITest.java:74)
at com.client.RMITest.runTest(RMITest.java:87)
at com.client.HelloWorldClient.main(HelloWorldClient.java:19)

at javax.security.auth.login.LoginContext.invoke(LoginContext.java:890)
at javax.security.auth.login.LoginContext.access$000(LoginContext.java:196)
at javax.security.auth.login.LoginContext$4.run(LoginContext.java:698)
at javax.security.auth.login.LoginContext$4.run(LoginContext.java:696)
at java.security.AccessController.doPrivileged(AccessController.java:650)
at javax.security.auth.login.LoginContext.invokePriv(LoginContext.java:696)
at javax.security.auth.login.LoginContext.login(LoginContext.java:597)
at com.client.RMITest.loginRMIproxy(RMITest.java:74)
at com.client.RMITest.runTest(RMITest.java:87)
at com.client.HelloWorldClient.main(HelloWorldClient.java:19)

Then I find there are different ways to get Class WSClientLoginModuleImpl on WebSphere and Liberty by decompiling the jar package. So I change the Class DSLoginConfiguration again like below:

public class DSLoginConfiguration extends Configuration {
    public AppConfigurationEntry[] getAppConfigurationEntry(java.lang.String applicationName) {
        WSClientLoginModuleImpl loginModuleImpl = new WSClientLoginModuleImpl();
        Hashtable<String, Class> h = new Hashtable<String, Class>();
        h.put("delegate", loginModuleImpl.getClass());
        AppConfigurationEntry entry = new AppConfigurationEntry(
                "com.ibm.ws.security.jaas.common.modules.WSLoginModuleProxy",
                AppConfigurationEntry.LoginModuleControlFlag.REQUIRED, h);
        return new AppConfigurationEntry[] { entry };
    }

    public void refresh() {

    }
}

Then it still throw a Exception like below:

javax.security.auth.login.LoginException: java.lang.IllegalStateException: Required attribute is null,AtomicServiceReference[name=clientAuthenticationService,ctx=null,ref=null,svc=null]
at com.ibm.wsspi.kernel.service.utils.AtomicServiceReference.getService(AtomicServiceReference.java:239)
at com.ibm.wsspi.kernel.service.utils.AtomicServiceReference.getServiceWithException(AtomicServiceReference.java:210)
at com.ibm.ws.security.client.internal.jaas.JAASClientService.getClientAuthenticationService(JAASClientService.java:372)
at com.ibm.ws.security.client.jaas.modules.WSClientLoginModuleImpl.login(WSClientLoginModuleImpl.java:110)
at com.ibm.ws.security.jaas.common.modules.WSLoginModuleProxy.login(WSLoginModuleProxy.java:141)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:90)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:55)
at java.lang.reflect.Method.invoke(Method.java:508)
at javax.security.auth.login.LoginContext.invoke(LoginContext.java:788)
at javax.security.auth.login.LoginContext.access$000(LoginContext.java:196)
at javax.security.auth.login.LoginContext$4.run(LoginContext.java:698)
at javax.security.auth.login.LoginContext$4.run(LoginContext.java:696)
at java.security.AccessController.doPrivileged(AccessController.java:650)
at javax.security.auth.login.LoginContext.invokePriv(LoginContext.java:696)
at javax.security.auth.login.LoginContext.login(LoginContext.java:597)
at com.client.RMITest.loginRMIproxy(RMITest.java:72)
at com.client.RMITest.runTest(RMITest.java:85)
at com.client.HelloWorldClient.main(HelloWorldClient.java:19)

at javax.security.auth.login.LoginContext.invoke(LoginContext.java:890)
at javax.security.auth.login.LoginContext.access$000(LoginContext.java:196)
at javax.security.auth.login.LoginContext$4.run(LoginContext.java:698)
at javax.security.auth.login.LoginContext$4.run(LoginContext.java:696)
at java.security.AccessController.doPrivileged(AccessController.java:650)
at javax.security.auth.login.LoginContext.invokePriv(LoginContext.java:696)
at javax.security.auth.login.LoginContext.login(LoginContext.java:597)
at com.client.RMITest.loginRMIproxy(RMITest.java:72)
at com.client.RMITest.runTest(RMITest.java:85)
at com.client.HelloWorldClient.main(HelloWorldClient.java:19)

I looked up a lot of documents, but I can not fix it, So I have to ask for help.

Does anyone know how to fix this or how to connect client and Server on Liberty with custom LoginModule?

Thanks in advance.

  • I get that error if I'm trying to authenticate using a standalone java client and not running in the application client container. Is your app running in the application client container? – F Rowe Dec 29 '17 at 15:22
  • @FRowe Thank you for your reply. My app is not running in the application client container, I'm using a standalone java client to authenticate and call remote EJB. – Chason Zhang Jan 02 '18 at 01:19

1 Answers1

0

The WSClientLoginModuleImpl class is not an API and it is an internal class in Liberty that uses internal OSGi services. The error seen is because a service that is provided in the client container is not available.

The client container is necessary in Liberty to use the WSClientLoginModuleImpl by creating a LoginContext with the "ClientContainer" or "WSLogin" JAAS login context entries.

  • Our goal is to migrate our EJB applications from traditional Websphere to Liberty, and our application use the CS architecture, client is a standalone java client, so we can't put it in client container. We also used the IBM migration tool to migrate our application, but it doesn't work. Can you give me some advice to finsh this migration, Thank you – Chason Zhang Jan 03 '18 at 08:53
  • If we don't use the WSClientLoginModuleImpel to create LoginContext, is there any other way? Thank you. – Chason Zhang Jan 03 '18 at 09:03
  • Please clarify how the standalone java client was executed when using traditional WebSphere since the client would have required an ORB with CSIv2 support in order to use GSSUP to authenticate in the remote server. – Teddy J. Torres Jan 04 '18 at 16:08
  • We configure ORB with CSIv2 support on traditional WebSphere Server and disable SSL, Then the standalone java client can be executed. – Chason Zhang Jan 08 '18 at 07:39