简体   繁体   中英

Access Secure EJB on Glassfish from Standalone Java application

I am trying to access a secure EJB (on Glassfish ) from a stand-alone application(running in Eclipse). I have a JAAS login module working fine with any web project (if configured in web.xml with <realm-name>MyRealm</realm-name> etc), Now I want to secure my EJB with same Login Module (As my custom login module authenticate user and add "User" to the authenticated context, so I have used the same for for ejb by typing @RolesAllowed({"User"})

Here is my EJB Project that contains only 1 EJB.

@Stateless(name="HiEjb", mappedName = "ejb/HiEjb")
@RolesAllowed({"User"})
@Remote(HiEjbRemote.class)
@Local(HiEjbLocal.class)
public class HiEjb implements HiEjbRemote, HiEjbLocal {

    @Override
    public String getHello() {
        return "3D Studio Max";
    }
}

Please note, I am able to access this EJB from stand alone client if I remove @RolesAllowed({"User"}) .

Here is my stand-alone client code (A simple java class running from Eclipse) and auth.conf contents

default { com.maz.test.MyCustomeLoginModule required; };

and here is main function

public static void main(String[] args) throws Exception {

        String authFile = "D:/auth.conf";
        System.setProperty("java.security.auth.login.config", authFile);
        ProgrammaticLogin programmaticLogin = new ProgrammaticLogin();

        programmaticLogin.login("zahoor", "abc123".toCharArray()); //here on this line exception occurs.


        Properties p = new Properties();
        //p.setProperty("java.naming.factory.initial","org.jnp.interfaces.NamingContextFactory");
        p.setProperty("java.naming.factory.url.pkgs","org.jboss.naming:org.jnp.interfaces");
        p.setProperty("java.naming.provider.url", "hostname:jnpport");
        p.setProperty(Context.SECURITY_PRINCIPAL, "zahoor");
        p.setProperty(Context.SECURITY_CREDENTIALS, "abc123");
        InitialContext ic = new InitialContext(p);

        final String jndiName = "ejb/HiEjb";
        HiEjbRemote testEjb = (HiEjbRemote) ic.lookup(jndiName);
        System.out.println("Got the reference of Remote Interface");
        System.out.println("Resulte from EJB::->"+ testEjb.getHello());

        programmaticLogin.logout();
    }

When I run above code I see following exception.

programmaticLogin.login("zahoor", "abc123".toCharArray());

Exception occurs on above line.

Jun 27, 2014 6:59:20 PM com.sun.appserv.security.AppservPasswordLoginModule extractCredentials
SEVERE: SEC1105: A PasswordCredential was required but not provided.
Jun 27, 2014 6:59:20 PM com.sun.appserv.security.ProgrammaticLogin login
SEVERE: SEC9050: Programmatic login failed
com.sun.enterprise.security.auth.login.common.LoginException: javax.security.auth.login.LoginException: No credentials.
    at com.sun.enterprise.security.auth.login.LoginContextDriver$9.run(LoginContextDriver.java:889)
    at com.sun.enterprise.security.common.AppservAccessController.doPrivileged(AppservAccessController.java:61)
    at com.sun.enterprise.security.auth.login.LoginContextDriver.doClientLogin(LoginContextDriver.java:881)
    at com.sun.appserv.security.ProgrammaticLogin$1.run(ProgrammaticLogin.java:184)
    at java.security.AccessController.doPrivileged(Native Method)
    at com.sun.appserv.security.ProgrammaticLogin.login(ProgrammaticLogin.java:168)
    at com.sun.appserv.security.ProgrammaticLogin.login(ProgrammaticLogin.java:239)
    at ClientTest.main(ClientTest.java:51)
Caused by: javax.security.auth.login.LoginException: No credentials.
    at com.sun.appserv.security.AppservPasswordLoginModule.extractCredentials(AppservPasswordLoginModule.java:331)
    at com.sun.appserv.security.AppservPasswordLoginModule.login(AppservPasswordLoginModule.java:140)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at javax.security.auth.login.LoginContext.invoke(LoginContext.java:769)
    at javax.security.auth.login.LoginContext.access$000(LoginContext.java:186)
    at javax.security.auth.login.LoginContext$4.run(LoginContext.java:683)
    at java.security.AccessController.doPrivileged(Native Method)
    at javax.security.auth.login.LoginContext.invokePriv(LoginContext.java:680)
    at javax.security.auth.login.LoginContext.login(LoginContext.java:579)
    at com.sun.enterprise.security.auth.login.LoginContextDriver$9.run(LoginContextDriver.java:887)
    ... 7 more

Questions:

  1. Is it possible to access a secure EJB (deployed on glassfish) from a stand alone client?
  2. Is there any configuration required in EJB project (other than @RolesAllowed({"User"}) ) to tell which login module to use? How that can be configured. like I know web project can be secured through web.xml by providing authentication configuration.
  3. By Specifying default { com.maz.test.MyCustomeLoginModule required; }; default { com.maz.test.MyCustomeLoginModule required; }; in auth.conf does any thing or not, I am assuming that it tells the ProgrammaticLogin to use MyCustomeLoginModule for authentication.

JAAS Support for EJBs

If you invoke any EJB from an application client outside the EJB container, then Java Authentication and Authorization Service (JAAS) is not supported for the EJB. However, if you call the EJB from a servlet within the OC4J instance, then JAAS is supported.

http://docs.oracle.com/cd/B14099_19/web.1012/b15505/access.htm#sthref262

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM