You're logging in to the WAS 5 server, not to the WAS 6 server, by the
looks of it. You need to explicitly login to the remote server, just as
you would from a client. The WAS 5 server is not secured, and so will
not pass any credentials to the remote server.
After the login, before you check for principals, do a
WSSubject.doAs(lc.getSubject()), instead of subject = lc.getSubject()
Enabling global security should not affect applications. If they have no
constraints defined, nothing should change. However, by *not* enabling
it, anyone can get to your admin console and make system changes, which
is really not a good thing.
As for Java version mismatch problems, the sending server also is a V6 actually in my test scenario. It will be a V5 server in the end, but this should not be a problem now.
I am not sure how to create a Subject for the invocation with all the right info. Is there another way than using a LoginContext? I would expect that lc.login(); is performing a login on the target server, since I "performed an InitialContext and default lookup prior to logging in" first, as described in the programmatic login example. However I think a login is performed on the sending server and since Global Security is not enabled there, I get a subject with no principals. (I tried a login with a wrong user name and password also and I get the same result). I also checked logs and trace after the lc.login, and I noticed that nothing was recorded on the target server.
I am calling the EJB method in a PrivilegedAction, as shown in the programmatic login example:
// create action to access the protected bean method
java.security.PrivilegedAction createDossierId = new java.security.PrivilegedAction() {
public Object run() {
Long id = null;
try {
Object obj = ctx
.lookup(CONTEXT_ROOT
+ "ejb/.../.../DossierServiceRemoteHome");
DossierServiceRemoteHome home = (DossierServiceRemoteHome) PortableRemoteObject
.narrow(obj, DossierServiceRemoteHome.class);
DossierServiceRemote dossierServiceRemote = home.create();
id = dossierServiceRemote.createDossierId();
} catch (... ) {
...
}
return id;
}
};
// invoke the secure action using the created subject
Long id = (Long) com.ibm.websphere.security.auth.WSSubject
.doAs(subject, createDossierId);
The SystemOut.log on the target server contains the following lines:
4/15/08 13:20:59:657 CEST 00000061 RoleBasedAuth A SECJ0305I: The role-based authorization check failed
for admin-authz operation Server:getName. The user UNAUTHENTICATED (unique ID: UNAUTHENTICATED) was not
granted any of the following required roles: administrator, operator, configurator, monitor.
4/15/08 13:40:59:844 CEST 00000069 RoleBasedAuth E SECJ0306E: No received or invocation credential
exist on the thread. The Role based authorization check will not have an accessId of the caller to
check. The parameters are: access check method getName on resource Server and module Server. The stack
trace is java.lang.Exception: Invocation and received credentials are both null
at com.ibm.ws.security.role.RoleBasedAuthorizerImpl.checkAccess(RoleBasedAuthorize rImpl.java:251)
at com.ibm.ws.management.AdminServiceImpl.preInvoke(AdminServiceImpl.java:1799)
at com.ibm.ws.management.AdminServiceImpl.preInvoke(AdminServiceImpl.java:1706)
at com.ibm.ws.management.AdminServiceImpl.preInvoke(AdminServiceImpl.java:1636)
at com.ibm.ws.management.AdminServiceImpl.preInvoke(AdminServiceImpl.java:1609)
at com.ibm.ws.management.AdminServiceImpl.getAttribute(AdminServiceImpl.java:590)
at com.ibm.ws.management.connector.AdminServiceDelegator.getAttribute(AdminService Delegator.java:117)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:85)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:58)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.ja va(Compiled Code))
at java.lang.reflect.Method.invoke(Method.java(Compiled Code))
at com.ibm.ws.management.connector.soap.SOAPConnector.invoke(SOAPConnector.java:34 5)
at com.ibm.ws.management.connector.soap.SOAPConnector.service(SOAPConnector.java:2 10)
at com.ibm.ws.management.connector.soap.SOAPConnection.handleRequest(SOAPConnectio n.java:55)
at com.ibm.ws.http.HttpConnection.readAndHandleRequest(HttpConnection.java:680)
at com.ibm.ws.http.HttpConnection.run(HttpConnection.java:484)
at com.ibm.ws.util.ThreadPool$Worker.run(ThreadPool.java(Compiled Code))
.
4/15/08 13:40:59:860 CEST 00000069 RoleBasedAuth A SECJ0305I: The role-based authorization check failed for admin-authz operation Server:getName. The user UNAUTHENTICATED (unique ID: UNAUTHENTICATED) was not granted any of the following required roles: administrator, operator, configurator, monitor.
At the client-side I receive the following stack-trace:
javax.naming.NamingException: Error during resolve. Root exception is org.omg.CORBA.NO_IMPLEMENT: No
available target vmcid: 0x49421000 minor code: 40 completed: No
at com.ibm.ws.cluster.router.selection.SelectionManager.getTarget(SelectionManager .java:264)
at com.ibm.ws.cluster.router.selection.WLMClientForCommonRouterImpl.
getNextTarget(WLMClientForCommonRouterImpl.java:221)
at com.ibm.ws.wlm.client.WLMClient.getNextTarget(WLMClient.java:187)
at com.ibm.rmi.corba.ClientDelegate._createRequest_WLM(ClientDelegate.java:1990)
org.omg.CORBA.NO_PERMISSION: java.rmi.AccessException: ; nested exception is:
com.ibm.websphere.csi.CSIAccessException: SECJ0053E: Authorization failed for /UNAUTHENTICATED
while invoking (Home)ejb/com/xxxx/xxxx/xxxx/ejb/DossierServiceRemoteHome create:2
securityName: /UNAUTHENTICATED;accessID: UNAUTHENTICATED is not granted any of the required roles:
AeosUser vmcid: 0x0 minor code: 0 completed: No
at com.ibm.ws.security.core.SecurityCollaborator.performAuthorization(SecurityColl aborator.java:490)
at com.ibm.ws.security.core.EJSSecurityCollaborator.preInvoke(EJSSecurityCollabora tor.java:193)
at com.ibm.ejs.container.EJSContainer.preInvokeForStatelessSessionCreate(EJSContai ner.java:3601)
at com.ibm.ejs.container.EJSContainer.preInvoke(EJSContainer.java:2813)
at com.xxxx.xxxx.xxxx.ejb.EJSRemoteStatelessDossierServiceHome_9d61e50f.create(Unk nown Source)
at com.xxxx.xxxx.xxxx.ejb._EJSRemoteStatelessDossierServiceHome_9d61e50f_Tie.
create(_EJSRemoteStatelessDossierServiceHome_9d61e50f_Tie.java:161)
at com.xxxx.xxxx.xxxx.ejb._EJSRemoteStatelessDossierServiceHome_9d61e50f_Tie.
_invoke(_EJSRemoteStatelessDossierServiceHome_9d61e50f_Tie.java:86)
at com.ibm.CORBA.iiop.ServerDelegate.dispatchInvokeHandler(ServerDelegate.java:610 )
at com.ibm.CORBA.iiop.ServerDelegate.dispatch(ServerDelegate.java:463)
at com.ibm.rmi.iiop.ORB.process(ORB.java:439)
at com.ibm.CORBA.iiop.ORB.process(ORB.java:1737)
at com.ibm.rmi.iiop.Connection.doWork(Connection.java:2260)
at com.ibm.rmi.iiop.WorkUnitImpl.doWork(WorkUnitImpl.java:65)
at com.ibm.ejs.oa.pool.PooledThread.run(ThreadPool.java:95)
at com.ibm.ws.util.ThreadPool$Worker.run(ThreadPool.java(Compiled Code))
org.omg.CORBA.NO_PERMISSION: java.rmi.AccessException: ; nested exception is:
com.ibm.websphere.csi.CSIAccessException: SECJ0053E: Authorization failed for /UNAUTHENTICATED
while invoking (Home)ejb/com/xxxx/xxxx/xxxx/ejb/DossierServiceRemoteHome create:2
securityName: /UNAUTHENTICATED;accessID: UNAUTHENTICATED is not granted any of the required roles:
AeosUser vmcid: 0x0 minor code: 0 completed: No
at com.ibm.ws.security.core.SecurityCollaborator.performAuthorization(SecurityColl aborator.java:490)
at com.ibm.ws.security.core.EJSSecurityCollaborator.preInvoke(EJSSecurityCollabora tor.java:193)
at com.ibm.ejs.container.EJSContainer.preInvokeForStatelessSessionCreate(EJSContai ner.java:3601)
at com.ibm.ejs.container.EJSContainer.preInvoke(EJSContainer.java:2813)
at com.xxxx.xxxx.xxxx.ejb.EJSRemoteStatelessDossierServiceHome_9d61e50f.create(Unk nown Source)
at com.xxxx.xxxx.xxxx.ejb._EJSRemoteStatelessDossierServiceHome_9d61e50f_Tie.
create(_EJSRemoteStatelessDossierServiceHome_9d61e50f_Tie.java:161)
at com.xxxx.xxxx.xxxx.ejb._EJSRemoteStatelessDossierServiceHome_9d61e50f_Tie.
_invoke(_EJSRemoteStatelessDossierServiceHome_9d61e50f_Tie.java:86)
at com.ibm.CORBA.iiop.ServerDelegate.dispatchInvokeHandler(ServerDelegate.java:610 )
at com.ibm.CORBA.iiop.ServerDelegate.dispatch(ServerDelegate.java:463)
at com.ibm.rmi.iiop.ORB.process(ORB.java:439)
at com.ibm.CORBA.iiop.ORB.process(ORB.java:1737)
at com.ibm.rmi.iiop.Connection.doWork(Connection.java:2260)
at com.ibm.rmi.iiop.WorkUnitImpl.doWork(WorkUnitImpl.java:65)
at com.ibm.ejs.oa.pool.PooledThread.run(ThreadPool.java:95)
at com.ibm.ws.util.ThreadPool$Worker.run(ThreadPool.java(Compiled Code))
END server: 1198777258 at host xxxx.xxxx.com
vmcid: 0x0 minor code: 0 completed: No
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessor Impl.java:80)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructor AccessorImpl.java:44)
at java.lang.reflect.Constructor.newInstance(Constructor.java:315)
at com.ibm.rmi.iiop.ReplyMessage._getSystemException(ReplyMessage.java:199)
at com.ibm.rmi.iiop.ReplyMessage.getSystemException(ReplyMessage.java:148)
at com.ibm.rmi.iiop.ClientResponseImpl.getSystemException(ClientResponseImpl.java: 207)
at com.ibm.rmi.corba.ClientDelegate.intercept(ClientDelegate.java:952)
at com.ibm.rmi.corba.ClientDelegate.invoke(ClientDelegate.java:434)
at com.ibm.CORBA.iiop.ClientDelegate.invoke(ClientDelegate.java:1150)
at com.ibm.rmi.corba.ClientDelegate.invoke(ClientDelegate.java:748)
at com.ibm.CORBA.iiop.ClientDelegate.invoke(ClientDelegate.java:1180)
at org.omg.CORBA.portable.ObjectImpl._invoke(ObjectImpl.java:486)
at com.xxxx.xxxx.xxxx.ejb._DossierServiceRemoteHome_Stub.
create(_DossierServiceRemoteHome_Stub.java:215)
at com.xxxx.xxxx.servlet.DossierServiceEJBTestServlet$1.run(DossierServiceEJBTestS ervlet.java:198)
at java.security.AccessController.doPrivileged(AccessController.java:207)
at javax.security.auth.Subject.doAs(Subject.java:477)
at com.ibm.websphere.security.auth.WSSubject.doAs(WSSubject.java:118)
at com.xxxx.xxxx.servlet.DossierServiceEJBTestServlet.doPost(DossierServiceEJBTest Servlet.java)
at com.xxxx.xxxx.servlet.DossierServiceEJBTestServlet.doGet(DossierServiceEJBTestS ervlet.java:88)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:743)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:856)
at com.ibm.ws.webcontainer.servlet.ServletWrapper.service(ServletWrapper.java:1282 )
at com.ibm.ws.webcontainer.servlet.ServletWrapper.handleRequest(ServletWrapper.jav a:673)
at com.ibm.ws.webcontainer.servlet.CacheServletWrapper.handleRequest(CacheServletW rapper.java:80)
at com.ibm.ws.webcontainer.WebContainer.handleRequest(WebContainer.java:1802)
at com.ibm.ws.webcontainer.channel.WCChannelLink.ready(WCChannelLink.java:84)
at com.ibm.ws.http.channel.inbound.impl.HttpInboundLink.handleDiscrimination(HttpI nboundLink.java:469)
at com.ibm.ws.http.channel.inbound.impl.HttpInboundLink.handleNewInformation(HttpI nboundLink.java:408)
at com.ibm.ws.http.channel.inbound.impl.HttpInboundLink.ready(HttpInboundLink.java :286)
at com.ibm.ws.tcp.channel.impl.NewConnectionInitialReadCallback.
sendToDiscriminaters(NewConnectionInitialReadCallback.java:201)
at com.ibm.ws.tcp.channel.impl.NewConnectionInitialReadCallback.
complete(NewConnectionInitialReadCallback.java:103)
at com.ibm.ws.tcp.channel.impl.WorkQueueManager.requestComplete(WorkQueueManager.j ava:566)
at com.ibm.ws.tcp.channel.impl.WorkQueueManager.attemptIO(WorkQueueManager.java:61 9)
at com.ibm.ws.tcp.channel.impl.WorkQueueManager.workerRun(WorkQueueManager.java:95 2)
at com.ibm.ws.tcp.channel.impl.WorkQueueManager$Worker.run(WorkQueueManager.java:1 039)
at com.ibm.ws.util.ThreadPool$Worker.run(ThreadPool.java:1455)
I also enabled tracing on the target server as discussed in the Security components troubleshooting tips. I will e-mail the full trace to you.
any luck with the login scenario since?
I have looked at the trace.log, but it is quite long. Is there any marker in the trace that I should look for to find the failing part? There are several login attempts in the trace, not sure which one I need to look at.
Just as a test, try to enable security on the sending server just to find out if your code supposed to work in that environment. Hopefully that is going to work.
The trusted server setting is good, I believe you should have that in place to make this scenario work.
I am looking at your code from the thread, I would suggest to use the callback handler where you can also pass the realm name, to ensure that you have the subject created for the right target environment:
//...
CallbackHandler loginCallbackHandler = new WSCallbackHandlerImpl(targetUsername, targetRealm, targetPassword);
LoginContext lc = new LoginContext("WSLogin", loginCallbackHandler);
lc.login();
Subject subject = lc.getSubject();
// subject should have the detail here already
//...
The PrivilegedAction.run() implementation seems to be OK, however I have a different context initialization code that works for me:
//...
public Object run() {
//...
Hashtable env = new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.ibm.websphere.naming.WsnInitialContextFactory");
env.put(Context.PROVIDER_URL, "iiop://" + REMOTE_SERVER + ":" + REMOTE_PORT);
Context initialContext = new InitialContext(env);
Object ejbHome = initialContext.lookup(REMOTE_EJB_JNDI);
//then the rest of the EJB call...
Hope this helps...
Peter
I abandoned this scenario. For now I disabled global security on the WAS 6 server and doing everything insecure. In the near future I will be migrating the WAS 5 server to a WAS 6 server. Then I will have global security enabled on both servers.
I did some tests with global security enabled on both servers. I followed Scenario 1: Identity propagation from your article . This worked fine.
As for the current scenario... The receiving server apparently does not receive a subject. I think it is trying to use LTPA, but the sending server does not support it because global security is disabled.
Some lines from the trace:
[4/15/08 13:20:59:548 CEST] 00000056 StateofCurrOb 3 setCallerSubject() null updatePropagationTokenWithSubjectChange Entry
[4/15/08 13:20:59:548 CEST] 00000056 SubjectHelper updatePropagationTokenWithSubjectChange Exit
[4/15/08 13:20:59:548 CEST] 00000056 StateofCurrOb 3 setCallerSubject() null subject
[4/15/08 13:20:59:548 CEST] 00000056 StateofCurrOb 3 setInvocationSubject() null subject
[4/15/08 13:20:59:548 CEST] 00000056 StateofCurrOb 3 secConfig has been initialized.
[4/15/08 13:20:59:548 CEST] 00000056 SASRas 3 [CurrentImpl.initialize_requestor_context], [ServerID: server1]
Requestor context being initialized with null (customRealm, token, system.RMI_INBOUND, . . .) Entry
[4/15/08 13:20:59:563 CEST] 0000005c distContextMa 3 Web inbound login config: system.WEB_INBOUND
[4/15/08 13:20:59:563 CEST] 0000005c distContextMa 3 Looking for opaque token on the thread before Subject cache lookup.
I think Scenario 4: Server-side identity assertion from your article would best apply to my situation because "a specific protocol (for example, CSIv2) is not available to propagate security information for identity assertion".
I would like to thank you and also Paul for your support.
Walter