如何从无状态会话bean中获取JSF应用程序用户名

问题描述:

我们使用JSF & EJB 3.0(EclipseLink 2.0)。我们需要为我们的无状态会话bean中的每个连接使用Oracle代理授权。为此,我们需要获取数据库用户名以通过代理连接。数据库用户名是通过规则从JSF认证用户名构建的。如何从无状态会话bean中获取JSF应用程序用户名

这里是话题http://blogs.oracle.com/olaf/2010/04/using_oracle_proxy_authenticat.html

的文章,因此,在经过身份验证的用户呼叫JSF管理bean的方法,它的依次调用一些会话bean的方法自己的用户名必须以某种方式传递给会话bean。

现在我有两个不是很好的解决方案: - 在每个会话bean方法中传递用户名作为参数(不是非常整洁,但将工作); - 上述文章的解决方案:使用会话bean的类成员变量来存储用户名(不是线程安全的和潜在危险的)

P.S.我发现使用线程局部变量的解决方案:_http://www.adam-bien.com/roller/abien/entry/how_to_pass_context_with 它工作正常,但仍然存在问题。我需要在每次调用ejb会话bean之前在每个jsf会话托管bean中放入当前用户名,因为它必须位于同一个线程中。

如果你的用户是由容器认证,您可以通过使用javax.ejb.SessionContext注入的情况下这样的访问的用户名在EJB:

@Resource 
private SessionContext context; 

private String getCurrentUsername() { 
    return context.getCallerPrincipal().getName(); 
} 

编辑:如果验证在配置这工作web.xml通过login-config和security-constraint元素。如果你自己进行认证,你可以使用ServletFilter和一个覆盖getUserPrincipal,getRemoteUser和isUserInRole(在glassfish中测试)的HttpServletRequestWrapper。

如果你在一个jsf bean中处理认证,那么这可能不起作用,因为ejb已经被初始化和注入了。然而,你也可以创建一个只保存用户名的session scoped ejb,并将这个bean注入到无状态bean中。

+0

非常感谢Jörn。你的解决方案对我来说很整洁。 P.S.你能告诉我什么时候SessionContext不会包含当前web层的用户名吗? – Andrey 2010-08-04 10:39:32