从独立Java应用程序访问Glassfish上的安全EJB

从独立Java应用程序访问Glassfish上的安全EJB,java,glassfish,lookup,jaas,Java,Glassfish,Lookup,Jaas,我正在尝试从一个独立的应用程序(在Eclipse中运行)访问一个安全EJB(在Glassfish)。 我有一个JAAS登录模块可以很好地处理任何web项目(如果在web.xml中配置了MyRealm等),现在我想用相同的登录模块保护我的EJB(作为我的自定义登录模块验证用户并添加“用户”)到经过身份验证的上下文,因此我通过键入@RolesAllowed({“User”}) 这是我的EJB项目,它只包含1个EJB @Stateless(name="HiEjb", mappedName = "ejb

我正在尝试从一个独立的应用程序(在Eclipse中运行)访问一个安全EJB(在
Glassfish
)。 我有一个
JAAS
登录模块可以很好地处理任何web项目(如果在web.xml中配置了
MyRealm
等),现在我想用相同的登录模块保护我的
EJB
(作为我的自定义登录模块验证用户并添加
“用户”)
到经过身份验证的上下文,因此我通过键入
@RolesAllowed({“User”})

这是我的EJB项目,它只包含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";
    }
}
请注意,如果我删除
@RolesAllowed({“User”})
,我就可以从独立客户端访问此EJB

下面是我的独立客户端代码(一个从Eclipse运行的简单java类)和
auth.conf
内容

default { com.maz.test.MyCustomeLoginModule required; };
这里是主要功能

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();
    }
当我运行上述代码时,我看到以下异常

programmaticLogin.login("zahoor", "abc123".toCharArray());
异常发生在上述行上

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
问题:

  • 是否可以从独立客户端访问安全EJB(部署在glassfish上)
  • EJB项目中是否需要任何配置(除了
    @RolesAllowed({“User”})
    )来确定要使用哪个登录模块?如何配置?正如我所知,通过提供身份验证配置,可以通过
    web.xml
    保护web项目
  • 通过在auth.conf中指定
    default{com.maz.test.MyCustomeLoginModule required;};
    是否执行任何操作,我假设它告诉
    programmaticologin
    使用
    MyCustomeLoginModule
    进行身份验证

  • JAAS对EJB的支持

    如果从EJB容器外部的应用程序客户端调用任何EJB,则EJB不支持Java身份验证和授权服务(JAAS)。但是,如果从OC4J实例中的servlet调用EJB,则支持JAAS