Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Accessing an EJB from a standalone client when websphere security enabled

13 views
Skip to first unread message

regis....@banque-france.fr

unread,
Feb 16, 2006, 8:24:28 AM2/16/06
to
Hi,

A client running on WSAD 5 (or Websphere Thin Application Client) tries
to open a connection on Websphere 5.0 with security enabled (and Java 2
security disabled).

My code snipsnet is:
Hashtable ht = new Hashtable();
ht.put(Context.PROVIDER_URL, "corbaloc:iiop:pc21180e:2809");
ht.put(
Context.INITIAL_CONTEXT_FACTORY,
"com.ibm.websphere.naming.WsnInitialContextFactory");
ht.put(Context.SECURITY_PRINCIPAL, "aze");
ht.put(Context.SECURITY_CREDENTIALS, "aze");

Context initial;
try {
initial = new InitialContext(ht);
QuoteHome home =
(QuoteHome) PortableRemoteObject.narrow(
initial.lookup("ejb/fr/bdf/testrmi/QuoteHome"),
QuoteHome.class);
Quote quote=home.create();
Quotation q = quote.get();

The error is
com.ibm.websphere.csi.CSIException: SECJ0053E: Authorization failed for
/UNAUTHENTICATED while invoking (Bean)ejb/fr/bdf/testrmi/QuoteHome
get:1 securityName: /UNAUTHENTICATED;accessID: null is not granted any
of the required roles: lecteur

The EJB deployment descriptor defines that role 'lecteur' has access to
method get() in bean Quote.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE ejb-jar PUBLIC "-//Sun Microsystems, Inc.//DTD Enterprise
JavaBeans 2.0//EN" "http://java.sun.com/dtd/ejb-jar_2_0.dtd">
<ejb-jar id="ejb-jar_ID">
<display-name>TestRMI</display-name>
<enterprise-beans>
<session id="Quote">
<description>Provides a random quotation</description>
<display-name>Quote</display-name>
<ejb-name>Quote</ejb-name>
<home>fr.bdf.testrmi.QuoteHome</home>
<remote>fr.bdf.testrmi.Quote</remote>
<ejb-class>fr.bdf.testrmi.QuoteBean</ejb-class>
<session-type>Stateless</session-type>
<transaction-type>Bean</transaction-type>
<security-identity>
<description></description>
<run-as>
<description></description>
<role-name>lecteur</role-name>
</run-as>
</security-identity>
</session>
</enterprise-beans>
<assembly-descriptor>
<security-role>
<description>Ce rôle comprend les utilisateurs de l'application. Il
autorise la lecture des citations.</description>
<role-name>lecteur</role-name>
</security-role>
<method-permission>
<role-name>lecteur</role-name>
<method>
<ejb-name>Quote</ejb-name>
<method-intf>Remote</method-intf>
<method-name>get</method-name>
<method-params>
</method-params>
</method>
</method-permission>
</assembly-descriptor>
<ejb-client-jar>TestRMIClient.jar</ejb-client-jar>
</ejb-jar>

I'd appreciate if someone can help me to solve this problem.

--
Régis Décamps

krao_...@yahoo.com

unread,
Feb 18, 2006, 1:59:42 PM2/18/06
to
WAS provides programmatic login process to create a security context. Look for WsSubject, WsLogin api to do a custom login in the client. You may have to deploy the standalone client inside an "application client" container for this to work. Pls postback if it works/helps.

Thanks.

Paul Ilechko

unread,
Feb 18, 2006, 7:13:24 PM2/18/06
to
regis....@banque-france.fr wrote:
> Hi,
>
> A client running on WSAD 5 (or Websphere Thin Application Client) tries
> to open a connection on Websphere 5.0 with security enabled (and Java 2
> security disabled).
>

You need to do a JAAS programmatic login, see here:

http://publib.boulder.ibm.com/infocenter/wasinfo/v5r1//index.jsp?topic=/com.ibm.websphere.nd.doc/info/ae/ae/tsec_pacs.html

>

regis....@banque-france.fr

unread,
Feb 20, 2006, 1:35:13 PM2/20/06
to
Hi,

Thanks for your assistance. I spent some time (in vain). I read the
JAAS doc and tried to call the WsSubject and WsLogin API.

I have changed my EJB invocation, to create a LoginContext, just before
creating the Bean:
Context initial = new InitialContext(env);
log.info("Connection on " + env.getProperty(Context.PROVIDER_URL));
log.debug("Performing lookup of " + jndiLookupName);


QuoteHome home =
(QuoteHome) PortableRemoteObject.narrow(

initial.lookup(jndiLookupName),
QuoteHome.class);
login(); // new method to set the WsSubject

log.debug("Creating Quote from home");
quote = home.create();


The new login() method is
private void login() {
Properties env = System.getProperties();
LoginContext lc = null;
try {
lc=
new LoginContext(
"WSLogin",
new WSCallbackHandlerImpl(
(String) env.get(Context.SECURITY_PRINCIPAL),
(String) env.get(Context.SECURITY_CREDENTIALS)));
lc.login();
} catch (LoginException le) {
System.out.println(
"Cannot create LoginContext. " + le.getMessage());
System.exit(1);
} catch (SecurityException se) {
System.out.println("Cannot create LoginContext." + se.getMessage());
System.exit(2);
}
subject=lc.getSubject();
}

The use of the bean itself is made inside doAs:
log.debug("Calling remote method...");
// Invoke a J2EE resource using the authenticated subject
WSSubject.doAs(subject, new java.security.PrivilegedAction() {
public Object run() {
try {
Quotation q = quote.get();
System.out.println(q.getQuote());

if (q.getAuthor() != null && q.getAuthor().length() > 0) {
System.out.println("\t-- " + q.getAuthor());
}
} catch (Exception e) {
log.error(
"error while accessing EJB resource, exception: "
+ e.getMessage());
e.printStackTrace();
}
return null;
}
});


Unfortunately, the error is unchanged.
java -Djava.naming.provider.url=iiop://pc21180e
-Djava.naming.security.principal=was5admin
-Djava.naming.security.credentials=blabla
-Djava.security.auth.login.config="C:\Program Files\IBM\WebSphere
Studio\Application
Developer\v5.1.2\runtimes\base_v5\properties\wsjaas_client.conf"
Fortune

DEBUG [main] (Fortune.java:51) - Context
factory=com.ibm.websphere.naming.WsnInitialContextFactory
INFO [main] (Fortune.java:56) - Connection on iiop://pc21180e
DEBUG [main] (Fortune.java:57) - Performing lookup of
ejb/fr/bdf/testrmi/QuoteHome
DEBUG [P=741908:O=0:CT] (Fortune.java:83) - Creating Quote from home
DEBUG [P=741908:O=0:CT] (Fortune.java:103) - Calling remote method...
java.rmi.ServerException: RemoteException occurred in server thread;
nested exception is:
java.rmi.RemoteException:

Trace from server: 1198777258 at host pc21180e >>
java.rmi.RemoteException: ; nested exception is:
com.ibm.websphere.csi.CSIException: SECJ0053E: Echec d'autorisation de
/UNAUTHENTICATED lors de l'appel de (Bean)ejb/fr/bdf/testrmi/QuoteHome


get:1 securityName: /UNAUTHENTICATED;accessID: null is not granted any
of the required roles: lecteur

com.ibm.websphere.csi.CSIException: SECJ0053E: Echec d'autorisation de
/UNAUTHENTICATED lors de l'appel de (Bean)ejb/fr/bdf/testrmi/QuoteHome


get:1 securityName: /UNAUTHENTICATED;accessID: null is not granted any
of the required roles: lecteur

at
com.ibm.ws.security.core.SecurityCollaborator.performAuthorization(SecurityCollaborator.java:386)
at
com.ibm.ws.security.core.EJSSecurityCollaborator.preInvoke(EJSSecurityCollaborator.java:170)
at
com.ibm.ejs.container.EJSContainer.preInvoke_internal(EJSContainer.java:2572)
at
com.ibm.ejs.container.EJSContainer.preInvoke(EJSContainer.java:2337)
at
com.ibm.ejs.container.EJSContainer.preInvoke(EJSContainer.java:2322)
at
fr.bdf.testrmi.EJSRemoteStatelessQuote_a60fa3c7.get(EJSRemoteStatelessQuote_a60fa3c7.java:21)
at
fr.bdf.testrmi._EJSRemoteStatelessQuote_a60fa3c7_Tie.get(_EJSRemoteStatelessQuote_a60fa3c7_Tie.java:150)
at
fr.bdf.testrmi._EJSRemoteStatelessQuote_a60fa3c7_Tie._invoke(_EJSRemoteStatelessQuote_a60fa3c7_Tie.java:76)
at
com.ibm.CORBA.iiop.ServerDelegate.dispatchInvokeHandler(ServerDelegate.java:615)
at com.ibm.CORBA.iiop.ServerDelegate.dispatch(ServerDelegate.java:468)
at com.ibm.rmi.iiop.ORB.process(ORB.java:396)
at com.ibm.CORBA.iiop.ORB.process(ORB.java:1608)
at com.ibm.rmi.iiop.Connection.doWork(Connection.java:2164)
at com.ibm.rmi.iiop.WorkUnitImpl.doWork(WorkUnitImpl.java:63)
at com.ibm.ejs.oa.pool.PooledThread.run(ThreadPool.java:95)
at com.ibm.ws.util.ThreadPool$Worker.run(ThreadPool.java:593)
<< END server: 1198777258 at host pc21180e

; nested exception is:
com.ibm.websphere.csi.CSIException: SECJ0053E: Echec d'autorisation de
/UNAUTHENTICATED lors de l'appel de (Bean)ejb/fr/bdf/testrmi/QuoteHome


get:1 securityName: /UNAUTHENTICATED;accessID: null is not granted any
of the required roles: lecteur

at
com.ibm.CORBA.iiop.UtilDelegateImpl.mapSystemException(UtilDelegateImpl.java:156)
at javax.rmi.CORBA.Util.mapSystemException(Util.java:83)
at fr.bdf.testrmi._Quote_Stub.get(_Quote_Stub.java:244)
at Fortune$1.run(Fortune.java:111)
at java.security.AccessController.doPrivileged(Native Method)
at javax.security.auth.Subject.doAs(Subject.java:476)
at com.ibm.websphere.security.auth.WSSubject.doAs(WSSubject.java:106)
at Fortune.go(Fortune.java:108)
at Fortune.main(Fortune.java:130)
Caused by: java.rmi.RemoteException:

I really wonder how to pass the identity to the server (accessID: null
is not granted any of the required roles). Do you know how to perform
this action with the Universal Test Client, by the way. I'd like to
have a way to know which of my client or my server is broken.

Thanks,
--
Régis

PS: Sorry for this long post

Paul Ilechko

unread,
Feb 20, 2006, 3:17:31 PM2/20/06
to
regis....@banque-france.fr wrote:

> I really wonder how to pass the identity to the server (accessID: null
> is not granted any of the required roles). Do you know how to perform
> this action with the Universal Test Client, by the way. I'd like to
> have a way to know which of my client or my server is broken.

A couple of questions ...

1. Do SECURITY_PRINCIPAL and SECURITY_CREDENTIALS contain a valid userid
and password for your user registry?

2. Have you mapped this user, or a group that contains this user, to the
role that is required to call the EJB ?

Paul.

regis....@banque-france.fr

unread,
Feb 21, 2006, 11:33:15 AM2/21/06
to
You're right, let's return to the basics.

Yes the security principal and credentials are mapped to a valid user
defined with a custom registry.

The proof I have is that the bean is correctly called from within a
Servlet, which is:


Hashtable ht = new Hashtable();

ht.put(Context.PROVIDER_URL, "iiop://pc21180e");
ht.put(
Context.INITIAL_CONTEXT_FACTORY,
"com.ibm.websphere.naming.WsnInitialContextFactory");

Context initial;


try {
initial = new InitialContext(ht);
QuoteHome home =

(QuoteHome) javax.rmi.PortableRemoteObject.narrow (


initial.lookup("ejb/fr/bdf/testrmi/QuoteHome"),
QuoteHome.class);
Quote quote=home.create();
Quotation q = quote.get();

resp.getWriter().print(q.getQuote());
} catch (...)

When the browser requests this servlet, the AppServer requires a login.
Providing a valid principal and credentials displays the quotation.

An incorrect principal and credential fails, and the server logs
[21/02/06 17:28:07:024 CET] 7ffcae1e JaasLoginHelp E SECJ4001E:
L'ouverture de session a échoué pour aze/customRealm
com.ibm.websphere.security.auth.WSLoginFailedException: Password check
failed for user: aze
at
com.ibm.ws.security.server.lm.swamLoginModule.login(swamLoginModule.java:269)
at
com.ibm.ws.security.common.auth.module.proxy.WSLoginModuleProxy.login(WSLoginModuleProxy.java:119)
at java.lang.reflect.Method.invoke(Native Method)
at
javax.security.auth.login.LoginContext.invoke(LoginContext.java:607)
at
javax.security.auth.login.LoginContext.access$000(LoginContext.java:124)
at javax.security.auth.login.LoginContext$3.run(LoginContext.java:543)
at java.security.AccessController.doPrivileged(Native Method)
at
javax.security.auth.login.LoginContext.invokeModule(LoginContext.java:540)
at javax.security.auth.login.LoginContext.login(LoginContext.java:450)
at
com.ibm.ws.security.auth.JaasLoginHelper.jaas_login(JaasLoginHelper.java:169)
at
com.ibm.ws.security.auth.ContextManagerImpl.login(ContextManagerImpl.java:735)
at
com.ibm.ws.security.web.WebAuthenticator.basicAuthenticate(WebAuthenticator.java:1053)
at
com.ibm.ws.security.web.WebAuthenticator.handleBasicAuth(WebAuthenticator.java:741)
at
com.ibm.ws.security.web.WebAuthenticator.authenticate(WebAuthenticator.java:878)
at
com.ibm.ws.security.web.WebCollaborator.authorize(WebCollaborator.java:473)
at
com.ibm.ws.security.web.EJSWebCollaborator.preInvoke(EJSWebCollaborator.java:214)
at
com.ibm.ws.webcontainer.webapp.WebAppSecurityCollaborator.preInvoke(WebAppSecurityCollaborator.java:132)
at
com.ibm.ws.webcontainer.webapp.WebAppRequestDispatcher.dispatch(WebAppRequestDispatcher.java:510)
at
com.ibm.ws.webcontainer.webapp.WebAppRequestDispatcher.forward(WebAppRequestDispatcher.java:176)
at
com.ibm.ws.webcontainer.srt.WebAppInvoker.doForward(WebAppInvoker.java:79)
at
com.ibm.ws.webcontainer.srt.WebAppInvoker.handleInvocationHook(WebAppInvoker.java:201)
at
com.ibm.ws.webcontainer.cache.invocation.CachedInvocation.handleInvocation(CachedInvocation.java:71)
at
com.ibm.ws.webcontainer.cache.invocation.CacheableInvocationContext.invoke(CacheableInvocationContext.java:114)
at
com.ibm.ws.webcontainer.srp.ServletRequestProcessor.dispatchByURI(ServletRequestProcessor.java:186)
at
com.ibm.ws.webcontainer.oselistener.OSEListenerDispatcher.service(OSEListener.java:334)
at
com.ibm.ws.webcontainer.http.HttpConnection.handleRequest(HttpConnection.java:56)
at
com.ibm.ws.http.HttpConnection.readAndHandleRequest(HttpConnection.java:610)
at com.ibm.ws.http.HttpConnection.run(HttpConnection.java:431)
at com.ibm.ws.util.ThreadPool$Worker.run(ThreadPool.java(Compiled
Code))
--------------------------------------------------------------------------------
com.ibm.websphere.security.PasswordCheckFailedException: Password check
failed for user: aze
--------------------------------------------------------------------------------

Do you have any other suggestion?

Thanks,
--
Régis

Paul Ilechko

unread,
Feb 21, 2006, 2:39:45 PM2/21/06
to
regis....@banque-france.fr wrote:

> Do you have any other suggestion?

Can you call the EJB from the main thread in your client rather than
creating a new thread ?

regis....@banque-france.fr

unread,
Feb 22, 2006, 8:41:46 AM2/22/06
to
PROBLEM SOLVED

Hi,

Thanks to Paul and Krao for their help.

I eventually made my client work. Here is how.

I assume that:
- you can already query the EJB from a servlet with the login
y817579/y817579
- the SSL key and trust are shared correctly between the client and the
server

The client needs to do a programmatic login (see WSLogin and WSSubject
http://publib.boulder.ibm.com/infocenter/wasinfo/v5r1//index.jsp%3Ftopic%3D/com.ibm.websphere.nd.doc/info/ae/ae/tsec_pacs.html)
Basically (try/catch removed), what I do is this:


Context initial = new InitialContext(env);

QuoteHome home =
(QuoteHome) PortableRemoteObject.narrow(

initial.lookup(jndiLookupName),
QuoteHome.class);
LoginContext lc = new LoginContext(
"ClientContainer", // I suppose WSLogin works too


new WSCallbackHandlerImpl(
(String) env.get(Context.SECURITY_PRINCIPAL),
(String) env.get(Context.SECURITY_CREDENTIALS)
));
lc.login();

quote = home.create();


WSSubject.doAs(subject, new java.security.PrivilegedAction() {
public Object run() {

Quotation q = quote.get();
System.out.println(q.getQuote());

if (q.getAuthor() != null && q.getAuthor().length() > 0) {
System.out.println("\t-- " + q.getAuthor());
}

}
});

The program is run with the arguments
-Djava.naming.provider.url=iiop://myserver
-Djava.naming.security.principal=y817579
-Djava.naming.security.credentials=y817579
At this point, you get the error message I described in my original
post.

Now, for the client to work, you need to define 2 properties file
-Dcom.ibm.CORBA.ConfigURL="C:\Program Files\IBM\WebSphere
Studio\Application
Developer\v5.1.2\runtimes\base_v5\properties\sas.client.props"


-Djava.security.auth.login.config="C:\Program Files\IBM\WebSphere
Studio\Application
Developer\v5.1.2\runtimes\base_v5\properties\wsjaas_client.conf"

In sas.client.propos, define
# RMI/IIOP user identity
and
com.ibm.CORBA.loginSource=none

hope this helps,
--
Régis
# RMI/IIOP user identity

0 new messages