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.