Java 如何解决';用户<;匿名>;没有足够的权限访问EJB';即使在InitialContext中指定了正确的用户

Java 如何解决';用户<;匿名>;没有足够的权限访问EJB';即使在InitialContext中指定了正确的用户,java,tomcat,weblogic12c,Java,Tomcat,Weblogic12c,我有一个客户端应用程序,在ApacheTomcat上作为servlet运行,连接到WildFly 10.1或WebLogic 12c应用服务器。该应用程序最近从JBoss 6.1和WebLogic 11g移植到这些较新的应用服务器上。当使用WildFly 10.1时,应用程序按预期工作,但当它尝试与运行在WebLogic 12c上的主应用程序通信时,我不断得到“用户没有足够的权限访问EJB” 我确实遇到过一篇关于JNDI上下文和线程的Oracle参考文献,说用户与线程相关,还有一篇参考文献提到W

我有一个客户端应用程序,在ApacheTomcat上作为servlet运行,连接到WildFly 10.1或WebLogic 12c应用服务器。该应用程序最近从JBoss 6.1和WebLogic 11g移植到这些较新的应用服务器上。当使用WildFly 10.1时,应用程序按预期工作,但当它尝试与运行在WebLogic 12c上的主应用程序通信时,我不断得到“用户没有足够的权限访问EJB”

我确实遇到过一篇关于JNDI上下文和线程的Oracle参考文献,说用户与线程相关,还有一篇参考文献提到WebLogic9.0中的行为发生了变化 支持VM范围内的默认用户,并且您必须在同一线程(或子线程)中才能进行身份验证

我能够编写一个简单的测试客户端来确认这种行为。如果我在一个线程中实例化InitialContext,然后尝试在另一个线程中使用它,则会出现“User”错误。如果我再试一次,但这次在主应用程序中实例化InitialContext,我能够通过主应用程序以及我创建的任何其他线程成功地与应用程序服务器通信

以下是复制错误的示例测试客户端:

import java.text.SimpleDateFormat;
import java.util.Properties;

import javax.ejb.FinderException;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;

import com.supportsoft.encore.inventory.dto.DeviceDTO;
import com.supportsoft.encore.inventory.ejb.InventoryInterfaceFactory;
import com.supportsoft.encore.inventory.ejb.remote.DeviceManager;
import com.supportsoft.encore.system.exception.RealmViolationException;

public class GetInitialContextThreaded {
    private static InitialContext ic;

    public static void main(String[] args) {

        try {
            // Use a thread to initialize the initial context
            Thread thread1 = new Thread() {
                public void run() {
                    log("THREAD1: Getting InitialContext.");
                    Properties icProps = new Properties();
                    icProps.put(Context.INITIAL_CONTEXT_FACTORY, "weblogic.jndi.WLInitialContextFactory");
                    icProps.put(Context.PROVIDER_URL, "t3://localhost:6002");
//                  icProps.put(Context.INITIAL_CONTEXT_FACTORY, "org.jboss.naming.remote.client.InitialContextFactory");
//                  icProps.put(Context.PROVIDER_URL, "http-remoting://localhost:7777");
                    icProps.put(Context.SECURITY_PRINCIPAL, "system");
                    icProps.put(Context.SECURITY_CREDENTIALS, "system");

//                   icProps.put("jboss.naming.client.ejb.context", false);
//                   icProps.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming");
//                   icProps.put("jboss.naming.client.connect.options.org.xnio.Options.SASL_POLICY_NOANONYMOUS", "false");
//                   icProps.put("jboss.naming.client.connect.options.org.xnio.Options.SASL_POLICY_NOPLAINTEXT", "false");

                    icProps.put("java.naming.factory.url.pkgs", "weblogic.jndi.factories:weblogic.corba.j2ee.naming.url");
//                  icProps.put("weblogic.jndi.enableDefaultUser", "true");

                    try {
                        ic = new InitialContext(icProps);
                        log("THREAD1: Have InitialContext.");
                    } catch (NamingException e) {
                        e.printStackTrace();
                    }
                }
            };
            thread1.start();

            try {
                Thread.sleep(5000);
            } catch (InterruptedException e1) {
                e1.printStackTrace();
            }

            // Test connection
            log("MAIN: Testing connection to app server.");
            InventoryInterfaceFactory iFactory = getInventoryInterfaceFactory(ic, "MAIN");

            log("MAIN: Getting DeviceManager handle");
            DeviceManager devMgr = iFactory.getDeviceManager();
            log("MAIN: Have DeviceManager handle");

            log("MAIN: Get device");
            DeviceDTO device = devMgr.getByID(1000L);
            log("MAIN: Have device");


            Thread thread2 = new Thread() {
                public void run() {
                    log("THREAD2: Testing connection to app server.");
                    InventoryInterfaceFactory iFactory = getInventoryInterfaceFactory(ic, "THREAD2");

                    try {
                        log("THREAD2: Getting DeviceManager handle");
                        DeviceManager devMgr = iFactory.getDeviceManager();
                        log("THREAD2: Have DeviceManager handle");

                        log("THREAD2: Get device");
                        DeviceDTO device = devMgr.getByID(1000L);
                        log("THREAD2: Have device");
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            };
            thread2.start();

            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            log("MAIN: Successfully connected to app server.");

        } catch (NamingException e) {
            e.printStackTrace();
        } catch (FinderException e) {
            e.printStackTrace();
        } catch (RealmViolationException e) {
            e.printStackTrace();
        }
    }

    private static InventoryInterfaceFactory getInventoryInterfaceFactory(InitialContext ctx, String logPrefix) {
        InventoryInterfaceFactory factory = null;
        try {
            log(logPrefix + ": Instantiating factory");
                factory = InventoryInterfaceFactory.getInstance(ctx);
            log(logPrefix + ": Instantiated factory");

        } catch (NamingException e) {
            e.printStackTrace();
        } 

        return factory;


    }

    private static void log(String message) {
        SimpleDateFormat time_formatter = new SimpleDateFormat("EEE MMM dd HH:mm:ss.SSS z yyyy");
        String current_time_str = time_formatter.format(System.currentTimeMillis());
        System.out.println(current_time_str + ": " + message);
    }

}
这是我运行它时看到的输出:

Tue Oct 22 15:34:35.395 ADT 2019: THREAD1: Getting InitialContext.
Tue Oct 22 15:34:37.469 ADT 2019: THREAD1: Have InitialContext.
Tue Oct 22 15:34:40.371 ADT 2019: MAIN: Testing connection to app server.
Tue Oct 22 15:34:40.372 ADT 2019: MAIN: Instantiating factory
Tue Oct 22 15:34:40.401 ADT 2019: MAIN: Instantiated factory
Tue Oct 22 15:34:40.402 ADT 2019: MAIN: Getting DeviceManager handle
Tue Oct 22 15:34:40.580 ADT 2019: MAIN: Have DeviceManager handle
Tue Oct 22 15:34:40.580 ADT 2019: MAIN: Get device
Exception in thread "main" javax.ejb.EJBAccessException: [EJB:010160]Security violation: User <anonymous> has insufficient permission to access EJB type=<ejb>, application=xyz, module=xyz-impl.jar, ejb=XYZManagerBean, method=getByID, methodInterface=Remote, signature={java.lang.Long}.
    at weblogic.utils.StackTraceDisabled.unknownMethod()
10月22日星期二15:34:35.395 ADT 2019:THREAD1:获取初始上下文。
10月22日星期二15:34:37.469 ADT 2019:THREAD1:具有初始上下文。
10月22日星期二15:34:40.371 ADT 2019:MAIN:测试与应用服务器的连接。
2019年10月22日星期二15:34:40.372 ADT:MAIN:实例化工厂
10月22日星期二15:34:40.401 ADT 2019:主要:实例化工厂
10月22日星期二15:34:40.402 ADT 2019:MAIN:获取设备管理器手柄
2010年10月22日星期二15:34:40.580 ADT 2019:主:具有设备管理器手柄
10月22日星期二15:34:40.580 ADT 2019:主:获取设备
线程“main”javax.ejb.EJBAccessException中出现异常:[ejb:010160]安全冲突:用户没有足够的权限访问ejb type=,application=xyz,module=xyz-impl.jar,ejb=XYZManagerBean,method=getByID,methodInterface=Remote,signature={java.lang.Long}。
在weblogic.utils.StackTraceDisabled.unknownMethod()中
正如我前面提到的,在我的测试客户机中,通过让主应用程序实例化InitialContext来解决这个问题是相当直接的

我的问题是如何在ApacheTomcat上部署和运行的servlet中处理这个问题。当应用程序启动时,initialize()方法会执行许多操作,例如加载属性文件、实例化InitialContext以及测试与应用程序服务器的连接。一切正常。问题是当servlet开始处理新请求并尝试与WebLogic 12c应用服务器通信时。正是在这一点上,我得到了“用户”错误

有没有一种方法可以配置Tomcat或servlet,以便在servlet线程之间共享InitialContext,而不会“丢失”经过身份验证的主体?在WebLogic 11g中,我们包含了一个名为“WebLogic.jndi.enableDefaultUser”的上下文属性,并将其设置为“true”,但WebLogic 12c似乎不支持该属性


有什么想法吗?

尝试回答,因为这可能对寻找答案的人有用

您是否看到此问题在服务器启动时发生? 如果是,请在Weblogic描述符文件中传递原则名称

只为前男友

三十、 YYYY.CREATE.PRINCIPAL

yyy.CREATE.PRINCIPAL