gpt4 book ai didi

security - 多个并发用户对 JBoss AS 4.2.3 的 RMI 调用

转载 作者:行者123 更新时间:2023-12-04 18:25:07 27 4
gpt4 key购买 nike

我想编写一个 Web 前端,它希望将从浏览器接收到的 HTTP 身份验证“传播”到公开众多 @Remote 接口(interface)的 JBoss AS 4.2.3。

考虑以下 RMI 调用并发的简单模拟:

Properties user1 = new Properties();
user1.setProperty(Context.INITIAL_CONTEXT_FACTORY,
"org.jboss.security.jndi.JndiLoginInitialContextFactory");
user1.setProperty(Context.URL_PKG_PREFIXES, "org.jboss.naming");
user1.setProperty(Context.PROVIDER_URL, "127.0.0.1:1099");
user1.setProperty(Context.SECURITY_PRINCIPAL, "user1");
user1.setProperty(Context.SECURITY_CREDENTIALS, "pass1");

Properties user2 = new Properties();
user2.setProperty(Context.INITIAL_CONTEXT_FACTORY,
"org.jboss.security.jndi.JndiLoginInitialContextFactory");
user2.setProperty(Context.URL_PKG_PREFIXES, "org.jboss.naming");
user2.setProperty(Context.PROVIDER_URL, "127.0.0.1:1099");
user2.setProperty(Context.SECURITY_PRINCIPAL, "user2");
user2.setProperty(Context.SECURITY_CREDENTIALS, "pass2");

InitialContext ctx1 = new InitialContext(user1);
Mine bean1 = (Mine) ctx1.lookup("myear/MyBean/remote");
InitialContext ctx2 = new InitialContext(user2);
Mine bean2 = (Mine) ctx2.lookup("myear/MyBean/remote");

System.out.println(bean1.whoami());
System.out.println(bean2.whoami());

调用使用 jbossall-client 4.2.3 并转到 JBoss AS 4.2.3。

.whoami() 方法只是回显登录的用户名。反过来,这导致两个调用都说它们是由“user2”发出的。据推测,底层连接是共享的,并且仅使用最后看到的属性包进行身份验证。

简而言之,这很糟糕。一些初步测试表明,同样的问题仍然存在于 JBoss AS 7 中,所以运气不好。

是否有我可以使用的任何其他 RMI 客户端实现或我可以在 prop 包中传递的任何参数以使 InitialContexts 不共享其登录信息? 或者,有人可以向我指出需要被黑客入侵才能实现这一目标的代码吗?

更新:

按要求:
public class Worker extends Thread {
private final String pass, user;
private int correct = 0;

public Worker(String user, String pass) { this.user = user; this.pass = pass; }

public void run() {
Properties props = new Properties();
props.setProperty(Context.INITIAL_CONTEXT_FACTORY,
"org.jboss.security.jndi.JndiLoginInitialContextFactory");
props.setProperty(Context.URL_PKG_PREFIXES, "org.jboss.naming");
props.setProperty(Context.PROVIDER_URL, "127.0.0.1:1099");
props.setProperty(Context.SECURITY_PRINCIPAL, this.user);
props.setProperty(Context.SECURITY_CREDENTIALS, this.pass);

try {
InitialContext ctx = new InitialContext(props);
for(int i = 0; i < 100; i++) {
Mine bean = (Mine) ctx.lookup("myear/MyBean/remote");
if(bean.whoami().equals(this.user)) this.correct++;
Thread.sleep(2); }
ctx.close();
} catch (Exception e) { throw new RuntimeException(e); }
System.out.println("Done [id="+this.getId()+", good="+this.correct+"]");
}
}

与两个 worker 一起运行会产生:
public static void main(String[] args) throws Exception {
new Worker("user1", "pass1").start();
new Worker("user2", "pass2").start();
}

Done [t=9, good=0]
Done [t=10, good=100]

使用 5 个线程运行会产生:
public static void main(String[] args) throws Exception {
new Worker("user1", "pass1").start();
new Worker("user2", "pass2").start();
new Worker("user3", "pass3").start();
new Worker("user4", "pass4").start();
new Worker("user5", "pass5").start();
}

Caused by: javax.ejb.EJBAccessException: Authentication failure
at org.jboss.ejb3.security.Ejb3AuthenticationInterceptor.handleGeneralSecurityException(Ejb3AuthenticationInterceptor.java:68)
at org.jboss.aspects.security.AuthenticationInterceptor.invoke(AuthenticationInterceptor.java:70)
at org.jboss.ejb3.security.Ejb3AuthenticationInterceptor.invoke(Ejb3AuthenticationInterceptor.java:110)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
at org.jboss.ejb3.ENCPropagationInterceptor.invoke(ENCPropagationInterceptor.java:46)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
at org.jboss.ejb3.asynchronous.AsynchronousInterceptor.invoke(AsynchronousInterceptor.java:106)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
at org.jboss.ejb3.stateless.StatelessContainer.dynamicInvoke(StatelessContainer.java:304)
at org.jboss.aop.Dispatcher.invoke(Dispatcher.java:106)
at org.jboss.aspects.remoting.AOPRemotingInvocationHandler.invoke(AOPRemotingInvocationHandler.java:82)
at org.jboss.remoting.ServerInvoker.invoke(ServerInvoker.java:809)
at org.jboss.remoting.transport.socket.ServerThread.processInvocation(ServerThread.java:608)
at org.jboss.remoting.transport.socket.ServerThread.dorun(ServerThread.java:406)
at org.jboss.remoting.transport.socket.ServerThread.run(ServerThread.java:173)
at org.jboss.remoting.MicroRemoteClientInvoker.invoke(MicroRemoteClientInvoker.java:163)
at org.jboss.remoting.Client.invoke(Client.java:1634)
at org.jboss.remoting.Client.invoke(Client.java:548)
at org.jboss.aspects.remoting.InvokeRemoteInterceptor.invoke(InvokeRemoteInterceptor.java:62)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
at org.jboss.aspects.tx.ClientTxPropagationInterceptor.invoke(ClientTxPropagationInterceptor.java:67)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
at org.jboss.aspects.security.SecurityClientInterceptor.invoke(SecurityClientInterceptor.java:53)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
at org.jboss.ejb3.remoting.IsLocalInterceptor.invoke(IsLocalInterceptor.java:74)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
at org.jboss.ejb3.stateless.StatelessRemoteProxy.invoke(StatelessRemoteProxy.java:107)
at $Proxy0.whoami(Unknown Source)
at net.windwards.Worker.run(TestRMIClient.java:31)
at org.jboss.aspects.remoting.InvokeRemoteInterceptor.invoke(InvokeRemoteInterceptor.java:74)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
at org.jboss.aspects.tx.ClientTxPropagationInterceptor.invoke(ClientTxPropagationInterceptor.java:67)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
at org.jboss.aspects.security.SecurityClientInterceptor.invoke(SecurityClientInterceptor.java:53)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
at org.jboss.ejb3.remoting.IsLocalInterceptor.invoke(IsLocalInterceptor.java:74)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
at org.jboss.ejb3.stateless.StatelessRemoteProxy.invoke(StatelessRemoteProxy.java:107)
at $Proxy0.whoami(Unknown Source)
at net.windwards.Worker.run(TestRMIClient.java:31)

建立初始连接大约需要 100 毫秒,所以我尝试了以下方法(在调用之间 sleep 10 毫秒以获得良好的重叠):
public static void main(String[] args) throws Exception {
new Worker("user1", "pass1").start();
Thread.sleep(200);
new Worker("user2", "pass2").start();
Thread.sleep(200);
new Worker("user3", "pass3").start();
Thread.sleep(200);
new Worker("user4", "pass4").start();
Thread.sleep(200);
new Worker("user5", "pass5").start();
}

Done [t=9, good=1]
Done [t=14, good=12]
Done [t=15, good=14]
Done [t=16, good=15]
Done [t=17, good=100]

最佳答案

来自 docs对于 org.jboss.security.jndi.JndiLoginInitialContextFactory :

During the getInitialContext callback from the JNDI naming, layer security context identity is populated with the username ... and the credentials ... There is no actual authentication of this information. It is merely made available to the jboss transport layer for incorporation into subsequent invocations



在这种情况下,当您调用 bean 时, user2是最后一个主体集,jboss 传输层可以使用的主体集也是如此。

但是,从 jboss4 source ,看起来您可以将安全上下文限定为线程上下文,在这种情况下,您的线程测试应该可以工作,只需添加以下属性:
userN.setProperty("jnp.multi-threaded", "true");

另一种解决方案是使用 org.jboss.security.jndi.LoginInitialContextFactory而不是 org.jboss.security.jndi.JndiLoginInitialContextFactory , 不像 JndiLoginInitialContextFactory , LoginInitialContextFactory将在进行查找时尝试进行身份验证,而不是在调用 EJB 时进行身份验证,您可以尝试一下,即使在 the docs 中也是如此,当涉及到远程客户端上的 EJB 授权时,他们推荐 JndiLoginInitialContextFactory

关于security - 多个并发用户对 JBoss AS 4.2.3 的 RMI 调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21578181/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com